Commit 1adf3cc2 authored by Lu Baolu's avatar Lu Baolu Committed by Joerg Roedel

iommu: Add max_pasids field in struct iommu_device

Use this field to keep the number of supported PASIDs that an IOMMU
hardware is able to support. This is a generic attribute of an IOMMU
and lifting it into the per-IOMMU device structure makes it possible
to allocate a PASID for device without calls into the IOMMU drivers.
Any iommu driver that supports PASID related features should set this
field before enabling them on the devices.

In the Intel IOMMU driver, intel_iommu_sm is moved to CONFIG_INTEL_IOMMU
enclave so that the pasid_supported() helper could be used in dmar.c
without compilation errors.
Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: default avatarJean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: default avatarKevin Tian <kevin.tian@intel.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Reviewed-by: default avatarYi Liu <yi.l.liu@intel.com>
Tested-by: default avatarZhangfei Gao <zhangfei.gao@linaro.org>
Tested-by: default avatarTony Zhu <tony.zhu@intel.com>
Link: https://lore.kernel.org/r/20221031005917.45690-2-baolu.lu@linux.intel.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 30a0b95b
...@@ -3543,6 +3543,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu) ...@@ -3543,6 +3543,7 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
/* SID/SSID sizes */ /* SID/SSID sizes */
smmu->ssid_bits = FIELD_GET(IDR1_SSIDSIZE, reg); smmu->ssid_bits = FIELD_GET(IDR1_SSIDSIZE, reg);
smmu->sid_bits = FIELD_GET(IDR1_SIDSIZE, reg); smmu->sid_bits = FIELD_GET(IDR1_SIDSIZE, reg);
smmu->iommu.max_pasids = 1UL << smmu->ssid_bits;
/* /*
* If the SMMU supports fewer bits than would fill a single L2 stream * If the SMMU supports fewer bits than would fill a single L2 stream
......
...@@ -1104,6 +1104,13 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) ...@@ -1104,6 +1104,13 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd)
raw_spin_lock_init(&iommu->register_lock); raw_spin_lock_init(&iommu->register_lock);
/*
* A value of N in PSS field of eCap register indicates hardware
* supports PASID field of N+1 bits.
*/
if (pasid_supported(iommu))
iommu->iommu.max_pasids = 2UL << ecap_pss(iommu->ecap);
/* /*
* This is only for hotplug; at boot time intel_iommu_enabled won't * This is only for hotplug; at boot time intel_iommu_enabled won't
* be set yet. When intel_iommu_init() runs, it registers the units * be set yet. When intel_iommu_init() runs, it registers the units
......
...@@ -480,8 +480,6 @@ enum { ...@@ -480,8 +480,6 @@ enum {
#define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1) #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1)
#define VTD_FLAG_SVM_CAPABLE (1 << 2) #define VTD_FLAG_SVM_CAPABLE (1 << 2)
extern int intel_iommu_sm;
#define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap)) #define sm_supported(iommu) (intel_iommu_sm && ecap_smts((iommu)->ecap))
#define pasid_supported(iommu) (sm_supported(iommu) && \ #define pasid_supported(iommu) (sm_supported(iommu) && \
ecap_pasid((iommu)->ecap)) ecap_pasid((iommu)->ecap))
...@@ -795,6 +793,7 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus, ...@@ -795,6 +793,7 @@ struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
extern const struct iommu_ops intel_iommu_ops; extern const struct iommu_ops intel_iommu_ops;
#ifdef CONFIG_INTEL_IOMMU #ifdef CONFIG_INTEL_IOMMU
extern int intel_iommu_sm;
extern int iommu_calculate_agaw(struct intel_iommu *iommu); extern int iommu_calculate_agaw(struct intel_iommu *iommu);
extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu); extern int iommu_calculate_max_sagaw(struct intel_iommu *iommu);
extern int dmar_disabled; extern int dmar_disabled;
...@@ -810,6 +809,7 @@ static inline int iommu_calculate_max_sagaw(struct intel_iommu *iommu) ...@@ -810,6 +809,7 @@ static inline int iommu_calculate_max_sagaw(struct intel_iommu *iommu)
} }
#define dmar_disabled (1) #define dmar_disabled (1)
#define intel_iommu_enabled (0) #define intel_iommu_enabled (0)
#define intel_iommu_sm (0)
#endif #endif
static inline const char *decode_prq_descriptor(char *str, size_t size, static inline const char *decode_prq_descriptor(char *str, size_t size,
......
...@@ -322,12 +322,14 @@ struct iommu_domain_ops { ...@@ -322,12 +322,14 @@ struct iommu_domain_ops {
* @list: Used by the iommu-core to keep a list of registered iommus * @list: Used by the iommu-core to keep a list of registered iommus
* @ops: iommu-ops for talking to this iommu * @ops: iommu-ops for talking to this iommu
* @dev: struct device for sysfs handling * @dev: struct device for sysfs handling
* @max_pasids: number of supported PASIDs
*/ */
struct iommu_device { struct iommu_device {
struct list_head list; struct list_head list;
const struct iommu_ops *ops; const struct iommu_ops *ops;
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
struct device *dev; struct device *dev;
u32 max_pasids;
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment