Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On 2024/3/23 1:06, Jason Gunthorpe wrote: On Fri, Mar 15, 2024 at 09:16:43AM +0800, Baolu Lu wrote: On 3/9/24 3:05 AM, Jason Gunthorpe wrote: On Mon, Jan 22, 2024 at 03:39:00PM +0800, Lu Baolu wrote: @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { * @__reserved: Must be 0 * @data_type: One of enum iommu_hwpt_data_type * @data_len: Length of the type specific data + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of + *IOMMU_HWPT_FAULT_ID_VALID is set. * @data_uptr: User pointer to the type specific data * * Explicitly allocate a hardware page table object. This is the same object @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { __u32 __reserved; __u32 data_type; __u32 data_len; + __u32 fault_id; __aligned_u64 data_uptr; }; ?? We can't add fault_id in the middle of the struct?? Yes. I should add the new field at the end. By the way, with a __u32 added, this data structure is not 64-byte- aligned anymore. Do we need to add another unused u32 entry, or just let the compiler handle it? Yes, add a reserved u32 to ensure the structs is always without implicit padding. Sure. + if (cmd->flags & IOMMU_HWPT_FAULT_ID_VALID) { + struct iommufd_fault *fault; + + fault = iommufd_get_fault(ucmd, cmd->fault_id); + if (IS_ERR(fault)) { + rc = PTR_ERR(fault); + goto out_hwpt; + } + hwpt->fault = fault; + hwpt->domain->iopf_handler = iommufd_fault_iopf_handler; + hwpt->domain->fault_data = hwpt; + hwpt->fault_capable = true; I wonder if there should be an iommu API to make a domain fault capable? The iommu core identifies a fault-capable domain by checking its domain->iopf_handler. Anyway, what's the difference between a fault or non-fault capable domain from iommu core's point of view? From the core? Nothing. I'm just wondering from an API perspective if we should have a little inline to indicate it. I have no objection if there's a consumer for it. Best regards, baolu
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On Fri, Mar 15, 2024 at 09:16:43AM +0800, Baolu Lu wrote: > On 3/9/24 3:05 AM, Jason Gunthorpe wrote: > > On Mon, Jan 22, 2024 at 03:39:00PM +0800, Lu Baolu wrote: > > > > > @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { > > >* @__reserved: Must be 0 > > >* @data_type: One of enum iommu_hwpt_data_type > > >* @data_len: Length of the type specific data > > > + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field > > > of > > > + *IOMMU_HWPT_FAULT_ID_VALID is set. > > >* @data_uptr: User pointer to the type specific data > > >* > > >* Explicitly allocate a hardware page table object. This is the same > > > object > > > @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { > > > __u32 __reserved; > > > __u32 data_type; > > > __u32 data_len; > > > + __u32 fault_id; > > > __aligned_u64 data_uptr; > > > }; > > > > ?? We can't add fault_id in the middle of the struct?? > > Yes. I should add the new field at the end. > > By the way, with a __u32 added, this data structure is not 64-byte- > aligned anymore. Do we need to add another unused u32 entry, or just let > the compiler handle it? Yes, add a reserved u32 to ensure the structs is always without implicit padding. > > > > > + if (cmd->flags & IOMMU_HWPT_FAULT_ID_VALID) { > > > + struct iommufd_fault *fault; > > > + > > > + fault = iommufd_get_fault(ucmd, cmd->fault_id); > > > + if (IS_ERR(fault)) { > > > + rc = PTR_ERR(fault); > > > + goto out_hwpt; > > > + } > > > + hwpt->fault = fault; > > > + hwpt->domain->iopf_handler = iommufd_fault_iopf_handler; > > > + hwpt->domain->fault_data = hwpt; > > > + hwpt->fault_capable = true; > > > > I wonder if there should be an iommu API to make a domain fault > > capable? > > The iommu core identifies a fault-capable domain by checking its > domain->iopf_handler. Anyway, what's the difference between a fault or > non-fault capable domain from iommu core's point of view? >From the core? Nothing. I'm just wondering from an API perspective if we should have a little inline to indicate it. Jason
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On 3/9/24 3:05 AM, Jason Gunthorpe wrote: On Mon, Jan 22, 2024 at 03:39:00PM +0800, Lu Baolu wrote: @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { * @__reserved: Must be 0 * @data_type: One of enum iommu_hwpt_data_type * @data_len: Length of the type specific data + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of + *IOMMU_HWPT_FAULT_ID_VALID is set. * @data_uptr: User pointer to the type specific data * * Explicitly allocate a hardware page table object. This is the same object @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { __u32 __reserved; __u32 data_type; __u32 data_len; + __u32 fault_id; __aligned_u64 data_uptr; }; ?? We can't add fault_id in the middle of the struct?? Yes. I should add the new field at the end. By the way, with a __u32 added, this data structure is not 64-byte- aligned anymore. Do we need to add another unused u32 entry, or just let the compiler handle it? + if (cmd->flags & IOMMU_HWPT_FAULT_ID_VALID) { + struct iommufd_fault *fault; + + fault = iommufd_get_fault(ucmd, cmd->fault_id); + if (IS_ERR(fault)) { + rc = PTR_ERR(fault); + goto out_hwpt; + } + hwpt->fault = fault; + hwpt->domain->iopf_handler = iommufd_fault_iopf_handler; + hwpt->domain->fault_data = hwpt; + hwpt->fault_capable = true; I wonder if there should be an iommu API to make a domain fault capable? The iommu core identifies a fault-capable domain by checking its domain->iopf_handler. Anyway, what's the difference between a fault or non-fault capable domain from iommu core's point of view? Best regards, baolu
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On Mon, Jan 22, 2024 at 03:39:00PM +0800, Lu Baolu wrote: > @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { > * @__reserved: Must be 0 > * @data_type: One of enum iommu_hwpt_data_type > * @data_len: Length of the type specific data > + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of > + *IOMMU_HWPT_FAULT_ID_VALID is set. > * @data_uptr: User pointer to the type specific data > * > * Explicitly allocate a hardware page table object. This is the same object > @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { > __u32 __reserved; > __u32 data_type; > __u32 data_len; > + __u32 fault_id; > __aligned_u64 data_uptr; > }; ?? We can't add fault_id in the middle of the struct?? > + if (cmd->flags & IOMMU_HWPT_FAULT_ID_VALID) { > + struct iommufd_fault *fault; > + > + fault = iommufd_get_fault(ucmd, cmd->fault_id); > + if (IS_ERR(fault)) { > + rc = PTR_ERR(fault); > + goto out_hwpt; > + } > + hwpt->fault = fault; > + hwpt->domain->iopf_handler = iommufd_fault_iopf_handler; > + hwpt->domain->fault_data = hwpt; > + hwpt->fault_capable = true; I wonder if there should be an iommu API to make a domain fault capable? Jason
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On 2024/3/7 0:01, Jason Gunthorpe wrote: On Wed, Mar 06, 2024 at 11:15:50PM +0800, Zhangfei Gao wrote: Double checked, this does not send flags, 0 is OK, Only domain_alloc_user in iommufd_hwpt_paging_alloc requires flags. In my debug, I need this patch, otherwise NULL pointer errors happen since SVA is not set. This is some driver bug, we need to get rid of these iommu_dev_enable_feature() requirements. Yes. Especially iopf should be independent of SVA. The problem in the arm smmu v3 driver is that enabling iopf is actually done in the enabling SVA path, while the enabling iopf path does nothing except for some checks. It doesn't matter if iopf is tied with SVA, but when it comes to delivering iopf to user space, we need to decouple it. Best regards, baolu
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On Wed, Mar 06, 2024 at 11:15:50PM +0800, Zhangfei Gao wrote: > > Double checked, this does not send flags, 0 is OK, > Only domain_alloc_user in iommufd_hwpt_paging_alloc requires flags. > > In my debug, I need this patch, otherwise NULL pointer errors happen > since SVA is not set. This is some driver bug, we need to get rid of these iommu_dev_enable_feature() requirements. Attaching domains with properties should be entirely sufficient. Jason
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
Hi, Baolu On Sat, 2 Mar 2024 at 10:36, Zhangfei Gao wrote: > > On Mon, 22 Jan 2024 at 15:46, Lu Baolu wrote: > > > > When allocating a user iommufd_hw_pagetable, the user space is allowed to > > associate a fault object with the hw_pagetable by specifying the fault > > object ID in the page table allocation data and setting the > > IOMMU_HWPT_FAULT_ID_VALID flag bit. > > > > On a successful return of hwpt allocation, the user can retrieve and > > respond to page faults by reading and writing the file interface of the > > fault object. > > > > Once a fault object has been associated with a hwpt, the hwpt is > > iopf-capable, indicated by fault_capable set to true. Attaching, > > detaching, or replacing an iopf-capable hwpt to an RID or PASID will > > differ from those that are not iopf-capable. The implementation of these > > will be introduced in the next patch. > > > > Signed-off-by: Lu Baolu > > --- > > drivers/iommu/iommufd/iommufd_private.h | 11 > > include/uapi/linux/iommufd.h| 6 + > > drivers/iommu/iommufd/fault.c | 14 ++ > > drivers/iommu/iommufd/hw_pagetable.c| 36 +++-- > > 4 files changed, 59 insertions(+), 8 deletions(-) > > > > diff --git a/drivers/iommu/iommufd/iommufd_private.h > > b/drivers/iommu/iommufd/iommufd_private.h > > index 52d83e888bd0..2780bed0c6b1 100644 > > --- a/drivers/iommu/iommufd/iommufd_private.h > > +++ b/drivers/iommu/iommufd/iommufd_private.h > > @@ -293,6 +293,8 @@ int iommufd_check_iova_range(struct io_pagetable *iopt, > > struct iommufd_hw_pagetable { > > struct iommufd_object obj; > > struct iommu_domain *domain; > > + struct iommufd_fault *fault; > > + bool fault_capable : 1; > > }; > > > > struct iommufd_hwpt_paging { > > @@ -446,8 +448,17 @@ struct iommufd_fault { > > struct wait_queue_head wait_queue; > > }; > > > > +static inline struct iommufd_fault * > > +iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id) > > +{ > > + return container_of(iommufd_get_object(ucmd->ictx, id, > > + IOMMUFD_OBJ_FAULT), > > + struct iommufd_fault, obj); > > +} > > + > > int iommufd_fault_alloc(struct iommufd_ucmd *ucmd); > > void iommufd_fault_destroy(struct iommufd_object *obj); > > +int iommufd_fault_iopf_handler(struct iopf_group *group); > > > > #ifdef CONFIG_IOMMUFD_TEST > > int iommufd_test(struct iommufd_ucmd *ucmd); > > diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h > > index c32d62b02306..7481cdd57027 100644 > > --- a/include/uapi/linux/iommufd.h > > +++ b/include/uapi/linux/iommufd.h > > @@ -357,10 +357,13 @@ struct iommu_vfio_ioas { > > *the parent HWPT in a nesting > > configuration. > > * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device > > IOMMU is > > * enforced on device attachment > > + * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data > > is > > + * valid. > > */ > > enum iommufd_hwpt_alloc_flags { > > IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, > > IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, > > + IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, > > }; > > > > /** > > @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { > > * @__reserved: Must be 0 > > * @data_type: One of enum iommu_hwpt_data_type > > * @data_len: Length of the type specific data > > + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of > > + *IOMMU_HWPT_FAULT_ID_VALID is set. > > * @data_uptr: User pointer to the type specific data > > * > > * Explicitly allocate a hardware page table object. This is the same > > object > > @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { > > __u32 __reserved; > > __u32 data_type; > > __u32 data_len; > > + __u32 fault_id; > > __aligned_u64 data_uptr; > > }; > > #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) > > diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c > > index 9844a85feeb2..e752d1c49dde 100644 > > --- a/drivers/iommu/iommufd/fault.c > > +++ b/drivers/iommu/iommufd/fault.c > > @@ -253,3 +253,17 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd) > > > > return rc; > > } > > + > > +int iommufd_fault_iopf_handler(struct iopf_group *group) > > +{ > > + struct iommufd_hw_pagetable *hwpt = > > group->cookie->domain->fault_data; > > + struct iommufd_fault *fault = hwpt->fault; > > + > > + mutex_lock(>mutex); > > + list_add_tail(>node, >deliver); > > + mutex_unlock(>mutex); > > + > > + wake_up_interruptible(>wait_queue); > > + > > + return 0; > > +} > > diff --git a/drivers/iommu/iommufd/hw_pagetable.c > > b/drivers/iommu/iommufd/hw_pagetable.c > > index 3f3f1fa1a0a9..2703d5aea4f5 100644 > > ---
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On Mon, 22 Jan 2024 at 15:46, Lu Baolu wrote: > > When allocating a user iommufd_hw_pagetable, the user space is allowed to > associate a fault object with the hw_pagetable by specifying the fault > object ID in the page table allocation data and setting the > IOMMU_HWPT_FAULT_ID_VALID flag bit. > > On a successful return of hwpt allocation, the user can retrieve and > respond to page faults by reading and writing the file interface of the > fault object. > > Once a fault object has been associated with a hwpt, the hwpt is > iopf-capable, indicated by fault_capable set to true. Attaching, > detaching, or replacing an iopf-capable hwpt to an RID or PASID will > differ from those that are not iopf-capable. The implementation of these > will be introduced in the next patch. > > Signed-off-by: Lu Baolu > --- > drivers/iommu/iommufd/iommufd_private.h | 11 > include/uapi/linux/iommufd.h| 6 + > drivers/iommu/iommufd/fault.c | 14 ++ > drivers/iommu/iommufd/hw_pagetable.c| 36 +++-- > 4 files changed, 59 insertions(+), 8 deletions(-) > > diff --git a/drivers/iommu/iommufd/iommufd_private.h > b/drivers/iommu/iommufd/iommufd_private.h > index 52d83e888bd0..2780bed0c6b1 100644 > --- a/drivers/iommu/iommufd/iommufd_private.h > +++ b/drivers/iommu/iommufd/iommufd_private.h > @@ -293,6 +293,8 @@ int iommufd_check_iova_range(struct io_pagetable *iopt, > struct iommufd_hw_pagetable { > struct iommufd_object obj; > struct iommu_domain *domain; > + struct iommufd_fault *fault; > + bool fault_capable : 1; > }; > > struct iommufd_hwpt_paging { > @@ -446,8 +448,17 @@ struct iommufd_fault { > struct wait_queue_head wait_queue; > }; > > +static inline struct iommufd_fault * > +iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id) > +{ > + return container_of(iommufd_get_object(ucmd->ictx, id, > + IOMMUFD_OBJ_FAULT), > + struct iommufd_fault, obj); > +} > + > int iommufd_fault_alloc(struct iommufd_ucmd *ucmd); > void iommufd_fault_destroy(struct iommufd_object *obj); > +int iommufd_fault_iopf_handler(struct iopf_group *group); > > #ifdef CONFIG_IOMMUFD_TEST > int iommufd_test(struct iommufd_ucmd *ucmd); > diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h > index c32d62b02306..7481cdd57027 100644 > --- a/include/uapi/linux/iommufd.h > +++ b/include/uapi/linux/iommufd.h > @@ -357,10 +357,13 @@ struct iommu_vfio_ioas { > *the parent HWPT in a nesting configuration. > * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU > is > * enforced on device attachment > + * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is > + * valid. > */ > enum iommufd_hwpt_alloc_flags { > IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, > IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, > + IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, > }; > > /** > @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { > * @__reserved: Must be 0 > * @data_type: One of enum iommu_hwpt_data_type > * @data_len: Length of the type specific data > + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of > + *IOMMU_HWPT_FAULT_ID_VALID is set. > * @data_uptr: User pointer to the type specific data > * > * Explicitly allocate a hardware page table object. This is the same object > @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { > __u32 __reserved; > __u32 data_type; > __u32 data_len; > + __u32 fault_id; > __aligned_u64 data_uptr; > }; > #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) > diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c > index 9844a85feeb2..e752d1c49dde 100644 > --- a/drivers/iommu/iommufd/fault.c > +++ b/drivers/iommu/iommufd/fault.c > @@ -253,3 +253,17 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd) > > return rc; > } > + > +int iommufd_fault_iopf_handler(struct iopf_group *group) > +{ > + struct iommufd_hw_pagetable *hwpt = group->cookie->domain->fault_data; > + struct iommufd_fault *fault = hwpt->fault; > + > + mutex_lock(>mutex); > + list_add_tail(>node, >deliver); > + mutex_unlock(>mutex); > + > + wake_up_interruptible(>wait_queue); > + > + return 0; > +} > diff --git a/drivers/iommu/iommufd/hw_pagetable.c > b/drivers/iommu/iommufd/hw_pagetable.c > index 3f3f1fa1a0a9..2703d5aea4f5 100644 > --- a/drivers/iommu/iommufd/hw_pagetable.c > +++ b/drivers/iommu/iommufd/hw_pagetable.c > @@ -8,6 +8,15 @@ > #include "../iommu-priv.h" > #include "iommufd_private.h" > > +static void __iommufd_hwpt_destroy(struct iommufd_hw_pagetable *hwpt) > +{ > + if (hwpt->domain) > + iommu_domain_free(hwpt->domain); > + > +
Re: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
On 2024/2/7 16:14, Tian, Kevin wrote: From: Lu Baolu Sent: Monday, January 22, 2024 3:39 PM + +int iommufd_fault_iopf_handler(struct iopf_group *group) +{ + struct iommufd_hw_pagetable *hwpt = group->cookie->domain- fault_data; + struct iommufd_fault *fault = hwpt->fault; + why not directly using iommufd_fault as the fault_data? The relationship among these structures is: iommufd_hwpt -> iommu_domain ^ | v iommufd_fault It appears preferable to hook the hwpt instead of iommufd_fault to an iommu_domain structure. Best regards, baolu
RE: [PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
> From: Lu Baolu > Sent: Monday, January 22, 2024 3:39 PM > > + > +int iommufd_fault_iopf_handler(struct iopf_group *group) > +{ > + struct iommufd_hw_pagetable *hwpt = group->cookie->domain- > >fault_data; > + struct iommufd_fault *fault = hwpt->fault; > + why not directly using iommufd_fault as the fault_data?
[PATCH v3 5/8] iommufd: Associate fault object with iommufd_hw_pgtable
When allocating a user iommufd_hw_pagetable, the user space is allowed to associate a fault object with the hw_pagetable by specifying the fault object ID in the page table allocation data and setting the IOMMU_HWPT_FAULT_ID_VALID flag bit. On a successful return of hwpt allocation, the user can retrieve and respond to page faults by reading and writing the file interface of the fault object. Once a fault object has been associated with a hwpt, the hwpt is iopf-capable, indicated by fault_capable set to true. Attaching, detaching, or replacing an iopf-capable hwpt to an RID or PASID will differ from those that are not iopf-capable. The implementation of these will be introduced in the next patch. Signed-off-by: Lu Baolu --- drivers/iommu/iommufd/iommufd_private.h | 11 include/uapi/linux/iommufd.h| 6 + drivers/iommu/iommufd/fault.c | 14 ++ drivers/iommu/iommufd/hw_pagetable.c| 36 +++-- 4 files changed, 59 insertions(+), 8 deletions(-) diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index 52d83e888bd0..2780bed0c6b1 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -293,6 +293,8 @@ int iommufd_check_iova_range(struct io_pagetable *iopt, struct iommufd_hw_pagetable { struct iommufd_object obj; struct iommu_domain *domain; + struct iommufd_fault *fault; + bool fault_capable : 1; }; struct iommufd_hwpt_paging { @@ -446,8 +448,17 @@ struct iommufd_fault { struct wait_queue_head wait_queue; }; +static inline struct iommufd_fault * +iommufd_get_fault(struct iommufd_ucmd *ucmd, u32 id) +{ + return container_of(iommufd_get_object(ucmd->ictx, id, + IOMMUFD_OBJ_FAULT), + struct iommufd_fault, obj); +} + int iommufd_fault_alloc(struct iommufd_ucmd *ucmd); void iommufd_fault_destroy(struct iommufd_object *obj); +int iommufd_fault_iopf_handler(struct iopf_group *group); #ifdef CONFIG_IOMMUFD_TEST int iommufd_test(struct iommufd_ucmd *ucmd); diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h index c32d62b02306..7481cdd57027 100644 --- a/include/uapi/linux/iommufd.h +++ b/include/uapi/linux/iommufd.h @@ -357,10 +357,13 @@ struct iommu_vfio_ioas { *the parent HWPT in a nesting configuration. * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU is * enforced on device attachment + * @IOMMU_HWPT_FAULT_ID_VALID: The fault_id field of hwpt allocation data is + * valid. */ enum iommufd_hwpt_alloc_flags { IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, + IOMMU_HWPT_FAULT_ID_VALID = 1 << 2, }; /** @@ -411,6 +414,8 @@ enum iommu_hwpt_data_type { * @__reserved: Must be 0 * @data_type: One of enum iommu_hwpt_data_type * @data_len: Length of the type specific data + * @fault_id: The ID of IOMMUFD_FAULT object. Valid only if flags field of + *IOMMU_HWPT_FAULT_ID_VALID is set. * @data_uptr: User pointer to the type specific data * * Explicitly allocate a hardware page table object. This is the same object @@ -441,6 +446,7 @@ struct iommu_hwpt_alloc { __u32 __reserved; __u32 data_type; __u32 data_len; + __u32 fault_id; __aligned_u64 data_uptr; }; #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) diff --git a/drivers/iommu/iommufd/fault.c b/drivers/iommu/iommufd/fault.c index 9844a85feeb2..e752d1c49dde 100644 --- a/drivers/iommu/iommufd/fault.c +++ b/drivers/iommu/iommufd/fault.c @@ -253,3 +253,17 @@ int iommufd_fault_alloc(struct iommufd_ucmd *ucmd) return rc; } + +int iommufd_fault_iopf_handler(struct iopf_group *group) +{ + struct iommufd_hw_pagetable *hwpt = group->cookie->domain->fault_data; + struct iommufd_fault *fault = hwpt->fault; + + mutex_lock(>mutex); + list_add_tail(>node, >deliver); + mutex_unlock(>mutex); + + wake_up_interruptible(>wait_queue); + + return 0; +} diff --git a/drivers/iommu/iommufd/hw_pagetable.c b/drivers/iommu/iommufd/hw_pagetable.c index 3f3f1fa1a0a9..2703d5aea4f5 100644 --- a/drivers/iommu/iommufd/hw_pagetable.c +++ b/drivers/iommu/iommufd/hw_pagetable.c @@ -8,6 +8,15 @@ #include "../iommu-priv.h" #include "iommufd_private.h" +static void __iommufd_hwpt_destroy(struct iommufd_hw_pagetable *hwpt) +{ + if (hwpt->domain) + iommu_domain_free(hwpt->domain); + + if (hwpt->fault) + iommufd_put_object(hwpt->fault->ictx, >fault->obj); +} + void iommufd_hwpt_paging_destroy(struct iommufd_object *obj) { struct iommufd_hwpt_paging *hwpt_paging = @@ -22,9 +31,7 @@ void iommufd_hwpt_paging_destroy(struct iommufd_object *obj)