Skip to content

Commit 69e61ed

Browse files
committed
Merge tag 'for-joerg' of git://git.kernel.org/pub/scm/linux/kernel/git/jgg/iommufd into core
iommu: Define EINVAL as device/domain incompatibility This series is to replace the previous EMEDIUMTYPE patch in a VFIO series: https://lore.kernel.org/kvm/[email protected]/ The purpose is to regulate all existing ->attach_dev callback functions to use EINVAL exclusively for an incompatibility error between a device and a domain. This allows VFIO and IOMMUFD to detect such a soft error, and then try a different domain with the same device. Among all the patches, the first two are preparatory changes. And then one patch to update kdocs and another three patches for the enforcement effort. Link: https://lore.kernel.org/r/[email protected]
2 parents 757636e + 04cee82 commit 69e61ed

File tree

16 files changed

+60
-56
lines changed

16 files changed

+60
-56
lines changed

drivers/iommu/amd/iommu.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2155,21 +2155,13 @@ static void amd_iommu_detach_device(struct iommu_domain *dom,
21552155
static int amd_iommu_attach_device(struct iommu_domain *dom,
21562156
struct device *dev)
21572157
{
2158+
struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
21582159
struct protection_domain *domain = to_pdomain(dom);
2159-
struct iommu_dev_data *dev_data;
2160-
struct amd_iommu *iommu;
2160+
struct amd_iommu *iommu = rlookup_amd_iommu(dev);
21612161
int ret;
21622162

2163-
if (!check_device(dev))
2164-
return -EINVAL;
2165-
2166-
dev_data = dev_iommu_priv_get(dev);
21672163
dev_data->defer_attach = false;
21682164

2169-
iommu = rlookup_amd_iommu(dev);
2170-
if (!iommu)
2171-
return -EINVAL;
2172-
21732165
if (dev_data->domain)
21742166
detach_device(dev);
21752167

drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,23 +2433,14 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
24332433
goto out_unlock;
24342434
}
24352435
} else if (smmu_domain->smmu != smmu) {
2436-
dev_err(dev,
2437-
"cannot attach to SMMU %s (upstream of %s)\n",
2438-
dev_name(smmu_domain->smmu->dev),
2439-
dev_name(smmu->dev));
2440-
ret = -ENXIO;
2436+
ret = -EINVAL;
24412437
goto out_unlock;
24422438
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
24432439
master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
2444-
dev_err(dev,
2445-
"cannot attach to incompatible domain (%u SSID bits != %u)\n",
2446-
smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
24472440
ret = -EINVAL;
24482441
goto out_unlock;
24492442
} else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
24502443
smmu_domain->stall_enabled != master->stall_enabled) {
2451-
dev_err(dev, "cannot attach to stall-%s domain\n",
2452-
smmu_domain->stall_enabled ? "enabled" : "disabled");
24532444
ret = -EINVAL;
24542445
goto out_unlock;
24552446
}

drivers/iommu/arm/arm-smmu/arm-smmu.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,9 +1150,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
11501150
* different SMMUs.
11511151
*/
11521152
if (smmu_domain->smmu != smmu) {
1153-
dev_err(dev,
1154-
"cannot attach to SMMU %s whilst already attached to domain on SMMU %s\n",
1155-
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
11561153
ret = -EINVAL;
11571154
goto rpm_put;
11581155
}

drivers/iommu/arm/arm-smmu/qcom_iommu.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,8 @@ static int qcom_iommu_attach_dev(struct iommu_domain *domain, struct device *dev
381381
* Sanity check the domain. We don't support domains across
382382
* different IOMMUs.
383383
*/
384-
if (qcom_domain->iommu != qcom_iommu) {
385-
dev_err(dev, "cannot attach to IOMMU %s while already "
386-
"attached to domain on IOMMU %s\n",
387-
dev_name(qcom_domain->iommu->dev),
388-
dev_name(qcom_iommu->dev));
384+
if (qcom_domain->iommu != qcom_iommu)
389385
return -EINVAL;
390-
}
391386

392387
return 0;
393388
}

drivers/iommu/fsl_pamu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ int pamu_config_ppaace(int liodn, u32 omi, u32 stashid, int prot)
211211
ppaace->op_encode.index_ot.omi = omi;
212212
} else if (~omi != 0) {
213213
pr_debug("bad operation mapping index: %d\n", omi);
214-
return -EINVAL;
214+
return -ENODEV;
215215
}
216216

217217
/* configure stash id */

drivers/iommu/fsl_pamu_domain.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain,
258258
liodn = of_get_property(dev->of_node, "fsl,liodn", &len);
259259
if (!liodn) {
260260
pr_debug("missing fsl,liodn property at %pOF\n", dev->of_node);
261-
return -EINVAL;
261+
return -ENODEV;
262262
}
263263

264264
spin_lock_irqsave(&dma_domain->domain_lock, flags);
@@ -267,7 +267,7 @@ static int fsl_pamu_attach_device(struct iommu_domain *domain,
267267
if (liodn[i] >= PAACE_NUMBER_ENTRIES) {
268268
pr_debug("Invalid liodn %d, attach device failed for %pOF\n",
269269
liodn[i], dev->of_node);
270-
ret = -EINVAL;
270+
ret = -ENODEV;
271271
break;
272272
}
273273

drivers/iommu/intel/iommu.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4196,19 +4196,15 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
41964196
return -ENODEV;
41974197

41984198
if (dmar_domain->force_snooping && !ecap_sc_support(iommu->ecap))
4199-
return -EOPNOTSUPP;
4199+
return -EINVAL;
42004200

42014201
/* check if this iommu agaw is sufficient for max mapped address */
42024202
addr_width = agaw_to_width(iommu->agaw);
42034203
if (addr_width > cap_mgaw(iommu->cap))
42044204
addr_width = cap_mgaw(iommu->cap);
42054205

4206-
if (dmar_domain->max_addr > (1LL << addr_width)) {
4207-
dev_err(dev, "%s: iommu width (%d) is not "
4208-
"sufficient for the mapped address (%llx)\n",
4209-
__func__, addr_width, dmar_domain->max_addr);
4210-
return -EFAULT;
4211-
}
4206+
if (dmar_domain->max_addr > (1LL << addr_width))
4207+
return -EINVAL;
42124208
dmar_domain->gaw = addr_width;
42134209

42144210
/*

drivers/iommu/intel/pasid.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ int intel_pasid_alloc_table(struct device *dev)
101101

102102
might_sleep();
103103
info = dev_iommu_priv_get(dev);
104-
if (WARN_ON(!info || !dev_is_pci(dev) || info->pasid_table))
105-
return -EINVAL;
104+
if (WARN_ON(!info || !dev_is_pci(dev)))
105+
return -ENODEV;
106+
if (WARN_ON(info->pasid_table))
107+
return -EEXIST;
106108

107109
pasid_table = kzalloc(sizeof(*pasid_table), GFP_KERNEL);
108110
if (!pasid_table)

drivers/iommu/iommu.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,6 +1976,18 @@ static int __iommu_attach_device(struct iommu_domain *domain,
19761976
return ret;
19771977
}
19781978

1979+
/**
1980+
* iommu_attach_device - Attach an IOMMU domain to a device
1981+
* @domain: IOMMU domain to attach
1982+
* @dev: Device that will be attached
1983+
*
1984+
* Returns 0 on success and error code on failure
1985+
*
1986+
* Note that EINVAL can be treated as a soft failure, indicating
1987+
* that certain configuration of the domain is incompatible with
1988+
* the device. In this case attaching a different domain to the
1989+
* device may succeed.
1990+
*/
19791991
int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
19801992
{
19811993
struct iommu_group *group;
@@ -2102,6 +2114,18 @@ static int __iommu_attach_group(struct iommu_domain *domain,
21022114
return ret;
21032115
}
21042116

2117+
/**
2118+
* iommu_attach_group - Attach an IOMMU domain to an IOMMU group
2119+
* @domain: IOMMU domain to attach
2120+
* @group: IOMMU group that will be attached
2121+
*
2122+
* Returns 0 on success and error code on failure
2123+
*
2124+
* Note that EINVAL can be treated as a soft failure, indicating
2125+
* that certain configuration of the domain is incompatible with
2126+
* the group. In this case attaching a different domain to the
2127+
* group may succeed.
2128+
*/
21052129
int iommu_attach_group(struct iommu_domain *domain, struct iommu_group *group)
21062130
{
21072131
int ret;

drivers/iommu/ipmmu-vmsa.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,6 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain,
628628
* Something is wrong, we can't attach two devices using
629629
* different IOMMUs to the same domain.
630630
*/
631-
dev_err(dev, "Can't attach IPMMU %s to domain on IPMMU %s\n",
632-
dev_name(mmu->dev), dev_name(domain->mmu->dev));
633631
ret = -EINVAL;
634632
} else
635633
dev_info(dev, "Reusing IPMMU context %u\n", domain->context_id);

0 commit comments

Comments
 (0)