Received: by 2002:a05:6358:45e:b0:b5:b6eb:e1f9 with SMTP id 30csp317391rwe; Fri, 26 Aug 2022 05:44:33 -0700 (PDT) X-Google-Smtp-Source: AA6agR6UoburT001B8RBMvVcN2TFFTE6cQwhFvOqyhVvIFmBdrPYzmVaZ532eS435tW6XJilKuJ5 X-Received: by 2002:a17:902:7845:b0:16e:d647:a66c with SMTP id e5-20020a170902784500b0016ed647a66cmr3453321pln.64.1661517872829; Fri, 26 Aug 2022 05:44:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661517872; cv=none; d=google.com; s=arc-20160816; b=jFnXTWhAUm7Zcxzr0kItfksYop0HTfqu0+EFz6MIEJigL05xRhUCSTGCDA/KxE4UQA JqJeE7akE8jW/IiVp19YVmR+XGd1tBHkA8Q8GjBMhZEgKeJMSINsFmUWurbA/9WdI4s+ EiaaKmr2qja22U8LBjbrQvVdvixALY9pfXl3spZPi5MEWp/hA5d5o5g0cdJnckf2gRqV j6GT376Ca/OYxuZUYRdbvVpiLW1yhBN/cGHmFidwAWlOwwQKaPx8jolAHCAOwOpbS2z1 jjVrp1p7RBoU2IIa/9JrZqUQbHRpE1afKaOTEVpy65Ks+qu9/ETQnlhsv8pm8ngESXRE N3Fg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=ZKqk9rEtyQokdbYqZo+vWxllfHlr+ziVbSr1wgQw4xE=; b=czVID6dOIkEc62RqHi9HuPjjUZLS9DZxdvYRVNAeb9TjyUGMOGSk6x91Lw5onCW03A E3vvT2sdvlM91qvk1fhMPCcEWm/xbMjXPkGy2RPYDRY8yf25xnUOGLWucTzfwGnO3TKA 3KDZNqyAh38HD2HPyFJsMTJi1RAcc/pK0cWKSimGnqR/iYwj0L4OJCajF2VKRMnhHh59 Gxep4CdGaDEKLb1oR7bYc7u80jzJQdm6N37xOctvMhr7V8saLhTvfImNEIsUH2Rn1gbp RzJZ0dNSxAQEDervQ+OocZ1GcJjpkl23R0BzQWGKyV20VX3K9+PoCIOZhlnUDhqWH9Lp S4zg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=VWpdrWg0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id m189-20020a6326c6000000b0041bd356a2a7si1629660pgm.422.2022.08.26.05.44.21; Fri, 26 Aug 2022 05:44:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=VWpdrWg0; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344175AbiHZMTk (ORCPT + 99 others); Fri, 26 Aug 2022 08:19:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344126AbiHZMSi (ORCPT ); Fri, 26 Aug 2022 08:18:38 -0400 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 94AEBDEA58; Fri, 26 Aug 2022 05:18:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1661516317; x=1693052317; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=7R85Whub3M9uZCnJrvM1kzuZxCbMYVPKJZigAY4Yo8w=; b=VWpdrWg0ZJ0zCKDVyJIbPcxe3K+FCuamoIW2y206sHYCwNLkG/wNItC2 ACkwNXMdAN6xFPqrZjPphU7yUovKbG79ciSq9Z4HiH0erY7fl/7Ql6kFd YRCj8cNwEWT7+usnktafz/usJFdAnCFcq2pTFG/+wETleQX5yNbhLKrix vt2P8CXp1HDV3MsPAFQfR86xn6eufzIrmRrfNuvWVOdJRYBrqnxOAz9Wk 3RHx97L25fPxnBiBNPfamus0o18R6sSw1q69Y+Hv/UzHW51qK1tfbTnld GO7GJ7sr6BF0zZPf7eRbA4vzYrFOL4Afz+w5PzEWTLEhqwtdUaKH1H/mh g==; X-IronPort-AV: E=McAfee;i="6500,9779,10450"; a="320587427" X-IronPort-AV: E=Sophos;i="5.93,265,1654585200"; d="scan'208";a="320587427" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Aug 2022 05:18:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,265,1654585200"; d="scan'208";a="606747864" Received: from allen-box.sh.intel.com ([10.239.159.48]) by orsmga007.jf.intel.com with ESMTP; 26 Aug 2022 05:18:32 -0700 From: Lu Baolu To: Joerg Roedel , Jason Gunthorpe , Christoph Hellwig , Bjorn Helgaas , Kevin Tian , Ashok Raj , Will Deacon , Robin Murphy , Jean-Philippe Brucker , Dave Jiang , Fenghua Yu , Vinod Koul Cc: Eric Auger , Liu Yi L , Jacob jun Pan , Zhangfei Gao , Zhu Tony , iommu@lists.linux.dev, linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Lu Baolu , Jean-Philippe Brucker Subject: [PATCH v12 16/17] iommu: Per-domain I/O page fault handling Date: Fri, 26 Aug 2022 20:11:40 +0800 Message-Id: <20220826121141.50743-17-baolu.lu@linux.intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220826121141.50743-1-baolu.lu@linux.intel.com> References: <20220826121141.50743-1-baolu.lu@linux.intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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() won't free the domain until all the pending page requests have been flushed from the pipeline. The drivers either call iopf_queue_flush_dev() explicitly, or in stall case, the device driver is required to flush all DMAs including stalled transactions before calling unbind(). This also renames iopf_handle_group() to iopf_handler() to avoid confusing. Signed-off-by: Lu Baolu Reviewed-by: Jean-Philippe Brucker Reviewed-by: Kevin Tian Reviewed-by: Jason Gunthorpe Tested-by: Zhangfei Gao Tested-by: Tony Zhu --- drivers/iommu/io-pgfault.c | 68 +++++--------------------------------- 1 file changed, 9 insertions(+), 59 deletions(-) diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index aee9e033012f..d046d89cec55 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) +static void iopf_handler(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, 0); + 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)) @@ -242,7 +192,7 @@ int iommu_queue_iopf(struct iommu_fault *fault, void *cookie) group->last_fault.fault = *fault; INIT_LIST_HEAD(&group->faults); list_add(&group->last_fault.list, &group->faults); - INIT_WORK(&group->work, iopf_handle_group); + INIT_WORK(&group->work, iopf_handler); /* See if we have partial faults for this group */ list_for_each_entry_safe(iopf, next, &iopf_param->partial, list) { -- 2.25.1