From patchwork Sat Dec 2 09:22:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yan Zhao X-Patchwork-Id: 172773 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp1674967vqy; Sat, 2 Dec 2023 01:51:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IHhPw8hUqyYIiquX7UnueKuNUrJR8KC4aIxJuEyuB4bwSskj/pT62bKhMh2BM3+COvyEO/a X-Received: by 2002:a92:c642:0:b0:35c:d832:5d5d with SMTP id 2-20020a92c642000000b0035cd8325d5dmr1069205ill.27.1701510713906; Sat, 02 Dec 2023 01:51:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701510713; cv=none; d=google.com; s=arc-20160816; b=O6prWPcZ5cDiGFH7z8KRslexXg/6hLt4XbRAI4uGr1DKKZcd7haEvPYj+gOGQ4bLgS ukDw6TbmLOJpIDLAtsXWQmnKM1KmXsY7K5cU35gXXABlbcjszX5hThp9lUNxzMa2SeaX faqOdoFKWZsOjJbbxWclMO3FxmMXrJYMZTDRIuv/PNahh6qd07z9XXl1mE2Xpi2NUN3T QaRNL1aEy9eCrG2XPiApH0Q1ygT8hyGzfzTnV3vrA5MwUqDnNGNB/xmwTmlrHJykeBYL g+AZK81NgwOJiqpfmLaPN/Vp/okz1G9/082yZEDEzn6LbjiQQsEADICdPUuMnUPcmmcz ju+A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dkim-signature; bh=KJ2Q2A39DH+A4PKOKXTb3yeKoiHY/W1TA/zjV25kzSg=; fh=+WI4m5k3dRLR+dR3neThuZkNBTzIm/a8HgtddERL9fA=; b=iDWJ0iWvSXqXwOPTUjUcV3GTYFJhYfvdbkHYro/1cLeEH1tmb2CPdaqoJdwuMfT0Zn lKk4WhHwmI+5bBXwQmCRrmkxrEt6SRBFqnGg0Gm7g89nWqMlxuCx1rPKSmb11DHgpIuJ ySwcj6pEY3OuIbdhMyFuOIThoNbANKjwlwmYT44vt4gPa1W8VQpJlE/YxhHJAvfdoE3l j3BWES+V0IJlJvg0njk/kzfgAp0/ubO9aPtaLmNz66WM3k9OEuH9TWFaiMQNdFzrVK2v 5xOhxUQUUfpppvd4XLLy9tRv7uMIzTlLhr85fSD6SOpQfXwN4BnKSoOq4qsWDXlToEI+ gCUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=PIS21ewV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:1 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from morse.vger.email (morse.vger.email. [2620:137:e000::3:1]) by mx.google.com with ESMTPS id l10-20020a170903244a00b001cf69216445si4881999pls.392.2023.12.02.01.51.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 Dec 2023 01:51:53 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:1 as permitted sender) client-ip=2620:137:e000::3:1; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=PIS21ewV; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:1 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id 24CAB82B8A47; Sat, 2 Dec 2023 01:51:50 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232405AbjLBJvk (ORCPT + 99 others); Sat, 2 Dec 2023 04:51:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229451AbjLBJvi (ORCPT ); Sat, 2 Dec 2023 04:51:38 -0500 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7ADA198; Sat, 2 Dec 2023 01:51:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701510705; x=1733046705; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=5tHj8FjpQu1zOKHpkDFSKBA08iJcnSpgfGv/y1ivWLI=; b=PIS21ewVdl6gu0+KyLc6oR27/mLImYs8GDdGT0vGnzMPTh0vaYOjxGtX KUk7TxUrdomXdrNBJFmiHBv2fkByQW97XFzS4+THiSTpHlFHW19+Ug9wt u7sWe68qaPrDiFn+nGEdFhX15piqHpgv2rQqw0/mGSBE8wAPj2V0/8L9g 5Ej/MzpswILuT8bkAMGgCH3IGeWVcrz3flIzBXDNw4lwJj7f47x/xWert vK0HQlUU0efw9Eq6r0oBNwKE7ns6QaV6UXo5g2AYVw9QGb9wiwhIFEdII lcjSsn2mEWD1OOOwbnBgmJ+I2rUZoucyKKhIW40gjvXgQ3b0Gi7FuZinY A==; X-IronPort-AV: E=McAfee;i="6600,9927,10911"; a="6886646" X-IronPort-AV: E=Sophos;i="6.04,245,1695711600"; d="scan'208";a="6886646" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Dec 2023 01:51:45 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10911"; a="746280146" X-IronPort-AV: E=Sophos;i="6.04,245,1695711600"; d="scan'208";a="746280146" Received: from yzhao56-desk.sh.intel.com ([10.239.159.62]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Dec 2023 01:51:40 -0800 From: Yan Zhao To: iommu@lists.linux.dev, kvm@vger.kernel.org, linux-kernel@vger.kernel.org Cc: alex.williamson@redhat.com, jgg@nvidia.com, pbonzini@redhat.com, seanjc@google.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, kevin.tian@intel.com, baolu.lu@linux.intel.com, dwmw2@infradead.org, yi.l.liu@intel.com, Yan Zhao Subject: [RFC PATCH 15/42] iommufd: Add iopf handler to KVM hw pagetable Date: Sat, 2 Dec 2023 17:22:45 +0800 Message-Id: <20231202092245.14335-1-yan.y.zhao@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20231202091211.13376-1-yan.y.zhao@intel.com> References: <20231202091211.13376-1-yan.y.zhao@intel.com> X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Sat, 02 Dec 2023 01:51:50 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784163298654479537 X-GMAIL-MSGID: 1784163298654479537 Add iopf handler to KVM HW page table. The iopf handler is implemented to forward IO page fault requests to KVM and return complete status back to IOMMU driver via iommu_page_response(). Signed-off-by: Yan Zhao --- drivers/iommu/iommufd/hw_pagetable_kvm.c | 87 ++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/drivers/iommu/iommufd/hw_pagetable_kvm.c b/drivers/iommu/iommufd/hw_pagetable_kvm.c index e0e205f384ed5..bff9fa3d9f703 100644 --- a/drivers/iommu/iommufd/hw_pagetable_kvm.c +++ b/drivers/iommu/iommufd/hw_pagetable_kvm.c @@ -6,6 +6,89 @@ #include "../iommu-priv.h" #include "iommufd_private.h" +static int iommufd_kvmtdp_fault(void *data, struct mm_struct *mm, + unsigned long addr, u32 perm) +{ + struct iommufd_hw_pagetable *hwpt = data; + struct kvm_tdp_fault_type fault_type = {0}; + unsigned long gfn = addr >> PAGE_SHIFT; + struct kvm_tdp_fd *tdp_fd; + int ret; + + if (!hwpt || !hwpt_is_kvm(hwpt)) + return IOMMU_PAGE_RESP_INVALID; + + tdp_fd = to_hwpt_kvm(hwpt)->context; + if (!tdp_fd->ops->fault) + return IOMMU_PAGE_RESP_INVALID; + + fault_type.read = !!(perm & IOMMU_FAULT_PERM_READ); + fault_type.write = !!(perm & IOMMU_FAULT_PERM_WRITE); + fault_type.exec = !!(perm & IOMMU_FAULT_PERM_EXEC); + + ret = tdp_fd->ops->fault(tdp_fd, mm, gfn, fault_type); + return ret ? IOMMU_PAGE_RESP_FAILURE : IOMMU_PAGE_RESP_SUCCESS; +} + +static int iommufd_kvmtdp_complete_group(struct device *dev, struct iopf_fault *iopf, + enum iommu_page_response_code status) +{ + struct iommu_page_response resp = { + .pasid = iopf->fault.prm.pasid, + .grpid = iopf->fault.prm.grpid, + .code = status, + }; + + if ((iopf->fault.prm.flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID) && + (iopf->fault.prm.flags & IOMMU_FAULT_PAGE_RESPONSE_NEEDS_PASID)) + resp.flags = IOMMU_PAGE_RESP_PASID_VALID; + + return iommu_page_response(dev, &resp); +} + +static void iommufd_kvmtdp_handle_iopf(struct work_struct *work) +{ + struct iopf_fault *iopf; + struct iopf_group *group; + enum iommu_page_response_code status = IOMMU_PAGE_RESP_SUCCESS; + struct iommu_domain *domain; + void *fault_data; + int ret; + + group = container_of(work, struct iopf_group, work); + domain = group->domain; + fault_data = domain->fault_data; + + list_for_each_entry(iopf, &group->faults, list) { + /* + * For the moment, errors are sticky: don't handle subsequent + * faults in the group if there is an error. + */ + if (status != IOMMU_PAGE_RESP_SUCCESS) + break; + + status = iommufd_kvmtdp_fault(fault_data, domain->mm, + iopf->fault.prm.addr, + iopf->fault.prm.perm); + } + + ret = iommufd_kvmtdp_complete_group(group->dev, &group->last_fault, status); + + iopf_free_group(group); + +} + +static int iommufd_kvmtdp_iopf_handler(struct iopf_group *group) +{ + struct iommu_fault_param *fault_param = group->dev->iommu->fault_param; + + INIT_WORK(&group->work, iommufd_kvmtdp_handle_iopf); + if (!queue_work(fault_param->queue->wq, &group->work)) + return -EBUSY; + + return 0; +} + static void iommufd_kvmtdp_invalidate(void *data, unsigned long start, unsigned long size) { @@ -169,6 +252,10 @@ iommufd_hwpt_kvm_alloc(struct iommufd_ctx *ictx, goto out_abort; } + hwpt->domain->mm = current->mm; + hwpt->domain->iopf_handler = iommufd_kvmtdp_iopf_handler; + hwpt->domain->fault_data = hwpt; + rc = kvmtdp_register(tdp_fd, hwpt); if (rc) goto out_abort;