From 112f02851ced711decc9596cd675531f508fd7fd Mon Sep 17 00:00:00 2001 From: Shuo A Liu Date: Wed, 22 Jul 2020 10:49:19 +0800 Subject: [PATCH] hv: Disable XSAVE-managed CET state of guest VM To hide CET feature from guest VM completely, the MSR IA32_MSR_XSS also need to be intercepted because it comprises CET_U and CET_S feature bits of xsave/xstors operations. Mask these two bits in IA32_MSR_XSS writing. With IA32_MSR_XSS interception, member 'xss' of 'struct ext_context' can be removed because it is duplicated with the MSR store array 'vcpu->arch.guest_msrs[]'. Tracked-On: #5074 Signed-off-by: Shuo A Liu Reviewed-by: Jason Chen CJ --- hypervisor/arch/x86/guest/trusty.c | 4 ++-- hypervisor/arch/x86/guest/vcpu.c | 12 +++++------- hypervisor/arch/x86/guest/vmsr.c | 13 +++++++++++++ hypervisor/include/arch/x86/cpu.h | 1 - hypervisor/include/arch/x86/guest/vcpu.h | 6 +++--- hypervisor/include/arch/x86/msr.h | 6 ++++++ 6 files changed, 29 insertions(+), 13 deletions(-) diff --git a/hypervisor/arch/x86/guest/trusty.c b/hypervisor/arch/x86/guest/trusty.c index 8b4d3ee1c..348ca9df2 100644 --- a/hypervisor/arch/x86/guest/trusty.c +++ b/hypervisor/arch/x86/guest/trusty.c @@ -194,7 +194,7 @@ static void save_world_ctx(struct acrn_vcpu *vcpu, struct ext_context *ext_ctx) ext_ctx->ia32_kernel_gs_base = msr_read(MSR_IA32_KERNEL_GS_BASE); /* XSAVE area */ - save_xsave_area(ext_ctx); + save_xsave_area(vcpu, ext_ctx); /* For MSRs need isolation between worlds */ for (i = 0U; i < NUM_WORLD_MSRS; i++) { @@ -246,7 +246,7 @@ static void load_world_ctx(struct acrn_vcpu *vcpu, const struct ext_context *ext msr_write(MSR_IA32_KERNEL_GS_BASE, ext_ctx->ia32_kernel_gs_base); /* XSAVE area */ - rstore_xsave_area(ext_ctx); + rstore_xsave_area(vcpu, ext_ctx); /* For MSRs need isolation between worlds */ for (i = 0U; i < NUM_WORLD_MSRS; i++) { diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index f129342cc..efc74c649 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -266,7 +266,6 @@ static void init_xsave(struct acrn_vcpu *vcpu) struct xsave_area *area = &ectx->xs_area; ectx->xcr0 = XSAVE_FPU; - ectx->xss = 0U; (void)memset((void *)area, 0U, XSAVE_STATE_AREA_SIZE); /* xsaves only support compacted format, so set it in xcomp_bv[63], @@ -750,18 +749,17 @@ void zombie_vcpu(struct acrn_vcpu *vcpu, enum vcpu_state new_state) } } -void save_xsave_area(struct ext_context *ectx) +void save_xsave_area(__unused struct acrn_vcpu *vcpu, struct ext_context *ectx) { ectx->xcr0 = read_xcr(0); - ectx->xss = msr_read(MSR_IA32_XSS); write_xcr(0, ectx->xcr0 | XSAVE_SSE); xsaves(&ectx->xs_area, UINT64_MAX); } -void rstore_xsave_area(const struct ext_context *ectx) +void rstore_xsave_area(const struct acrn_vcpu *vcpu, const struct ext_context *ectx) { write_xcr(0, ectx->xcr0 | XSAVE_SSE); - msr_write(MSR_IA32_XSS, ectx->xss); + msr_write(MSR_IA32_XSS, vcpu_get_guest_msr(vcpu, MSR_IA32_XSS)); xrstors(&ectx->xs_area, UINT64_MAX); write_xcr(0, ectx->xcr0); } @@ -782,7 +780,7 @@ static void context_switch_out(struct thread_object *prev) ectx->ia32_fmask = msr_read(MSR_IA32_FMASK); ectx->ia32_kernel_gs_base = msr_read(MSR_IA32_KERNEL_GS_BASE); - save_xsave_area(ectx); + save_xsave_area(vcpu, ectx); } static void context_switch_in(struct thread_object *next) @@ -797,7 +795,7 @@ static void context_switch_in(struct thread_object *next) msr_write(MSR_IA32_FMASK, ectx->ia32_fmask); msr_write(MSR_IA32_KERNEL_GS_BASE, ectx->ia32_kernel_gs_base); - rstore_xsave_area(ectx); + rstore_xsave_area(vcpu, ectx); } diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index bb79b0fe7..6ba5153ae 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -59,6 +59,8 @@ static const uint32_t emulated_guest_msrs[NUM_GUEST_MSRS] = { /* Read only */ MSR_IA32_SGX_SVN_STATUS, + MSR_IA32_XSS, + MSR_TEST_CTL, }; @@ -359,6 +361,7 @@ void init_msr_emulation(struct acrn_vcpu *vcpu) /* don't need to intercept rdmsr for these MSRs */ enable_msr_interception(msr_bitmap, MSR_IA32_TIME_STAMP_COUNTER, INTERCEPT_WRITE); + enable_msr_interception(msr_bitmap, MSR_IA32_XSS, INTERCEPT_WRITE); /* Setup MSR bitmap - Intel SDM Vol3 24.6.9 */ value64 = hva2hpa(vcpu->arch.msr_bitmap); @@ -829,6 +832,16 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu) set_guest_ia32_misc_enalbe(vcpu, v); break; } + case MSR_IA32_XSS: + { + if ((v & ~(MSR_IA32_XSS_PT | MSR_IA32_XSS_HDC)) != 0UL) { + err = -EACCES; + } else { + vcpu_set_guest_msr(vcpu, MSR_IA32_XSS, v); + msr_write(msr, v); + } + break; + } case MSR_TEST_CTL: { /* If VM has MSR_TEST_CTL, ignore write operation diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index fbe7eed35..5d0f24af2 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -404,7 +404,6 @@ struct ext_context { struct xsave_area xs_area; uint64_t xcr0; - uint64_t xss; }; struct cpu_context { diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index 757bb3ff7..a73be7b87 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -164,7 +164,7 @@ enum reset_mode; #define SECURE_WORLD 1 #define NUM_WORLD_MSRS 2U -#define NUM_COMMON_MSRS 16U +#define NUM_COMMON_MSRS 17U #define NUM_GUEST_MSRS (NUM_WORLD_MSRS + NUM_COMMON_MSRS) #define EOI_EXIT_BITMAP_SIZE 256U @@ -578,8 +578,8 @@ static inline bool is_pae(struct acrn_vcpu *vcpu) struct acrn_vcpu *get_running_vcpu(uint16_t pcpu_id); struct acrn_vcpu *get_ever_run_vcpu(uint16_t pcpu_id); -void save_xsave_area(struct ext_context *ectx); -void rstore_xsave_area(const struct ext_context *ectx); +void save_xsave_area(struct acrn_vcpu *vcpu, struct ext_context *ectx); +void rstore_xsave_area(const struct acrn_vcpu *vcpu, const struct ext_context *ectx); /** * @brief create a vcpu for the target vm diff --git a/hypervisor/include/arch/x86/msr.h b/hypervisor/include/arch/x86/msr.h index f40e27b02..7255359fa 100644 --- a/hypervisor/include/arch/x86/msr.h +++ b/hypervisor/include/arch/x86/msr.h @@ -575,6 +575,12 @@ #define MSR_IA32_MISC_ENABLE_xTPR (1UL << 23U) #define MSR_IA32_MISC_ENABLE_XD_DISABLE (1UL << 34U) +/* MSR_IA32_XSS bits */ +#define MSR_IA32_XSS_PT (1UL << 8U) +#define MSR_IA32_XSS_CET_U (1UL << 11U) +#define MSR_IA32_XSS_CET_S (1UL << 12U) +#define MSR_IA32_XSS_HDC (1UL << 13U) + /* Miscellaneous data */ #define MSR_IA32_MISC_UNRESTRICTED_GUEST (1U<<5U)