From 92bbd3ff484c660b402375a7061a2942ab412ab7 Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Mon, 8 Mar 2021 09:13:35 +0800 Subject: [PATCH] hv: disable host MONITOR-WAIT support when SW SRAM is enabled Per-core software SRAM L2 cache may be flushed by 'mwait' extension instruction, which guest VM may execute to enter core deep sleep. Such kind of flushing is not expected when software SRAM is enabled for RTVM. Hypervisor disables MONITOR-WAIT support on both hypervisor and VMs sides to protect above software SRAM from being flushed. This patch disable hypervisor(host) MONITOR-WAIT support. Tracked-On: #5649 Signed-off-by: Yonghua Huang Reviewed-by: Fei Li Acked-by: Eddie Dong --- hypervisor/arch/x86/cpu.c | 8 +++---- hypervisor/arch/x86/cpu_caps.c | 31 ++++++++++++++++++++++++++ hypervisor/arch/x86/rtcm.c | 13 +++++++++-- hypervisor/include/arch/x86/cpu_caps.h | 1 + hypervisor/include/arch/x86/rtcm.h | 2 +- 5 files changed, 48 insertions(+), 7 deletions(-) diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 9949fa953..279173542 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -265,15 +265,11 @@ void init_pcpu_post(uint16_t pcpu_id) } ASSERT(get_pcpu_id() == BSP_CPU_ID, ""); - - init_software_sram(true); } else { pr_dbg("Core %hu is up", pcpu_id); pr_warn("Skipping VM configuration check which should be done before building HV binary."); - init_software_sram(false); - /* Initialize secondary processor interrupts. */ init_interrupt(pcpu_id); @@ -284,6 +280,10 @@ void init_pcpu_post(uint16_t pcpu_id) wait_sync_change(&pcpu_sync, 0UL); } + if (!init_software_sram(pcpu_id == BSP_CPU_ID)) { + panic("failed to initialize software SRAM!"); + } + init_sched(pcpu_id); #ifdef CONFIG_RDT_ENABLED diff --git a/hypervisor/arch/x86/cpu_caps.c b/hypervisor/arch/x86/cpu_caps.c index 8853150dd..9897dc156 100644 --- a/hypervisor/arch/x86/cpu_caps.c +++ b/hypervisor/arch/x86/cpu_caps.c @@ -74,6 +74,37 @@ bool has_monitor_cap(void) return ret; } +bool disable_host_monitor_wait(void) +{ + bool ret = true; + uint32_t eax = 0U, ebx = 0U, ecx = 0U, edx = 0U; + + cpuid_subleaf(0x1U, 0x0U, &eax, &ebx, &ecx, &edx); + if ((ecx & CPUID_ECX_MONITOR) != 0U) { + /* According to SDM Vol4 2.1 Table 2-2, + * update on 'MSR_IA32_MISC_ENABLE_MONITOR_ENA' bit + * is not allowed if the SSE3 feature flag is set to 0. + */ + if ((ecx & CPUID_ECX_SSE3) != 0U) { + msr_write(MSR_IA32_MISC_ENABLE, (msr_read(MSR_IA32_MISC_ENABLE) & + ~MSR_IA32_MISC_ENABLE_MONITOR_ENA)); + + /* Update cpuid_leaves of boot_cpu_data to + * refresh 'has_monitor_cap' state. + */ + if (has_monitor_cap()) { + cpuid_subleaf(CPUID_FEATURES, 0x0U, &eax, &ebx, + &boot_cpu_data.cpuid_leaves[FEAT_1_ECX], + &boot_cpu_data.cpuid_leaves[FEAT_1_EDX]); + } + + } else { + ret = false; + } + } + return ret; +} + static inline bool is_fast_string_erms_supported_and_enabled(void) { bool ret = false; diff --git a/hypervisor/arch/x86/rtcm.c b/hypervisor/arch/x86/rtcm.c index 02b0f5d5c..96f6ff43c 100644 --- a/hypervisor/arch/x86/rtcm.c +++ b/hypervisor/arch/x86/rtcm.c @@ -106,7 +106,7 @@ static void parse_rtct(void) * Synchronization of AP and BSP is ensured, both inside and outside RTCM. * BSP shall be the last to finish the call. */ -void init_software_sram(bool is_bsp) +bool init_software_sram(bool is_bsp) { int32_t rtcm_ret_code; struct rtcm_header *header; @@ -162,14 +162,23 @@ void init_software_sram(bool is_bsp) } } } + + if (acpi_rtct_tbl == NULL) { + is_sw_sram_initialized = true; + } else { + is_sw_sram_initialized = disable_host_monitor_wait(); + } + + return is_sw_sram_initialized; } #else void set_rtct_tbl(__unused void *rtct_tbl_addr) { } -void init_software_sram(__unused bool is_bsp) +bool init_software_sram(__unused bool is_bsp) { + return true; } #endif diff --git a/hypervisor/include/arch/x86/cpu_caps.h b/hypervisor/include/arch/x86/cpu_caps.h index ba7a9b6c9..5559eef51 100644 --- a/hypervisor/include/arch/x86/cpu_caps.h +++ b/hypervisor/include/arch/x86/cpu_caps.h @@ -46,6 +46,7 @@ struct cpuinfo_x86 { }; bool has_monitor_cap(void); +bool disable_host_monitor_wait(void); bool is_apl_platform(void); bool is_apicv_advanced_feature_supported(void); bool pcpu_has_cap(uint32_t bit); diff --git a/hypervisor/include/arch/x86/rtcm.h b/hypervisor/include/arch/x86/rtcm.h index 239f9be0d..ecca1aea1 100644 --- a/hypervisor/include/arch/x86/rtcm.h +++ b/hypervisor/include/arch/x86/rtcm.h @@ -26,7 +26,7 @@ struct rtcm_header { uint64_t command_offset; } __packed; -void init_software_sram(bool is_bsp); +bool init_software_sram(bool is_bsp); void set_rtct_tbl(void *rtct_tbl_addr); bool is_software_sram_enabled(void); #endif /* RTCM_H */