Messages in this thread | | | Date | Tue, 3 May 2022 19:27:40 +0100 | From | Jean-Philippe Brucker <> | Subject | Re: [PATCH v5 11/12] iommu: Per-domain I/O page fault handling |
| |
On Mon, May 02, 2022 at 09:48:41AM +0800, Lu Baolu wrote: > Tweak the I/O page fault handling framework to route the page faults to > the domain and call the page fault handler retrieved from the domain. > This makes the I/O page fault handling framework possible to serve more > usage scenarios as long as they have an IOMMU domain and install a page > fault handler in it. Some unused functions are also removed to avoid > dead code. > > Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
> --- > drivers/iommu/iommu-sva-lib.h | 1 - > drivers/iommu/io-pgfault.c | 64 ++++------------------------------- > drivers/iommu/iommu-sva-lib.c | 20 ----------- > 3 files changed, 7 insertions(+), 78 deletions(-) > > diff --git a/drivers/iommu/iommu-sva-lib.h b/drivers/iommu/iommu-sva-lib.h > index 5776b4c80cc1..e7813c6706fb 100644 > --- a/drivers/iommu/iommu-sva-lib.h > +++ b/drivers/iommu/iommu-sva-lib.h > @@ -8,7 +8,6 @@ > #include <linux/ioasid.h> > #include <linux/mm_types.h> > > -struct mm_struct *iommu_sva_find(ioasid_t pasid); > struct mm_struct *iommu_sva_domain_mm(struct iommu_domain *domain); > > /* I/O Page fault */ > diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c > index 1df8c1dcae77..8a2bb56e1474 100644 > --- a/drivers/iommu/io-pgfault.c > +++ b/drivers/iommu/io-pgfault.c > @@ -69,69 +69,18 @@ static int iopf_complete_group(struct device *dev, struct iopf_fault *iopf, > return iommu_page_response(dev, &resp); > } > > -static enum iommu_page_response_code > -iopf_handle_single(struct iopf_fault *iopf) > -{ > - vm_fault_t ret; > - struct mm_struct *mm; > - struct vm_area_struct *vma; > - unsigned int access_flags = 0; > - unsigned int fault_flags = FAULT_FLAG_REMOTE; > - struct iommu_fault_page_request *prm = &iopf->fault.prm; > - enum iommu_page_response_code status = IOMMU_PAGE_RESP_INVALID; > - > - if (!(prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID)) > - return status; > - > - mm = iommu_sva_find(prm->pasid); > - if (IS_ERR_OR_NULL(mm)) > - return status; > - > - mmap_read_lock(mm); > - > - vma = find_extend_vma(mm, prm->addr); > - if (!vma) > - /* Unmapped area */ > - goto out_put_mm; > - > - if (prm->perm & IOMMU_FAULT_PERM_READ) > - access_flags |= VM_READ; > - > - if (prm->perm & IOMMU_FAULT_PERM_WRITE) { > - access_flags |= VM_WRITE; > - fault_flags |= FAULT_FLAG_WRITE; > - } > - > - if (prm->perm & IOMMU_FAULT_PERM_EXEC) { > - access_flags |= VM_EXEC; > - fault_flags |= FAULT_FLAG_INSTRUCTION; > - } > - > - if (!(prm->perm & IOMMU_FAULT_PERM_PRIV)) > - fault_flags |= FAULT_FLAG_USER; > - > - if (access_flags & ~vma->vm_flags) > - /* Access fault */ > - goto out_put_mm; > - > - ret = handle_mm_fault(vma, prm->addr, fault_flags, NULL); > - status = ret & VM_FAULT_ERROR ? IOMMU_PAGE_RESP_INVALID : > - IOMMU_PAGE_RESP_SUCCESS; > - > -out_put_mm: > - mmap_read_unlock(mm); > - mmput(mm); > - > - return status; > -} > - > static void iopf_handle_group(struct work_struct *work) > { > struct iopf_group *group; > + struct iommu_domain *domain; > struct iopf_fault *iopf, *next; > enum iommu_page_response_code status = IOMMU_PAGE_RESP_SUCCESS; > > group = container_of(work, struct iopf_group, work); > + domain = iommu_get_domain_for_dev_pasid(group->dev, > + group->last_fault.fault.prm.pasid); > + if (!domain || !domain->iopf_handler) > + status = IOMMU_PAGE_RESP_INVALID; > > list_for_each_entry_safe(iopf, next, &group->faults, list) { > /* > @@ -139,7 +88,8 @@ static void iopf_handle_group(struct work_struct *work) > * faults in the group if there is an error. > */ > if (status == IOMMU_PAGE_RESP_SUCCESS) > - status = iopf_handle_single(iopf); > + status = domain->iopf_handler(&iopf->fault, > + domain->fault_data); > > if (!(iopf->fault.prm.flags & > IOMMU_FAULT_PAGE_REQUEST_LAST_PAGE)) > diff --git a/drivers/iommu/iommu-sva-lib.c b/drivers/iommu/iommu-sva-lib.c > index 05a7d2f0e46f..ae3595d60f38 100644 > --- a/drivers/iommu/iommu-sva-lib.c > +++ b/drivers/iommu/iommu-sva-lib.c > @@ -69,26 +69,6 @@ static int iommu_sva_alloc_pasid(struct mm_struct *mm, > return ret; > } > > -/* ioasid_find getter() requires a void * argument */ > -static bool __mmget_not_zero(void *mm) > -{ > - return mmget_not_zero(mm); > -} > - > -/** > - * iommu_sva_find() - Find mm associated to the given PASID > - * @pasid: Process Address Space ID assigned to the mm > - * > - * On success a reference to the mm is taken, and must be released with mmput(). > - * > - * Returns the mm corresponding to this PASID, or an error if not found. > - */ > -struct mm_struct *iommu_sva_find(ioasid_t pasid) > -{ > - return ioasid_find(&iommu_sva_pasid, pasid, __mmget_not_zero); > -} > -EXPORT_SYMBOL_GPL(iommu_sva_find); > - > /* > * Get or put an ioas for a shared memory. > */ > -- > 2.25.1 >
| |