Skip to content

Commit 607ba1b

Browse files
jgunthorpejoergroedel
authored andcommitted
iommu/vt-d: Check if SVA is supported when attaching the SVA domain
Attach of a SVA domain should fail if SVA is not supported, move the check for SVA support out of IOMMU_DEV_FEAT_SVA and into attach. Also check when allocating a SVA domain to match other drivers. Signed-off-by: Jason Gunthorpe <[email protected]> Signed-off-by: Lu Baolu <[email protected]> Reviewed-by: Kevin Tian <[email protected]> Reviewed-by: Yi Liu <[email protected]> Tested-by: Zhangfei Gao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent a8653e5 commit 607ba1b

File tree

2 files changed

+44
-36
lines changed

2 files changed

+44
-36
lines changed

drivers/iommu/intel/iommu.c

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3855,41 +3855,6 @@ static struct iommu_group *intel_iommu_device_group(struct device *dev)
38553855
return generic_device_group(dev);
38563856
}
38573857

3858-
static int intel_iommu_enable_sva(struct device *dev)
3859-
{
3860-
struct device_domain_info *info = dev_iommu_priv_get(dev);
3861-
struct intel_iommu *iommu;
3862-
3863-
if (!info || dmar_disabled)
3864-
return -EINVAL;
3865-
3866-
iommu = info->iommu;
3867-
if (!iommu)
3868-
return -EINVAL;
3869-
3870-
if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE))
3871-
return -ENODEV;
3872-
3873-
if (!info->pasid_enabled || !info->ats_enabled)
3874-
return -EINVAL;
3875-
3876-
/*
3877-
* Devices having device-specific I/O fault handling should not
3878-
* support PCI/PRI. The IOMMU side has no means to check the
3879-
* capability of device-specific IOPF. Therefore, IOMMU can only
3880-
* default that if the device driver enables SVA on a non-PRI
3881-
* device, it will handle IOPF in its own way.
3882-
*/
3883-
if (!info->pri_supported)
3884-
return 0;
3885-
3886-
/* Devices supporting PRI should have it enabled. */
3887-
if (!info->pri_enabled)
3888-
return -EINVAL;
3889-
3890-
return 0;
3891-
}
3892-
38933858
static int context_flip_pri(struct device_domain_info *info, bool enable)
38943859
{
38953860
struct intel_iommu *iommu = info->iommu;
@@ -4010,7 +3975,7 @@ intel_iommu_dev_enable_feat(struct device *dev, enum iommu_dev_features feat)
40103975
return intel_iommu_enable_iopf(dev);
40113976

40123977
case IOMMU_DEV_FEAT_SVA:
4013-
return intel_iommu_enable_sva(dev);
3978+
return 0;
40143979

40153980
default:
40163981
return -ENODEV;

drivers/iommu/intel/svm.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,41 @@ static const struct mmu_notifier_ops intel_mmuops = {
110110
.free_notifier = intel_mm_free_notifier,
111111
};
112112

113+
static int intel_iommu_sva_supported(struct device *dev)
114+
{
115+
struct device_domain_info *info = dev_iommu_priv_get(dev);
116+
struct intel_iommu *iommu;
117+
118+
if (!info || dmar_disabled)
119+
return -EINVAL;
120+
121+
iommu = info->iommu;
122+
if (!iommu)
123+
return -EINVAL;
124+
125+
if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE))
126+
return -ENODEV;
127+
128+
if (!info->pasid_enabled || !info->ats_enabled)
129+
return -EINVAL;
130+
131+
/*
132+
* Devices having device-specific I/O fault handling should not
133+
* support PCI/PRI. The IOMMU side has no means to check the
134+
* capability of device-specific IOPF. Therefore, IOMMU can only
135+
* default that if the device driver enables SVA on a non-PRI
136+
* device, it will handle IOPF in its own way.
137+
*/
138+
if (!info->pri_supported)
139+
return 0;
140+
141+
/* Devices supporting PRI should have it enabled. */
142+
if (!info->pri_enabled)
143+
return -EINVAL;
144+
145+
return 0;
146+
}
147+
113148
static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
114149
struct device *dev, ioasid_t pasid,
115150
struct iommu_domain *old)
@@ -121,6 +156,10 @@ static int intel_svm_set_dev_pasid(struct iommu_domain *domain,
121156
unsigned long sflags;
122157
int ret = 0;
123158

159+
ret = intel_iommu_sva_supported(dev);
160+
if (ret)
161+
return ret;
162+
124163
dev_pasid = domain_add_dev_pasid(domain, dev, pasid);
125164
if (IS_ERR(dev_pasid))
126165
return PTR_ERR(dev_pasid);
@@ -161,6 +200,10 @@ struct iommu_domain *intel_svm_domain_alloc(struct device *dev,
161200
struct dmar_domain *domain;
162201
int ret;
163202

203+
ret = intel_iommu_sva_supported(dev);
204+
if (ret)
205+
return ERR_PTR(ret);
206+
164207
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
165208
if (!domain)
166209
return ERR_PTR(-ENOMEM);

0 commit comments

Comments
 (0)