From 34a6336525b6c9d29cdb108eb7b471536ea309b3 Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Wed, 12 Sep 2018 00:48:00 +0800 Subject: [PATCH] HV: enable L1 cache flush when VM entry - flush L1 cache before VM entry only on platform affected by L1TF - flush operation is configurable by below MACRO: --CONFIG_L1D_FLUSH_VMENTRY_ENABLED Tracked-On: #1672 Signed-off-by: Yonghua Huang Reviewed-by: Kevin Tian --- hypervisor/arch/x86/Kconfig | 4 ++++ hypervisor/arch/x86/cpu.c | 15 +++++++++++++++ hypervisor/arch/x86/guest/vcpu.c | 7 +++++++ hypervisor/include/arch/x86/cpu.h | 1 + 4 files changed, 27 insertions(+) diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index c9d74ca85..faed21a6c 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -300,3 +300,7 @@ config ENFORCE_VALIDATED_ACPI_INFO tools to generate such data is required. Otherwise a warning will be printed when validated ACPI info is unavailable, but a binary can still be built with the ACPI info template. + +config L1D_FLUSH_VMENTRY_ENABLED + bool "Enable L1 cache flush before VM entry" + default n diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index b000e9bd5..1a50d15e9 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -911,3 +911,18 @@ static void cpu_xsave_init(void) } } } + +void cpu_l1d_flush(void) +{ + /* + * 'skip_l1dfl_vmentry' will be true on platform that + * is not affected by L1TF. + * + */ + if (!skip_l1dfl_vmentry) { + if (cpu_has_cap(X86_FEATURE_L1D_FLUSH)) { + msr_write(MSR_IA32_FLUSH_CMD, IA32_L1D_FLUSH); + } + } + +} diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index c620e9a76..360f68f63 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -426,6 +426,10 @@ int run_vcpu(struct vcpu *vcpu) if (ibrs_type == IBRS_RAW) msr_write(MSR_IA32_PRED_CMD, PRED_SET_IBPB); +#ifdef CONFIG_L1D_FLUSH_VMENTRY_ENABLED + cpu_l1d_flush(); +#endif + /* Launch the VM */ status = vmx_vmrun(ctx, VM_LAUNCH, ibrs_type); @@ -444,6 +448,9 @@ int run_vcpu(struct vcpu *vcpu) rip = vcpu_get_rip(vcpu); exec_vmwrite(VMX_GUEST_RIP, ((rip+(uint64_t)instlen) & 0xFFFFFFFFFFFFFFFFUL)); +#ifdef CONFIG_L1D_FLUSH_VMENTRY_ENABLED + cpu_l1d_flush(); +#endif /* Resume the VM */ status = vmx_vmrun(ctx, VM_RESUME, ibrs_type); diff --git a/hypervisor/include/arch/x86/cpu.h b/hypervisor/include/arch/x86/cpu.h index ca2fb6a3a..769b555ab 100644 --- a/hypervisor/include/arch/x86/cpu.h +++ b/hypervisor/include/arch/x86/cpu.h @@ -324,6 +324,7 @@ void cpu_secondary_init(void); void start_cpus(void); void stop_cpus(void); void wait_sync_change(uint64_t *sync, uint64_t wake_sync); +void cpu_l1d_flush(void); /* Read control register */ #define CPU_CR_READ(cr, result_ptr) \