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: <20240515005952.3410568-5-rick.p.edgecombe@intel.com>
Date: Tue, 14 May 2024 17:59:40 -0700
From: Rick Edgecombe <rick.p.edgecombe@...el.com>
To: pbonzini@...hat.com,
	seanjc@...gle.com,
	kvm@...r.kernel.org
Cc: linux-kernel@...r.kernel.org,
	isaku.yamahata@...il.com,
	erdemaktas@...gle.com,
	sagis@...gle.com,
	yan.y.zhao@...el.com,
	dmatlack@...gle.com,
	rick.p.edgecombe@...el.com
Subject: [PATCH 04/16] KVM: x86/mmu: Add address conversion functions for TDX shared bit of GPA

From: Isaku Yamahata <isaku.yamahata@...el.com>

Introduce a "gfn_shared_mask" field in the kvm_arch structure to record GPA
shared bit and provide address conversion helpers for TDX shared bit of
GPA.

TDX designates a specific GPA bit as the shared bit, which can be either
bit 51 or bit 47 based on configuration.

This GPA shared bit indicates whether the corresponding physical page is
shared (if shared bit set) or private (if shared bit cleared).

- GPAs with shared bit set will be mapped by VMM into conventional EPT,
  which is pointed by shared EPTP in TDVMCS, resides in host VMM memory
  and is managed by VMM.
- GPAs with shared bit cleared will be mapped by VMM firstly into a
  mirrored EPT, which resides in host VMM memory. Changes of the mirrored
  EPT are then propagated into a private EPT, which resides outside of host
  VMM memory and is managed by TDX module.

Add the "gfn_shared_mask" field to the kvm_arch structure for each VM with
a default value of 0. It will be set to the position of the GPA shared bit
in GFN through TD specific initialization code.

Provide helpers to utilize the gfn_shared_mask to determine whether a GPA
is shared or private, retrieve the GPA shared bit value, and insert/strip
shared bit to/from a GPA.

Signed-off-by: Isaku Yamahata <isaku.yamahata@...el.com>
Co-developed-by: Rick Edgecombe <rick.p.edgecombe@...el.com>
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@...el.com>
Reviewed-by: Binbin Wu <binbin.wu@...ux.intel.com>
---
TDX MMU Part 1:
 - Update commit log (Yan)
 - Fix documentation on kvm_is_private_gpa() (Binbin)

v19:
- Add comment on default vm case.
- Added behavior table in the commit message
- drop CONFIG_KVM_MMU_PRIVATE

v18:
- Added Reviewed-by Binbin
---
 arch/x86/include/asm/kvm_host.h |  2 ++
 arch/x86/kvm/mmu.h              | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index aabf1648a56a..d2f924f1d579 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1519,6 +1519,8 @@ struct kvm_arch {
 	 */
 #define SPLIT_DESC_CACHE_MIN_NR_OBJECTS (SPTE_ENT_PER_PAGE + 1)
 	struct kvm_mmu_memory_cache split_desc_cache;
+
+	gfn_t gfn_shared_mask;
 };
 
 struct kvm_vm_stat {
diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h
index 3c7a88400cbb..dac13a2d944f 100644
--- a/arch/x86/kvm/mmu.h
+++ b/arch/x86/kvm/mmu.h
@@ -321,4 +321,37 @@ static inline gpa_t kvm_translate_gpa(struct kvm_vcpu *vcpu,
 		return gpa;
 	return translate_nested_gpa(vcpu, gpa, access, exception);
 }
+
+/*
+ *			default or SEV-SNP	TDX: where S = (47 or 51) - 12
+ * gfn_shared_mask	0			S bit
+ * is_private_gpa()	always false		true if GPA has S bit clear
+ * gfn_to_shared()	nop			set S bit
+ * gfn_to_private()	nop			clear S bit
+ *
+ * fault.is_private means that host page should be gotten from guest_memfd
+ * is_private_gpa() means that KVM MMU should invoke private MMU hooks.
+ */
+static inline gfn_t kvm_gfn_shared_mask(const struct kvm *kvm)
+{
+	return kvm->arch.gfn_shared_mask;
+}
+
+static inline gfn_t kvm_gfn_to_shared(const struct kvm *kvm, gfn_t gfn)
+{
+	return gfn | kvm_gfn_shared_mask(kvm);
+}
+
+static inline gfn_t kvm_gfn_to_private(const struct kvm *kvm, gfn_t gfn)
+{
+	return gfn & ~kvm_gfn_shared_mask(kvm);
+}
+
+static inline bool kvm_is_private_gpa(const struct kvm *kvm, gpa_t gpa)
+{
+	gfn_t mask = kvm_gfn_shared_mask(kvm);
+
+	return mask && !(gpa_to_gfn(gpa) & mask);
+}
+
 #endif
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ