Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iommufd: Enforce PASID-compatible domain in PASID path

AMD IOMMU requires attaching PASID-compatible domains to PASID-capable
devices. This includes the domains attached to RID and PASIDs. Related
discussions in link [1] and [2]. ARM also has such a requirement, Intel
does not need it, but can live up with it. Hence, iommufd is going to
enforce this requirement as it is not harmful to vendors that do not
need it.

Mark the PASID-compatible domains and enforce it in the PASID path.

[1] https://lore.kernel.org/linux-iommu/20240709182303.GK14050@ziepe.ca/
[2] https://lore.kernel.org/linux-iommu/20240822124433.GD3468552@ziepe.ca/

Link: https://patch.msgid.link/r/20250321171940.7213-11-yi.l.liu@intel.com
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
Tested-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Yi Liu and committed by
Jason Gunthorpe
ff3f014e c0e301b2

+21
+17
drivers/iommu/iommufd/device.c
··· 395 395 return xa_load(&attach->device_array, idev->obj.id); 396 396 } 397 397 398 + static int iommufd_hwpt_pasid_compat(struct iommufd_hw_pagetable *hwpt, 399 + struct iommufd_device *idev, 400 + ioasid_t pasid) 401 + { 402 + if (pasid != IOMMU_NO_PASID && !hwpt->pasid_compat) 403 + return -EINVAL; 404 + return 0; 405 + } 406 + 398 407 static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt, 399 408 struct iommufd_device *idev, 400 409 ioasid_t pasid) ··· 412 403 int rc; 413 404 414 405 lockdep_assert_held(&idev->igroup->lock); 406 + 407 + rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid); 408 + if (rc) 409 + return rc; 415 410 416 411 handle = kzalloc(sizeof(*handle), GFP_KERNEL); 417 412 if (!handle) ··· 484 471 int rc; 485 472 486 473 WARN_ON(pasid != IOMMU_NO_PASID); 474 + 475 + rc = iommufd_hwpt_pasid_compat(hwpt, idev, pasid); 476 + if (rc) 477 + return rc; 487 478 488 479 old_handle = iommufd_device_get_attach_handle(idev, pasid); 489 480
+3
drivers/iommu/iommufd/hw_pagetable.c
··· 136 136 if (IS_ERR(hwpt_paging)) 137 137 return ERR_CAST(hwpt_paging); 138 138 hwpt = &hwpt_paging->common; 139 + hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID; 139 140 140 141 INIT_LIST_HEAD(&hwpt_paging->hwpt_item); 141 142 /* Pairs with iommufd_hw_pagetable_destroy() */ ··· 245 244 if (IS_ERR(hwpt_nested)) 246 245 return ERR_CAST(hwpt_nested); 247 246 hwpt = &hwpt_nested->common; 247 + hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID; 248 248 249 249 refcount_inc(&parent->common.obj.users); 250 250 hwpt_nested->parent = parent; ··· 302 300 if (IS_ERR(hwpt_nested)) 303 301 return ERR_CAST(hwpt_nested); 304 302 hwpt = &hwpt_nested->common; 303 + hwpt->pasid_compat = flags & IOMMU_HWPT_ALLOC_PASID; 305 304 306 305 hwpt_nested->viommu = viommu; 307 306 refcount_inc(&viommu->obj.users);
+1
drivers/iommu/iommufd/iommufd_private.h
··· 299 299 struct iommufd_object obj; 300 300 struct iommu_domain *domain; 301 301 struct iommufd_fault *fault; 302 + bool pasid_compat : 1; 302 303 }; 303 304 304 305 struct iommufd_hwpt_paging {