Re: [PATCH v10 10/12] iommu: Prepare IOMMU domain for IOPF

From: Baolu Lu
Date: Sun Jul 24 2022 - 10:05:04 EST


On 2022/7/23 22:33, Jason Gunthorpe wrote:
On Tue, Jul 05, 2022 at 01:07:08PM +0800, Lu Baolu wrote:
This adds some mechanisms around the iommu_domain so that the I/O page
fault handling framework could route a page fault to the domain and
call the fault handler from it.

Add pointers to the page fault handler and its private data in struct
iommu_domain. The fault handler will be called with the private data
as a parameter once a page fault is routed to the domain. Any kernel
component which owns an iommu domain could install handler and its
private parameter so that the page fault could be further routed and
handled.

This also prepares the SVA implementation to be the first consumer of
the per-domain page fault handling model. The I/O page fault handler
for SVA is copied to the SVA file with mmget_not_zero() added before
mmap_read_lock().

Suggested-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
Reviewed-by: Jean-Philippe Brucker <jean-philippe@xxxxxxxxxx>
Tested-by: Zhangfei Gao <zhangfei.gao@xxxxxxxxxx>
Tested-by: Tony Zhu <tony.zhu@xxxxxxxxx>
---
include/linux/iommu.h | 3 ++
drivers/iommu/iommu-sva-lib.h | 8 +++++
drivers/iommu/io-pgfault.c | 7 +++++
drivers/iommu/iommu-sva-lib.c | 58 +++++++++++++++++++++++++++++++++++
drivers/iommu/iommu.c | 4 +++
5 files changed, 80 insertions(+)

diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ae0cfca064e6..47610f21d451 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -105,6 +105,9 @@ struct iommu_domain {
unsigned long pgsize_bitmap; /* Bitmap of page sizes in use */
struct iommu_domain_geometry geometry;
struct iommu_dma_cookie *iova_cookie;
+ enum iommu_page_response_code (*iopf_handler)(struct iommu_fault *fault,
+ void *data);
+ void *fault_data;
union {
struct {
iommu_fault_handler_t handler;

Why do we need two falut callbacks? The only difference is that one is
recoverable and the other is not, right?

Can we run both down the same op?

The iommu_fault_handler_t is for report_iommu_fault() which could be
replaced with the newer iommu_report_device_fault().

https://lore.kernel.org/linux-iommu/Yo4Nw9QyllT1RZbd@myrica/


+/*
+ * I/O page fault handler for SVA
+ */
+enum iommu_page_response_code
+iommu_sva_handle_iopf(struct iommu_fault *fault, void *data)
+{
+ vm_fault_t ret;
+ struct vm_area_struct *vma;
+ struct mm_struct *mm = data;
+ unsigned int access_flags = 0;
+ unsigned int fault_flags = FAULT_FLAG_REMOTE;
+ struct iommu_fault_page_request *prm = &fault->prm;
+ enum iommu_page_response_code status = IOMMU_PAGE_RESP_INVALID;
+
+ if (!(prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID))
+ return status;
+
+ if (IS_ERR_OR_NULL(mm) || !mmget_not_zero(mm))

Do not use IS_ERR_ON_NULL. mm should never be null here since the
fault handler should have been removed from the domain before the
fault_data is changed.

Yes. Updated.

Best regards,
baolu