From patchwork Sat Dec 2 09:13:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yan Zhao X-Patchwork-Id: 172759 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:bcd1:0:b0:403:3b70:6f57 with SMTP id r17csp1672378vqy; Sat, 2 Dec 2023 01:42:39 -0800 (PST) X-Google-Smtp-Source: AGHT+IElneBM1dRhe6ELav0IIRj3GgElZmquApU+R22oyIMhp++SsMGYUEZpBKtb+HhfCwq5p6Tz X-Received: by 2002:a05:6808:1143:b0:3b8:b063:6ba7 with SMTP id u3-20020a056808114300b003b8b0636ba7mr1397964oiu.86.1701510159725; Sat, 02 Dec 2023 01:42:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701510159; cv=none; d=google.com; s=arc-20160816; b=ZclxHDw5nejgA0ZMdnY2TpgwYoMt9lL5GYhDBw9rspzVMiSDHivLXYc0nhGxay6uAj vK8ZMYM6YEihUROibK3JuKWUY+f9Sy2CJ/ZgDaY27NuA10Ci3fdpjML9fjuCWAhAUkrD /gdBYJGEJyPOq34eXF8yrt5jQR52ZtjxcRdQ9E+u3hMyMjAQ6rhxjr/TTP6e3VERXpTi hKH6kW7Qd9kjCNryi1rm+L0UwHcXg5B9Y0KzPazfwNOYL+ImbdoFcK8Fy56sUPBfw190 i3IpRpP2eQp9/4RskzHVPdnbfRRBlCj9BfHk4M9nOFbi/NQ8QXL93ujOBVEUSAgD3Uv0 076A== 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=gRniOLfZ4Up353axQzF28aGUSvsS61TwVE5SB8xCoEY=; fh=+WI4m5k3dRLR+dR3neThuZkNBTzIm/a8HgtddERL9fA=; b=LVXCu/Wap0wrBD3G9x5hAef61ROg8QZqU84/M9DvGiPiV86pLkiPUbnavTsIvczL9z cBXRSqEAkus9k4sdMGi2OiCOByFjOE6HFCLTzgvdF8EemcRlwAJt+AsNkESKpi7Xr7HW XWZVZ9PJAlQZECWGTFrSLhQfJwS25O4izKTRr5dT4sCRmZKeiPLJx0VzCFw5+SKNLsmw /LL0GwDg29YhDmjWKpCgFnrx0fm87LSZrzBLQphVmK7/MYPCnKEmnd9z37Ib0kuYGAnF kAkUfwSZVkljZAWn7KwrqBQOcZBY3SMN7W7fjABWiHWTKzmg9Zhw6PamfTweIGh/JtnE FwcQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=FmnHunGa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 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 pete.vger.email (pete.vger.email. [23.128.96.36]) by mx.google.com with ESMTPS id s7-20020a170902b18700b001cff624a64asi4636301plr.532.2023.12.02.01.42.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 02 Dec 2023 01:42:39 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 as permitted sender) client-ip=23.128.96.36; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=FmnHunGa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.36 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 pete.vger.email (Postfix) with ESMTP id 785FE831411D; Sat, 2 Dec 2023 01:42:34 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231984AbjLBJm0 (ORCPT + 99 others); Sat, 2 Dec 2023 04:42:26 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53190 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229472AbjLBJmY (ORCPT ); Sat, 2 Dec 2023 04:42:24 -0500 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E76FC129; Sat, 2 Dec 2023 01:42:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1701510150; x=1733046150; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=nR/psJ1R705oxKAaTJeTprEYjfrf/NpWHn/y7k4WDWk=; b=FmnHunGaHs7cezVOUapSseOo2uOYSrJkAGr91I3yxShEV4kk7W15LlRy CfAYIQmd75BDQnKLC2CIphJUedxYXTfsutXgcp69PJYkWY7/izPZMXZ3Z mzrpxFvbHAJYEdGHKY5/P6WiS5onHnUd38VDiSyxJt0M8wQinuD5wjx4X xJ7rvZmSNdarAS4ZAiqX1acDqkwykwq39oWMLw3mNZGG/bL4+Srh9KA1f F7V64cHVcIs9Vu21WFJaxDzHk7X9UH/CFhnoLRFygxE+cbi88BVhGfmBQ /Tvi/1FdKP0lQy3hKAhRI6HZz2xQTrRMGmBUNxZ5SOe3FY7lcgrWmhwiF w==; X-IronPort-AV: E=McAfee;i="6600,9927,10911"; a="424755031" X-IronPort-AV: E=Sophos;i="6.04,245,1695711600"; d="scan'208";a="424755031" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Dec 2023 01:42:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10911"; a="836018614" X-IronPort-AV: E=Sophos;i="6.04,245,1695711600"; d="scan'208";a="836018614" Received: from yzhao56-desk.sh.intel.com ([10.239.159.62]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Dec 2023 01:42:26 -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 01/42] KVM: Public header for KVM to export TDP Date: Sat, 2 Dec 2023 17:13:24 +0800 Message-Id: <20231202091324.13436-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 pete.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 (pete.vger.email [0.0.0.0]); Sat, 02 Dec 2023 01:42:34 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1784162717162218934 X-GMAIL-MSGID: 1784162717162218934 Introduce public header for data structures and interfaces for KVM to export TDP page table (EPT/NPT in x86) to external components of KVM. KVM exposes a TDP FD object which allows external components to get page table meta data, request mapping, and register invalidation callbacks to the TDP page table exported by KVM. Two symbols kvm_tdp_fd_get() and kvm_tdp_fd_put() are exported by KVM to external components to get/put the TDP FD object. New header file kvm_tdp_fd.h is added because kvm_host.h is not expected to be included from outside of KVM in future AFAIK. Signed-off-by: Yan Zhao --- include/linux/kvm_tdp_fd.h | 137 +++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 include/linux/kvm_tdp_fd.h diff --git a/include/linux/kvm_tdp_fd.h b/include/linux/kvm_tdp_fd.h new file mode 100644 index 0000000000000..3661779dd8cf5 --- /dev/null +++ b/include/linux/kvm_tdp_fd.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __KVM_TDP_FD_H +#define __KVM_TDP_FD_H + +#include +#include + +struct kvm_exported_tdp; +struct kvm_exported_tdp_ops; +struct kvm_tdp_importer_ops; + +/** + * struct kvm_tdp_fd - KVM TDP FD object + * + * Interface of exporting KVM TDP page table to external components of KVM. + * + * This KVM TDP FD object is created by KVM VM ioctl KVM_CREATE_TDP_FD. + * On object creation, KVM will find or create a TDP page table, mark it as + * exported and increase reference count of this exported TDP page table. + * + * On object destroy, the exported TDP page table is unmarked as exported with + * its reference count decreased. + * + * During the life cycle of KVM TDP FD object, ref count of KVM VM is hold. + * + * Components outside of KVM can get meta data (e.g. page table type, levels, + * root HPA,...), request page fault on the exported TDP page table and register + * themselves as importers to receive notification through kvm_exported_tdp_ops + * @ops. + * + * @file: struct file object associated with the KVM TDP FD object. + * @ops: kvm_exported_tdp_ops associated with the exported TDP page table. + * @priv: internal data structures used by KVM to manage TDP page table + * exported by KVM. + * + */ +struct kvm_tdp_fd { + /* Public */ + struct file *file; + const struct kvm_exported_tdp_ops *ops; + + /* private to KVM */ + struct kvm_exported_tdp *priv; +}; + +/** + * kvm_tdp_fd_get - Public interface to get KVM TDP FD object. + * + * @fd: fd of the KVM TDP FD object. + * @return: KVM TDP FD object if @fd corresponds to a valid KVM TDP FD file. + * -EBADF if @fd does not correspond a struct file. + * -EINVAL if @fd does not correspond to a KVM TDP FD file. + * + * Callers of this interface will get a KVM TDP FD object with ref count + * increased. + */ +struct kvm_tdp_fd *kvm_tdp_fd_get(int fd); + +/** + * kvm_tdp_fd_put - Public interface to put ref count of a KVM TDP FD object. + * + * @tdp: KVM TDP FD object. + * + * Put reference count of the KVM TDP FD object. + * After the last reference count of the TDP FD object goes away, + * kvm_tdp_fd_release() will be called to decrease KVM VM ref count and destroy + * the KVM TDP FD object. + */ +void kvm_tdp_fd_put(struct kvm_tdp_fd *tdp); + +struct kvm_tdp_fault_type { + u32 read:1; + u32 write:1; + u32 exec:1; +}; + +/** + * struct kvm_exported_tdp_ops - operations possible on KVM TDP FD object. + * @register_importer: This is called from components outside of KVM to register + * importer callback ops and the importer data. + * This callback is a must. + * Returns: 0 on success, negative error code on failure. + * -EBUSY if the importer ops is already registered. + * @unregister_importer:This is called from components outside of KVM if it does + * not want to receive importer callbacks any more. + * This callback is a must. + * @fault: This is called from components outside of KVM to trigger + * page fault on a GPA and to map physical page into the + * TDP page tables exported by KVM. + * This callback is optional. + * If this callback is absent, components outside KVM will + * not be able to trigger page fault and map physical pages + * into the TDP page tables exported by KVM. + * @get_metadata: This is called from components outside of KVM to retrieve + * meta data of the TDP page tables exported by KVM, e.g. + * page table type,root HPA, levels, reserved zero bits... + * Returns: pointer to a vendor meta data on success. + * Error PTR on error. + * This callback is a must. + */ +struct kvm_exported_tdp_ops { + int (*register_importer)(struct kvm_tdp_fd *tdp_fd, + struct kvm_tdp_importer_ops *ops, + void *importer_data); + + void (*unregister_importer)(struct kvm_tdp_fd *tdp_fd, + struct kvm_tdp_importer_ops *ops); + + int (*fault)(struct kvm_tdp_fd *tdp_fd, struct mm_struct *mm, + unsigned long gfn, struct kvm_tdp_fault_type type); + + void *(*get_metadata)(struct kvm_tdp_fd *tdp_fd); +}; + +/** + * struct kvm_tdp_importer_ops - importer callbacks + * + * Components outside of KVM can be registered as importers of KVM's exported + * TDP page tables via register_importer op in kvm_exported_tdp_ops of a KVM TDP + * FD object. + * + * Each importer must define its own importer callbacks and KVM will notify + * importers of changes of the exported TDP page tables. + */ +struct kvm_tdp_importer_ops { + /** + * This is called by KVM to notify the importer that a range of KVM + * TDP has been invalidated. + * When @start is 0 and @size is -1, a whole of KVM TDP is invalidated. + * + * @data: the importer private data. + * @start: start GPA of the invalidated range. + * @size: length of in the invalidated range. + */ + void (*invalidate)(void *data, unsigned long start, unsigned long size); +}; +#endif /* __KVM_TDP_FD_H */