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 and refine
software sram initializaion flow.

Tracked-On: #5649
Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
Reviewed-by: Fei Li <fei1.li@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Yonghua Huang 2021-03-10 11:55:18 +08:00 committed by wenlingz
parent ea44bb6c4d
commit ae43b2a847
5 changed files with 43 additions and 7 deletions

View File

@ -264,15 +264,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);
@ -283,6 +279,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

View File

@ -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;

View File

@ -106,8 +106,9 @@ 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)
{
bool ret = true;
int32_t rtcm_ret_code;
struct rtcm_header *header;
rtcm_abi_func rtcm_command_func = NULL;
@ -160,16 +161,19 @@ void init_software_sram(bool is_bsp)
pr_info("BSP Software SRAM has been initialized, base_hpa:0x%lx, top_hpa:0x%lx.\n",
software_sram_bottom_hpa, software_sram_top_hpa);
}
ret = disable_host_monitor_wait();
}
}
return ret;
}
#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

View File

@ -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);

View File

@ -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 */