lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20231202093510.15817-1-yan.y.zhao@intel.com>
Date:   Sat,  2 Dec 2023 17:35:10 +0800
From:   Yan Zhao <yan.y.zhao@...el.com>
To:     iommu@...ts.linux.dev, kvm@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     alex.williamson@...hat.com, jgg@...dia.com, pbonzini@...hat.com,
        seanjc@...gle.com, joro@...tes.org, will@...nel.org,
        robin.murphy@....com, kevin.tian@...el.com,
        baolu.lu@...ux.intel.com, dwmw2@...radead.org, yi.l.liu@...el.com,
        Yan Zhao <yan.y.zhao@...el.com>
Subject: [RFC PATCH 38/42] KVM: x86: "compose" and "get" interface for meta data of exported TDP

Added two fields .exported_tdp_meta_size and .exported_tdp_meta_compose in
kvm_x86_ops to allow vendor specific code to compose meta data of exported
TDP and provided an arch interface for external components to get the
composed meta data.

As the meta data is consumed in IOMMU's vendor driver to check if the
exported TDP is compatible to the IOMMU hardware before reusing them as
IOMMU's stage 2 page tables, it's better to compose them in KVM's vendor
spcific code too.

Signed-off-by: Yan Zhao <yan.y.zhao@...el.com>
---
 arch/x86/include/asm/kvm-x86-ops.h |  3 +++
 arch/x86/include/asm/kvm_host.h    |  7 +++++++
 arch/x86/kvm/x86.c                 | 23 ++++++++++++++++++++++-
 include/linux/kvm_host.h           |  6 ++++++
 virt/kvm/tdp_fd.c                  |  2 +-
 5 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index d751407b1056c..baf3efaa148c2 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -136,6 +136,9 @@ KVM_X86_OP(msr_filter_changed)
 KVM_X86_OP(complete_emulated_msr)
 KVM_X86_OP(vcpu_deliver_sipi_vector)
 KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons);
+#if IS_ENABLED(CONFIG_HAVE_KVM_EXPORTED_TDP)
+KVM_X86_OP_OPTIONAL(exported_tdp_meta_compose);
+#endif
 
 #undef KVM_X86_OP
 #undef KVM_X86_OP_OPTIONAL
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 860502720e3e7..412a1b2088f09 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -26,6 +26,7 @@
 #include <linux/irqbypass.h>
 #include <linux/hyperv.h>
 #include <linux/kfifo.h>
+#include <linux/kvm_tdp_fd.h>
 
 #include <asm/apic.h>
 #include <asm/pvclock-abi.h>
@@ -1493,6 +1494,7 @@ struct kvm_exported_tdp_mmu {
 };
 struct kvm_arch_exported_tdp {
 	struct kvm_exported_tdp_mmu mmu;
+	void *meta;
 };
 #endif
 
@@ -1784,6 +1786,11 @@ struct kvm_x86_ops {
 	 * Returns vCPU specific APICv inhibit reasons
 	 */
 	unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu);
+
+#ifdef CONFIG_HAVE_KVM_EXPORTED_TDP
+	unsigned long exported_tdp_meta_size;
+	void (*exported_tdp_meta_compose)(struct kvm_exported_tdp *tdp);
+#endif
 };
 
 struct kvm_x86_nested_ops {
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2886eac0590d8..468bcde414691 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -13432,18 +13432,39 @@ EXPORT_SYMBOL_GPL(kvm_arch_no_poll);
 #ifdef CONFIG_HAVE_KVM_EXPORTED_TDP
 int kvm_arch_exported_tdp_init(struct kvm *kvm, struct kvm_exported_tdp *tdp)
 {
+	void *meta;
 	int ret;
 
+	if (!kvm_x86_ops.exported_tdp_meta_size ||
+	    !kvm_x86_ops.exported_tdp_meta_compose)
+		return -EOPNOTSUPP;
+
+	meta = __vmalloc(kvm_x86_ops.exported_tdp_meta_size,
+			 GFP_KERNEL_ACCOUNT | __GFP_ZERO);
+	if (!meta)
+		return -ENOMEM;
+
+	tdp->arch.meta = meta;
+
 	ret = kvm_mmu_get_exported_tdp(kvm, tdp);
-	if (ret)
+	if (ret) {
+		kvfree(meta);
 		return ret;
+	}
 
+	static_call(kvm_x86_exported_tdp_meta_compose)(tdp);
 	return 0;
 }
 
 void kvm_arch_exported_tdp_destroy(struct kvm_exported_tdp *tdp)
 {
 	kvm_mmu_put_exported_tdp(tdp);
+	kvfree(tdp->arch.meta);
+}
+
+void *kvm_arch_exported_tdp_get_metadata(struct kvm_exported_tdp *tdp)
+{
+	return tdp->arch.meta;
 }
 
 int kvm_arch_fault_exported_tdp(struct kvm_exported_tdp *tdp, unsigned long gfn,
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index a8af95194767f..48324c846d90b 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -2348,6 +2348,7 @@ int kvm_arch_exported_tdp_init(struct kvm *kvm, struct kvm_exported_tdp *tdp);
 void kvm_arch_exported_tdp_destroy(struct kvm_exported_tdp *tdp);
 int kvm_arch_fault_exported_tdp(struct kvm_exported_tdp *tdp, unsigned long gfn,
 				struct kvm_tdp_fault_type type);
+void *kvm_arch_exported_tdp_get_metadata(struct kvm_exported_tdp *tdp);
 #else
 static inline int kvm_arch_exported_tdp_init(struct kvm *kvm,
 					     struct kvm_exported_tdp *tdp)
@@ -2364,6 +2365,11 @@ static inline int kvm_arch_fault_exported_tdp(struct kvm_exported_tdp *tdp,
 {
 	return -EOPNOTSUPP;
 }
+
+static inline void *kvm_arch_exported_tdp_get_metadata(struct kvm_exported_tdp *tdp)
+{
+	return NULL;
+}
 #endif /* __KVM_HAVE_ARCH_EXPORTED_TDP */
 
 void kvm_tdp_fd_flush_notify(struct kvm *kvm, unsigned long gfn, unsigned long npages);
diff --git a/virt/kvm/tdp_fd.c b/virt/kvm/tdp_fd.c
index 8c16af685a061..e4a2453a5547f 100644
--- a/virt/kvm/tdp_fd.c
+++ b/virt/kvm/tdp_fd.c
@@ -217,7 +217,7 @@ static void kvm_tdp_unregister_all_importers(struct kvm_exported_tdp *tdp)
 
 static void *kvm_tdp_get_metadata(struct kvm_tdp_fd *tdp_fd)
 {
-	return ERR_PTR(-EOPNOTSUPP);
+	return kvm_arch_exported_tdp_get_metadata(tdp_fd->priv);
 }
 
 static int kvm_tdp_fault(struct kvm_tdp_fd *tdp_fd, struct mm_struct *mm,
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ