From: Lu Baolu <baolu.lu@linux.intel.com> To: Joerg Roedel <joro@8bytes.org>, Jason Gunthorpe <jgg@nvidia.com>, Christoph Hellwig <hch@infradead.org>, Kevin Tian <kevin.tian@intel.com>, Ashok Raj <ashok.raj@intel.com>, Will Deacon <will@kernel.org>, Robin Murphy <robin.murphy@arm.com>, Jean-Philippe Brucker <jean-philippe@linaro.com>, Dave Jiang <dave.jiang@intel.com>, Vinod Koul <vkoul@kernel.org> Cc: Eric Auger <eric.auger@redhat.com>, Liu Yi L <yi.l.liu@intel.com>, Jacob jun Pan <jacob.jun.pan@intel.com>, iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, Lu Baolu <baolu.lu@linux.intel.com>, Jean-Philippe Brucker <jean-philippe@linaro.org> Subject: [PATCH v7 09/10] iommu: Per-domain I/O page fault handling Date: Thu, 19 May 2022 15:20:46 +0800 [thread overview] Message-ID: <20220519072047.2996983-10-baolu.lu@linux.intel.com> (raw) In-Reply-To: <20220519072047.2996983-1-baolu.lu@linux.intel.com> 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. The iommu_get_domain_for_dev_pasid() which retrieves attached domain for a {device, PASID} pair is used. It will be used by the page fault handling framework which knows {device, PASID} reported from the iommu driver. We have a guarantee that the SVA domain doesn't go away during IOPF handling, because unbind() waits for pending faults with iopf_queue_flush_dev() before freeing the domain. Hence, there's no need to synchronize life cycle of the iommu domains between the unbind() and the interrupt threads. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- drivers/iommu/io-pgfault.c | 64 +++++--------------------------------- 1 file changed, 7 insertions(+), 57 deletions(-) diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index aee9e033012f..4f24ec703479 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)) -- 2.25.1
WARNING: multiple messages have this Message-ID (diff)
From: Lu Baolu <baolu.lu@linux.intel.com> To: Joerg Roedel <joro@8bytes.org>, Jason Gunthorpe <jgg@nvidia.com>, Christoph Hellwig <hch@infradead.org>, Kevin Tian <kevin.tian@intel.com>, Ashok Raj <ashok.raj@intel.com>, Will Deacon <will@kernel.org>, Robin Murphy <robin.murphy@arm.com>, Jean-Philippe Brucker <jean-philippe@linaro.com>, Dave Jiang <dave.jiang@intel.com>, Vinod Koul <vkoul@kernel.org> Cc: Jean-Philippe Brucker <jean-philippe@linaro.org>, linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org, Jacob jun Pan <jacob.jun.pan@intel.com> Subject: [PATCH v7 09/10] iommu: Per-domain I/O page fault handling Date: Thu, 19 May 2022 15:20:46 +0800 [thread overview] Message-ID: <20220519072047.2996983-10-baolu.lu@linux.intel.com> (raw) In-Reply-To: <20220519072047.2996983-1-baolu.lu@linux.intel.com> 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. The iommu_get_domain_for_dev_pasid() which retrieves attached domain for a {device, PASID} pair is used. It will be used by the page fault handling framework which knows {device, PASID} reported from the iommu driver. We have a guarantee that the SVA domain doesn't go away during IOPF handling, because unbind() waits for pending faults with iopf_queue_flush_dev() before freeing the domain. Hence, there's no need to synchronize life cycle of the iommu domains between the unbind() and the interrupt threads. Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- drivers/iommu/io-pgfault.c | 64 +++++--------------------------------- 1 file changed, 7 insertions(+), 57 deletions(-) diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index aee9e033012f..4f24ec703479 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)) -- 2.25.1 _______________________________________________ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
next prev parent reply other threads:[~2022-05-19 7:25 UTC|newest] Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-05-19 7:20 [PATCH v7 00/10] iommu: SVA and IOPF refactoring Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 7:20 ` [PATCH v7 01/10] iommu: Add pasids field in struct iommu_device Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 10:37 ` Jean-Philippe Brucker 2022-05-19 10:37 ` Jean-Philippe Brucker 2022-05-19 11:55 ` Baolu Lu 2022-05-19 11:55 ` Baolu Lu 2022-05-24 9:24 ` Tian, Kevin 2022-05-24 9:24 ` Tian, Kevin 2022-05-25 2:03 ` Baolu Lu 2022-05-25 2:03 ` Baolu Lu 2022-05-25 2:13 ` Baolu Lu 2022-05-25 2:13 ` Baolu Lu 2022-05-19 7:20 ` [PATCH v7 02/10] iommu: Remove SVM_FLAG_SUPERVISOR_MODE support Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 16:22 ` Jean-Philippe Brucker 2022-05-19 16:22 ` Jean-Philippe Brucker 2022-05-24 9:27 ` Tian, Kevin 2022-05-24 9:27 ` Tian, Kevin 2022-05-19 7:20 ` [PATCH v7 03/10] iommu/sva: Add iommu_sva_domain support Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 16:33 ` Jean-Philippe Brucker 2022-05-19 16:33 ` Jean-Philippe Brucker 2022-05-20 4:55 ` Baolu Lu 2022-05-20 4:55 ` Baolu Lu 2022-05-23 7:12 ` Baolu Lu 2022-05-23 7:12 ` Baolu Lu 2022-05-24 9:44 ` Tian, Kevin 2022-05-24 9:44 ` Tian, Kevin 2022-05-25 2:18 ` Baolu Lu 2022-05-25 2:18 ` Baolu Lu 2022-05-24 9:39 ` Tian, Kevin 2022-05-24 9:39 ` Tian, Kevin 2022-05-24 13:38 ` Jason Gunthorpe 2022-05-24 13:38 ` Jason Gunthorpe via iommu 2022-05-25 0:44 ` Tian, Kevin 2022-05-25 0:44 ` Tian, Kevin 2022-05-25 2:38 ` Baolu Lu 2022-05-25 2:38 ` Baolu Lu 2022-05-25 4:50 ` Baolu Lu 2022-05-25 4:50 ` Baolu Lu 2022-05-24 13:44 ` Jason Gunthorpe 2022-05-24 13:44 ` Jason Gunthorpe via iommu 2022-05-25 5:19 ` Baolu Lu 2022-05-25 5:19 ` Baolu Lu 2022-05-25 15:25 ` Jason Gunthorpe 2022-05-25 15:25 ` Jason Gunthorpe via iommu 2022-05-26 1:03 ` Baolu Lu 2022-05-26 1:03 ` Baolu Lu 2022-05-25 5:33 ` Baolu Lu 2022-05-25 5:33 ` Baolu Lu 2022-05-24 14:36 ` Robin Murphy 2022-05-24 14:36 ` Robin Murphy 2022-05-25 6:20 ` Baolu Lu 2022-05-25 6:20 ` Baolu Lu 2022-05-25 10:07 ` Robin Murphy 2022-05-25 10:07 ` Robin Murphy 2022-05-25 11:06 ` Jean-Philippe Brucker 2022-05-25 11:06 ` Jean-Philippe Brucker 2022-05-25 13:11 ` Baolu Lu 2022-05-25 13:11 ` Baolu Lu 2022-05-19 7:20 ` [PATCH v7 04/10] iommu/vt-d: Add SVA domain support Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 7:20 ` [PATCH v7 05/10] arm-smmu-v3/sva: " Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 16:37 ` Jean-Philippe Brucker 2022-05-19 16:37 ` Jean-Philippe Brucker 2022-05-19 7:20 ` [PATCH v7 06/10] iommu/sva: Refactoring iommu_sva_bind/unbind_device() Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 16:39 ` Jean-Philippe Brucker 2022-05-19 16:39 ` Jean-Philippe Brucker 2022-05-20 6:38 ` Baolu Lu 2022-05-20 6:38 ` Baolu Lu 2022-05-20 11:28 ` Jean-Philippe Brucker 2022-05-20 11:28 ` Jean-Philippe Brucker 2022-05-23 3:07 ` Baolu Lu 2022-05-23 3:07 ` Baolu Lu 2022-05-24 10:22 ` Tian, Kevin 2022-05-24 10:22 ` Tian, Kevin 2022-05-24 10:57 ` Jean-Philippe Brucker 2022-05-24 10:57 ` Jean-Philippe Brucker 2022-05-25 2:04 ` Tian, Kevin 2022-05-25 2:04 ` Tian, Kevin 2022-05-25 7:29 ` Jean-Philippe Brucker 2022-05-25 7:29 ` Jean-Philippe Brucker 2022-06-02 6:46 ` Tian, Kevin 2022-06-02 6:46 ` Tian, Kevin 2022-05-19 7:20 ` [PATCH v7 07/10] iommu: Remove SVA related callbacks from iommu ops Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-24 10:23 ` Tian, Kevin 2022-05-24 10:23 ` Tian, Kevin 2022-05-19 7:20 ` [PATCH v7 08/10] iommu: Prepare IOMMU domain for IOPF Lu Baolu 2022-05-19 7:20 ` Lu Baolu 2022-05-19 16:40 ` Jean-Philippe Brucker 2022-05-19 16:40 ` Jean-Philippe Brucker 2022-05-19 7:20 ` Lu Baolu [this message] 2022-05-19 7:20 ` [PATCH v7 09/10] iommu: Per-domain I/O page fault handling Lu Baolu 2022-05-19 7:20 ` [PATCH v7 10/10] iommu: Rename iommu-sva-lib.{c,h} Lu Baolu 2022-05-19 7:20 ` Lu Baolu
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220519072047.2996983-10-baolu.lu@linux.intel.com \ --to=baolu.lu@linux.intel.com \ --cc=ashok.raj@intel.com \ --cc=dave.jiang@intel.com \ --cc=eric.auger@redhat.com \ --cc=hch@infradead.org \ --cc=iommu@lists.linux-foundation.org \ --cc=jacob.jun.pan@intel.com \ --cc=jean-philippe@linaro.com \ --cc=jean-philippe@linaro.org \ --cc=jgg@nvidia.com \ --cc=joro@8bytes.org \ --cc=kevin.tian@intel.com \ --cc=linux-kernel@vger.kernel.org \ --cc=robin.murphy@arm.com \ --cc=vkoul@kernel.org \ --cc=will@kernel.org \ --cc=yi.l.liu@intel.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.