From f32b59d73d9505073e8321eab1eafb68c6de6f5a Mon Sep 17 00:00:00 2001 From: Binbin Wu Date: Tue, 19 Mar 2019 10:55:52 +0800 Subject: [PATCH] hv: disable mpx capability for guest This patch hide Memory Protection Extention (MPX) capability from guest. - vCPUID change: Clear cpuid.07H.0.ebx[14] Clear cpuid.0DH.0.eax[4:3] - vMSR change: Add MSR_IA32_BNDCFGS to un-supported MSR array. - XCR0[4:3] is not allowed to set by guest. Tracked-On: #2821 Signed-off-by: Binbin Wu Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/vcpuid.c | 10 ++++++++++ hypervisor/arch/x86/guest/vmexit.c | 12 ++++++++++-- hypervisor/arch/x86/guest/vmsr.c | 5 ++++- hypervisor/include/arch/x86/cpu.h | 8 ++++++++ hypervisor/include/arch/x86/cpuid.h | 6 ++++++ 5 files changed, 38 insertions(+), 3 deletions(-) diff --git a/hypervisor/arch/x86/guest/vcpuid.c b/hypervisor/arch/x86/guest/vcpuid.c index 5a68f35fb..3b4b65a7c 100644 --- a/hypervisor/arch/x86/guest/vcpuid.c +++ b/hypervisor/arch/x86/guest/vcpuid.c @@ -122,6 +122,9 @@ static void init_vcpuid_entry(uint32_t leaf, uint32_t subleaf, entry->ebx &= ~CPUID_EBX_SGX; entry->ecx &= ~CPUID_ECX_SGX_LC; + /* mask MPX */ + entry->ebx &= ~CPUID_EBX_MPX; + /* mask Intel Processor Trace, since 14h is disabled */ entry->ebx &= ~CPUID_EBX_PROC_TRC; } else { @@ -414,6 +417,13 @@ void guest_cpuid(struct acrn_vcpu *vcpu, uint32_t *eax, uint32_t *ebx, uint32_t *edx = 0U; } else { cpuid_subleaf(leaf, subleaf, eax, ebx, ecx, edx); + if (subleaf == 0U) { + /* SDM Vol.1 17-2, On processors that do not support Intel MPX, + * CPUID.(EAX=0DH,ECX=0):EAX[3] and + * CPUID.(EAX=0DH,ECX=0):EAX[4] will both be 0 */ + *eax &= ~ CPUID_EAX_XCR0_BNDREGS; + *eax &= ~ CPUID_EAX_XCR0_BNDCSR; + } } break; diff --git a/hypervisor/arch/x86/guest/vmexit.c b/hypervisor/arch/x86/guest/vmexit.c index 4bbcb99c5..dfab91e5e 100644 --- a/hypervisor/arch/x86/guest/vmexit.c +++ b/hypervisor/arch/x86/guest/vmexit.c @@ -302,10 +302,18 @@ static int32_t xsetbv_vmexit_handler(struct acrn_vcpu *vcpu) * set to 10b as it is necessary to set both bits * to use AVX instructions. */ - if (((val64 >> 1U) & 0x3UL) == 0x2UL) { + if ((val64 & (XCR0_SSE | XCR0_AVX)) == XCR0_AVX) { vcpu_inject_gp(vcpu, 0U); } else { - write_xcr(0, val64); + /* + * SDM Vol.1 13-4, XCR0[4:3] are associated with MPX state, + * Guest should not set these two bits without MPX support. + */ + if ((val64 & (XCR0_BNDREGS | XCR0_BNDCSR)) != 0UL) { + vcpu_inject_gp(vcpu, 0U); + } else { + write_xcr(0, val64); + } } } } diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 7cc6861bf..5ba28ccbe 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -64,7 +64,7 @@ static const uint32_t mtrr_msrs[NUM_MTRR_MSRS] = { }; /* Following MSRs are intercepted, but it throws GPs for any guest accesses */ -#define NUM_UNSUPPORTED_MSRS 103U +#define NUM_UNSUPPORTED_MSRS 104U static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = { /* Variable MTRRs are not supported */ MSR_IA32_MTRR_PHYSBASE_0, @@ -120,6 +120,9 @@ static const uint32_t unsupported_msrs[NUM_UNSUPPORTED_MSRS] = { /* SGX disabled : CPUID.07H.EBX[2] */ MSR_IA32_SGX_SVN_STATUS, + /* MPX disabled: CPUID.07H.EBX[14] */ + MSR_IA32_BNDCFGS, + /* SGX disabled : CPUID.12H.EAX[0] */ MSR_SGXOWNEREPOCH0, MSR_SGXOWNEREPOCH1, diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index e977526b3..f0b4d84ce 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -83,6 +83,14 @@ #define CR4_SMAP (1UL<<21U) #define CR4_PKE (1UL<<22U) /* Protect-key-enable */ +/* XCR0_SSE */ +#define XCR0_SSE (1U<<1U) +/* XCR0_AVX */ +#define XCR0_AVX (1U<<2U) +/* XCR0_BNDREGS */ +#define XCR0_BNDREGS (1U<<3U) +/* XCR0_BNDCSR */ +#define XCR0_BNDCSR (1U<<4U) /* * Entries in the Interrupt Descriptor Table (IDT) diff --git a/hypervisor/include/arch/x86/cpuid.h b/hypervisor/include/arch/x86/cpuid.h index 0063feb59..697ef8ace 100644 --- a/hypervisor/include/arch/x86/cpuid.h +++ b/hypervisor/include/arch/x86/cpuid.h @@ -76,6 +76,8 @@ #define CPUID_EBX_TSC_ADJ (1U<<1U) /* CPUID.07H:EBX.SGX */ #define CPUID_EBX_SGX (1U<<2U) +/* CPUID.07H:EBX.MPX */ +#define CPUID_EBX_MPX (1U<<14U) /* CPUID.07H:ECX.SGX_LC*/ #define CPUID_ECX_SGX_LC (1U<<30U) /* CPUID.07H:EDX.IBRS_IBPB*/ @@ -94,6 +96,10 @@ #define CPUID_EBX_PROC_TRC (1U<<25U) /* CPUID.01H:ECX.PCID*/ #define CPUID_ECX_PCID (1U<<17U) +/* CPUID.0DH.EAX.XCR0_BNDREGS */ +#define CPUID_EAX_XCR0_BNDREGS (1U<<3U) +/* CPUID.0DH.EAX.XCR0_BNDCSR */ +#define CPUID_EAX_XCR0_BNDCSR (1U<<4U) /* CPUID source operands */ #define CPUID_VENDORSTRING 0U