The idxd driver attaches the default domain to a PASID of the device to perform kernel DMA using that PASID. The domain is attached to the device's PASID through iommu_attach_device_pasid(), which checks if the domain->owner matches the iommu_ops retrieved from the device. If they do not match, it returns a failure.
if (ops != domain->owner || pasid == IOMMU_NO_PASID) return -EINVAL;
The static identity domain implemented by the intel iommu driver doesn't specify the domain owner. Therefore, kernel DMA with PASID doesn't work for the idxd driver if the device translation mode is set to passthrough.
Fix this by specifying the domain owner for the static identity domain.
Fixes: 2031c469f816 ("iommu/vt-d: Add support for static identity domain") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220031 Cc: stable@vger.kernel.org Signed-off-by: Lu Baolu baolu.lu@linux.intel.com --- drivers/iommu/intel/iommu.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index cb0b993bebb4..63c9c97ccf69 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4385,6 +4385,7 @@ static struct iommu_domain identity_domain = { .attach_dev = identity_domain_attach_dev, .set_dev_pasid = identity_domain_set_dev_pasid, }, + .owner = &intel_iommu_ops, };
const struct iommu_ops intel_iommu_ops = {
On 4/22/25 12:54 AM, Lu Baolu wrote:
The idxd driver attaches the default domain to a PASID of the device to perform kernel DMA using that PASID. The domain is attached to the device's PASID through iommu_attach_device_pasid(), which checks if the domain->owner matches the iommu_ops retrieved from the device. If they do not match, it returns a failure.
if (ops != domain->owner || pasid == IOMMU_NO_PASID) return -EINVAL;
The static identity domain implemented by the intel iommu driver doesn't specify the domain owner. Therefore, kernel DMA with PASID doesn't work for the idxd driver if the device translation mode is set to passthrough.
Fix this by specifying the domain owner for the static identity domain.
Fixes: 2031c469f816 ("iommu/vt-d: Add support for static identity domain") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220031 Cc: stable@vger.kernel.org Signed-off-by: Lu Baolu baolu.lu@linux.intel.com
Reviewed-by: Dave Jiang dave.jiang@intel.com
drivers/iommu/intel/iommu.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index cb0b993bebb4..63c9c97ccf69 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4385,6 +4385,7 @@ static struct iommu_domain identity_domain = { .attach_dev = identity_domain_attach_dev, .set_dev_pasid = identity_domain_set_dev_pasid, },
- .owner = &intel_iommu_ops,
}; const struct iommu_ops intel_iommu_ops = {
On Tue, Apr 22, 2025 at 03:54:22PM +0800, Lu Baolu wrote:
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index cb0b993bebb4..63c9c97ccf69 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4385,6 +4385,7 @@ static struct iommu_domain identity_domain = { .attach_dev = identity_domain_attach_dev, .set_dev_pasid = identity_domain_set_dev_pasid, },
- .owner = &intel_iommu_ops,
};
Is this a systemic mistake in all the static domains in all the drivers?
Maybe a bigger check is a more complete fix:
static bool iommu_domain_compatible(struct device *dev, struct iommu_domain *domain) { const struct iommu_ops *ops = dev_iommu_ops(dev);
if (domain->owner == ops) return true;
/* For static domains owner isn't set */ if (ops->blocked_domain == domain || ops->identity_domain == domain) return true; return false; }
Jason
On 4/23/25 03:15, Jason Gunthorpe wrote:
On Tue, Apr 22, 2025 at 03:54:22PM +0800, Lu Baolu wrote:
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index cb0b993bebb4..63c9c97ccf69 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -4385,6 +4385,7 @@ static struct iommu_domain identity_domain = { .attach_dev = identity_domain_attach_dev, .set_dev_pasid = identity_domain_set_dev_pasid, },
- .owner = &intel_iommu_ops, };
Is this a systemic mistake in all the static domains in all the drivers?
Yes. The owner field is not set for all static domains.
Maybe a bigger check is a more complete fix:
static bool iommu_domain_compatible(struct device *dev, struct iommu_domain *domain) { const struct iommu_ops *ops = dev_iommu_ops(dev);
if (domain->owner == ops) return true;
/* For static domains owner isn't set */ if (ops->blocked_domain == domain || ops->identity_domain == domain) return true; return false; }
That's better. I will post a v2 accordingly.
Jason
Thanks, baolu
linux-stable-mirror@lists.linaro.org