Received: by 2002:a05:7412:b10a:b0:f3:1519:9f41 with SMTP id az10csp1590371rdb; Sat, 2 Dec 2023 01:51:57 -0800 (PST) X-Google-Smtp-Source: AGHT+IHAvpEzUWm9EsVkGTKiK61K2xiA/34fxHXXfHjmL/fRTQGZww5qG+pQm/jFVJgBsXzxurro X-Received: by 2002:a5e:8f0b:0:b0:7b4:28f8:d7 with SMTP id c11-20020a5e8f0b000000b007b428f800d7mr1173401iok.32.1701510717227; Sat, 02 Dec 2023 01:51:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701510717; cv=none; d=google.com; s=arc-20160816; b=uvW8Ycuwp4iS+g3tP51SBOyj9Si+0ZfG2YjLEHKcDiFg/q1GAk58EJY/vIp5SCiLVR Xg4hYTnGZwsR/paLU2rydvyHpgAw+dLUkBjUibGqegAmjroRw3aQlnJfkUAjZb5puCyu WQM34Grzj5Rb1ySHcucS/LtHiZ/MWRLk0QhzTFXQyToXS1ZVHutiRHo/4HAR9KDhgQ2q mBpX81nFnwGzZJJtTv4MRfPP7/nI10TtC0fltuUfSS72CMyff4bb4fltMfLbnAuO680Q CQoVs/BVK11wtbeMghb/UWyE4RTv02hSdMIGsBT+5rZp5vRsSJuNSLnapkP1g7Cw5VH1 /A9w== 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 23.128.96.31 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 morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id t6-20020a1709028c8600b001cfa22e6bd7si4683346plo.179.2023.12.02.01.51.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 Dec 2023 01:51:57 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; 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 23.128.96.31 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 12DE7808725A; Sat, 2 Dec 2023 01:51:55 -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:55 -0800 (PST) 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; -- 2.17.1