@@ -574,11 +574,26 @@ static struct hw_pgtable_fault *hw_pagetable_fault_alloc(int eventfd)
return ERR_PTR(rc);
}
+static void iommufd_fault_list_destroy(struct hw_pgtable_fault *fault,
+ struct list_head *list)
+{
+ struct iommufd_fault *ifault;
+
+ mutex_lock(&fault->mutex);
+ while (!list_empty(list)) {
+ ifault = list_first_entry(list, struct iommufd_fault, item);
+ if (iommufd_fault_timer_teardown(ifault))
+ drain_iopf_fault(ifault);
+ list_del_init(&ifault->item);
+ iommufd_put_fault(ifault);
+ }
+ mutex_unlock(&fault->mutex);
+}
+
static void hw_pagetable_fault_free(struct hw_pgtable_fault *fault)
{
- WARN_ON(!list_empty(&fault->deliver));
- WARN_ON(!list_empty(&fault->response));
-
+ iommufd_fault_list_destroy(fault, &fault->deliver);
+ iommufd_fault_list_destroy(fault, &fault->response);
eventfd_ctx_put(fault->trigger);
kfree(fault);
}
When a HWPT is unexpectedly destroyed, drain all faults in the pending lists. It is safe because the iommu domain has been released and there will never be new io page faults anymore. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> --- drivers/iommu/iommufd/hw_pagetable.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)