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.

iommu: Add iommu_driver_get_domain_for_dev() helper

There is a need to stage a resetting PCI device to temporarily the blocked
domain and then attach back to its previously attached domain after reset.

This can be simply done by keeping the "previously attached domain" in the
iommu_group->domain pointer while adding an iommu_group->resetting_domain,
which gives troubles to IOMMU drivers using the iommu_get_domain_for_dev()
for a device's physical domain in order to program IOMMU hardware.

And in such for-driver use cases, the iommu_group->mutex must be held, so
it doesn't fit in external callers that don't hold the iommu_group->mutex.

Introduce a new iommu_driver_get_domain_for_dev() helper, exclusively for
driver use cases that hold the iommu_group->mutex, to separate from those
external use cases.

Add a lockdep_assert_not_held to the existing iommu_get_domain_for_dev()
and highlight that in a kdoc.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com>
Signed-off-by: Nicolin Chen <nicolinc@nvidia.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>

authored by

Nicolin Chen and committed by
Joerg Roedel
a75b2be2 4a73abb9

+32 -2
+3 -2
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
··· 3125 3125 struct arm_smmu_domain *smmu_domain, ioasid_t pasid, 3126 3126 struct arm_smmu_cd *cd, struct iommu_domain *old) 3127 3127 { 3128 - struct iommu_domain *sid_domain = iommu_get_domain_for_dev(master->dev); 3128 + struct iommu_domain *sid_domain = 3129 + iommu_driver_get_domain_for_dev(master->dev); 3129 3130 struct arm_smmu_attach_state state = { 3130 3131 .master = master, 3131 3132 .ssid = pasid, ··· 3192 3191 */ 3193 3192 if (!arm_smmu_ssids_in_use(&master->cd_table)) { 3194 3193 struct iommu_domain *sid_domain = 3195 - iommu_get_domain_for_dev(master->dev); 3194 + iommu_driver_get_domain_for_dev(master->dev); 3196 3195 3197 3196 if (sid_domain->type == IOMMU_DOMAIN_IDENTITY || 3198 3197 sid_domain->type == IOMMU_DOMAIN_BLOCKED)
+28
drivers/iommu/iommu.c
··· 2217 2217 } 2218 2218 EXPORT_SYMBOL_GPL(iommu_detach_device); 2219 2219 2220 + /** 2221 + * iommu_get_domain_for_dev() - Return the DMA API domain pointer 2222 + * @dev: Device to query 2223 + * 2224 + * This function can be called within a driver bound to dev. The returned 2225 + * pointer is valid for the lifetime of the bound driver. 2226 + * 2227 + * It should not be called by drivers with driver_managed_dma = true. 2228 + */ 2220 2229 struct iommu_domain *iommu_get_domain_for_dev(struct device *dev) 2221 2230 { 2222 2231 /* Caller must be a probed driver on dev */ ··· 2234 2225 if (!group) 2235 2226 return NULL; 2236 2227 2228 + lockdep_assert_not_held(&group->mutex); 2229 + 2237 2230 return group->domain; 2238 2231 } 2239 2232 EXPORT_SYMBOL_GPL(iommu_get_domain_for_dev); 2233 + 2234 + /** 2235 + * iommu_driver_get_domain_for_dev() - Return the driver-level domain pointer 2236 + * @dev: Device to query 2237 + * 2238 + * This function can be called by an iommu driver that wants to get the physical 2239 + * domain within an iommu callback function where group->mutex is held. 2240 + */ 2241 + struct iommu_domain *iommu_driver_get_domain_for_dev(struct device *dev) 2242 + { 2243 + struct iommu_group *group = dev->iommu_group; 2244 + 2245 + lockdep_assert_held(&group->mutex); 2246 + 2247 + return group->domain; 2248 + } 2249 + EXPORT_SYMBOL_GPL(iommu_driver_get_domain_for_dev); 2240 2250 2241 2251 /* 2242 2252 * For IOMMU_DOMAIN_DMA implementations which already provide their own
+1
include/linux/iommu.h
··· 910 910 extern void iommu_detach_device(struct iommu_domain *domain, 911 911 struct device *dev); 912 912 extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); 913 + struct iommu_domain *iommu_driver_get_domain_for_dev(struct device *dev); 913 914 extern struct iommu_domain *iommu_get_dma_domain(struct device *dev); 914 915 extern int iommu_map(struct iommu_domain *domain, unsigned long iova, 915 916 phys_addr_t paddr, size_t size, int prot, gfp_t gfp);