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-next>] [day] [month] [year] [list]
Message-ID: <20220203181432.34911-1-faresx@amazon.de>
Date:   Thu, 3 Feb 2022 18:14:32 +0000
From:   Fares Mehanna <faresx@...zon.de>
To:     Paolo Bonzini <pbonzini@...hat.com>,
        Sean Christopherson <seanjc@...gle.com>,
        Vitaly Kuznetsov <vkuznets@...hat.com>,
        Wanpeng Li <wanpengli@...cent.com>,
        Jim Mattson <jmattson@...gle.com>,
        Joerg Roedel <joro@...tes.org>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        Dave Hansen <dave.hansen@...ux.intel.com>,
        "H. Peter Anvin" <hpa@...or.com>,
        Jarkko Sakkinen <jarkko@...nel.org>
CC:     <x86@...nel.org>, <kvm@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>, <linux-sgx@...r.kernel.org>,
        Fares Mehanna <faresx@...zon.de>
Subject: [PATCH] KVM: VMX: pass TME information to guests

Guests running on IceLake have TME-EN disabled in CPUID, and they can't read TME
related MSRs [IA32_TME_CAPABILITY, IA32_TME_ACTIVATE, IA32_TME_EXCLUDE_MASK,
IA32_TME_EXCLUDE_BASE].

So guests don't know if they are running with TME enabled or not.

In this patch, TME information is passed to the guest if the host has `TME-EN`
enabled in CPUID and TME MSRs are locked and the exclusion range is disabled.

This will guarantee that hardware supports TME, MSRs are locked, so host can't
change them and exclusion range is disabled, so TME rules apply on all host
memory.

In IA32_TME_CAPABILITY and IA32_TME_ACTIVATE we mask out the reserved bits and
MKTME related bits.

So in IA32_TME_CAPABILITY, we are passing:
Bit[0]:  Support for AES-XTS 128-bit encryption algorithm
Bit[2]:  Support for AES-XTS 256-bit encryption algorithm
Bit[31]: TME encryption bypass supported

And in IA32_TME_ACTIVATE, we are passing:
Bit[0]:   Lock RO
Bit[1]:   TME Enable RWL
Bit[2]:   Key select
Bit[3]:   Save TME key for Standby
Bit[4:7]: Encryption Algorithm
Bit[31]:  TME Encryption Bypass Enable

However IA32_TME_EXCLUDE_MASK and IA32_TME_EXCLUDE_BASE are read by the guest as
zero, since we will only pass TME information if the exclusion range is
disabled.

Those information are helpful for the guest to determine if TME is enabled by
the BIOS or not.

Signed-off-by: Fares Mehanna <faresx@...zon.de>
---
 arch/x86/include/asm/msr-index.h |  6 ++++++
 arch/x86/include/asm/processor.h | 14 ++++++++++++++
 arch/x86/kernel/cpu/intel.c      | 15 +--------------
 arch/x86/kvm/cpuid.c             | 19 ++++++++++++++++++-
 arch/x86/kvm/vmx/vmx.c           | 20 ++++++++++++++++++++
 5 files changed, 59 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 3faf0f97edb1..908aad1a7cad 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -438,6 +438,12 @@
 #define MSR_RELOAD_PMC0			0x000014c1
 #define MSR_RELOAD_FIXED_CTR0		0x00001309
 
+/* Memory encryption MSRs */
+#define MSR_IA32_TME_CAPABILITY		0x981
+#define MSR_IA32_TME_ACTIVATE		0x982
+#define MSR_IA32_TME_EXCLUDE_MASK	0x983
+#define MSR_IA32_TME_EXCLUDE_BASE	0x984
+
 /*
  * AMD64 MSRs. Not complete. See the architecture manual for a more
  * complete list.
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2c5f12ae7d04..28387ae7277b 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -863,4 +863,18 @@ bool arch_is_platform_page(u64 paddr);
 #define arch_is_platform_page arch_is_platform_page
 #endif
 
+/* Helpers to access TME_ACTIVATE MSR */
+#define TME_ACTIVATE_LOCKED(x)		((x) & 0x1)
+#define TME_ACTIVATE_ENABLED(x)		((x) & 0x2)
+
+#define TME_ACTIVATE_POLICY(x)		(((x) >> 4) & 0xf)        /* Bits 7:4 */
+#define TME_ACTIVATE_POLICY_AES_XTS_128	0
+
+#define TME_ACTIVATE_KEYID_BITS(x)	(((x) >> 32) & 0xf)     /* Bits 35:32 */
+
+#define TME_ACTIVATE_CRYPTO_ALGS(x)	(((x) >> 48) & 0xffff)    /* Bits 63:48 */
+#define TME_ACTIVATE_CRYPTO_AES_XTS_128	1
+
+#define TME_EXCLUSION_ENABLED(x)	((x) & 0x800) /* Bit 11 */
+
 #endif /* _ASM_X86_PROCESSOR_H */
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 8321c43554a1..46ad006089a3 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -14,6 +14,7 @@
 
 #include <asm/cpufeature.h>
 #include <asm/msr.h>
+#include <asm/processor.h>
 #include <asm/bugs.h>
 #include <asm/cpu.h>
 #include <asm/intel-family.h>
@@ -492,20 +493,6 @@ static void srat_detect_node(struct cpuinfo_x86 *c)
 #endif
 }
 
-#define MSR_IA32_TME_ACTIVATE		0x982
-
-/* Helpers to access TME_ACTIVATE MSR */
-#define TME_ACTIVATE_LOCKED(x)		(x & 0x1)
-#define TME_ACTIVATE_ENABLED(x)		(x & 0x2)
-
-#define TME_ACTIVATE_POLICY(x)		((x >> 4) & 0xf)	/* Bits 7:4 */
-#define TME_ACTIVATE_POLICY_AES_XTS_128	0
-
-#define TME_ACTIVATE_KEYID_BITS(x)	((x >> 32) & 0xf)	/* Bits 35:32 */
-
-#define TME_ACTIVATE_CRYPTO_ALGS(x)	((x >> 48) & 0xffff)	/* Bits 63:48 */
-#define TME_ACTIVATE_CRYPTO_AES_XTS_128	1
-
 /* Values for mktme_status (SW only construct) */
 #define MKTME_ENABLED			0
 #define MKTME_DISABLED			1
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 28be02adc669..c5a18527f099 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -84,6 +84,22 @@ static inline struct kvm_cpuid_entry2 *cpuid_entry2_find(
 	return NULL;
 }
 
+static bool kvm_tme_supported(void)
+{
+	u64 tme_activation, tme_exclusion;
+
+	if (!feature_bit(TME))
+		return false;
+
+	if (rdmsrl_safe(MSR_IA32_TME_EXCLUDE_MASK, &tme_exclusion))
+		return false;
+	if (rdmsrl_safe(MSR_IA32_TME_ACTIVATE, &tme_activation))
+		return false;
+
+	return TME_ACTIVATE_LOCKED(tme_activation) &&
+		!TME_EXCLUSION_ENABLED(tme_exclusion);
+}
+
 static int kvm_check_cpuid(struct kvm_vcpu *vcpu,
 			   struct kvm_cpuid_entry2 *entries,
 			   int nent)
@@ -508,6 +524,7 @@ static __always_inline void kvm_cpu_cap_mask(enum cpuid_leafs leaf, u32 mask)
 
 void kvm_set_cpu_caps(void)
 {
+	unsigned int f_tme = kvm_tme_supported() ? F(TME) : 0;
 #ifdef CONFIG_X86_64
 	unsigned int f_gbpages = F(GBPAGES);
 	unsigned int f_lm = F(LM);
@@ -565,7 +582,7 @@ void kvm_set_cpu_caps(void)
 		F(AVX512VBMI) | F(LA57) | F(PKU) | 0 /*OSPKE*/ | F(RDPID) |
 		F(AVX512_VPOPCNTDQ) | F(UMIP) | F(AVX512_VBMI2) | F(GFNI) |
 		F(VAES) | F(VPCLMULQDQ) | F(AVX512_VNNI) | F(AVX512_BITALG) |
-		F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/ |
+		f_tme | F(CLDEMOTE) | F(MOVDIRI) | F(MOVDIR64B) | 0 /*WAITPKG*/ |
 		F(SGX_LC) | F(BUS_LOCK_DETECT)
 	);
 	/* Set LA57 based on hardware capability. */
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index aca3ae2a02f3..f8cbf935cfe0 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1913,6 +1913,26 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
 	case MSR_IA32_DEBUGCTLMSR:
 		msr_info->data = vmcs_read64(GUEST_IA32_DEBUGCTL);
 		break;
+	case MSR_IA32_TME_CAPABILITY:
+		if (!guest_cpuid_has(vcpu, X86_FEATURE_TME))
+			return 1;
+		if (rdmsrl_safe(MSR_IA32_TME_CAPABILITY, &msr_info->data))
+			return 1;
+		msr_info->data &= 0x80000005; /* Bit 0, 2, 31 */
+		break;
+	case MSR_IA32_TME_ACTIVATE:
+		if (!guest_cpuid_has(vcpu, X86_FEATURE_TME))
+			return 1;
+		if (rdmsrl_safe(MSR_IA32_TME_ACTIVATE, &msr_info->data))
+			return 1;
+		msr_info->data &= 0x800000FF; /* Bits [0-7] and Bit 31 */
+		break;
+	case MSR_IA32_TME_EXCLUDE_MASK:
+	case MSR_IA32_TME_EXCLUDE_BASE:
+		if (!guest_cpuid_has(vcpu, X86_FEATURE_TME))
+			return 1;
+		msr_info->data = 0x0;
+		break;
 	default:
 	find_uret_msr:
 		msr = vmx_find_uret_msr(vmx, msr_info->index);
-- 
2.32.0




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879



Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ