summaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommu-sva.c
diff options
context:
space:
mode:
authorLu Baolu <baolu.lu@linux.intel.com>2024-02-12 09:22:23 +0800
committerJoerg Roedel <jroedel@suse.de>2024-02-16 15:19:33 +0100
commita74c077b9021b36c785095c571336e5b204d3c2d (patch)
tree7e33054cae25270ebce39c5549050b1e4a69dbb1 /drivers/iommu/iommu-sva.c
parentcc7338e9d807e20e60e6720a62956f0e9d46f0f8 (diff)
downloadlinux-a74c077b9021b36c785095c571336e5b204d3c2d.tar.gz
linux-a74c077b9021b36c785095c571336e5b204d3c2d.tar.bz2
linux-a74c077b9021b36c785095c571336e5b204d3c2d.zip
iommu: Use refcount for fault data access
The per-device fault data structure stores information about faults occurring on a device. Its lifetime spans from IOPF enablement to disablement. Multiple paths, including IOPF reporting, handling, and responding, may access it concurrently. Previously, a mutex protected the fault data from use after free. But this is not performance friendly due to the critical nature of IOPF handling paths. Refine this with a refcount-based approach. The fault data pointer is obtained within an RCU read region with a refcount. The fault data pointer is returned for usage only when the pointer is valid and a refcount is successfully obtained. The fault data is freed with kfree_rcu(), ensuring data is only freed after all RCU critical regions complete. An iopf handling work starts once an iopf group is created. The handling work continues until iommu_page_response() is called to respond to the iopf and the iopf group is freed. During this time, the device fault parameter should always be available. Add a pointer to the device fault parameter in the iopf_group structure and hold the reference until the iopf_group is freed. Make iommu_page_response() static as it is only used in io-pgfault.c. Co-developed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Tested-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://lore.kernel.org/r/20240212012227.119381-13-baolu.lu@linux.intel.com Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/iommu-sva.c')
-rw-r--r--drivers/iommu/iommu-sva.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index 9de878e40413..b51995b4fe90 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -251,7 +251,7 @@ static void iommu_sva_handle_iopf(struct work_struct *work)
static int iommu_sva_iopf_handler(struct iopf_group *group)
{
- struct iommu_fault_param *fault_param = group->dev->iommu->fault_param;
+ struct iommu_fault_param *fault_param = group->fault_param;
INIT_WORK(&group->work, iommu_sva_handle_iopf);
if (!queue_work(fault_param->queue->wq, &group->work))