coreboot: Add a VMX feature lock check and reset if VMX is disabled
Starting with M80, OS requires VMX to be enabled. However, since the
previous version of the OS had the feature disabled and locked, the
system needs to go through a cold reset to allow VMX to be enabled.
BUG=b:150215069, crbug:1072877
TEST=Update/reset between M79 and M84 versions; confirm that the
issue is resolved and /dev/kvm comes up.
Change-Id: Ifa2f370b1212b13a2eeb8d95c738068d5109d423
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/coreboot/+/2319413
Tested-by: Dossym Nurmukhanov <dossym@chromium.org>
Auto-Submit: Dossym Nurmukhanov <dossym@chromium.org>
Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
diff --git a/src/soc/intel/broadwell/cpu.c b/src/soc/intel/broadwell/cpu.c
index 4c47a3a..fb9037b 100644
--- a/src/soc/intel/broadwell/cpu.c
+++ b/src/soc/intel/broadwell/cpu.c
@@ -44,7 +44,12 @@
#include <soc/rcba.h>
#include <soc/smm.h>
#include <soc/systemagent.h>
+#include <soc/reset.h>
#include <soc/intel/broadwell/chip.h>
+#if CONFIG_EC_GOOGLE_CHROMEEC
+#include <ec/google/chromeec/ec.h>
+#include <ec/google/chromeec/ec_commands.h>
+#endif
/* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */
static const u8 power_limit_time_sec_to_msr[] = {
@@ -683,6 +688,30 @@
.id_table = cpu_table,
};
+static void validate_vmx_lock_status(void)
+{
+#if CONFIG_EC_GOOGLE_CHROMEEC
+ msr_t msr;
+
+ msr = rdmsr(IA32_FEATURE_CONTROL);
+ printk(BIOS_DEBUG, "IA32 Feature Control hi = %u, lo = %u.\n",
+ msr.hi, msr.lo);
+
+ if ((msr.lo & FEATURE_CONTROL_LOCK_BIT) &&
+ !(msr.lo & (FEATURE_ENABLE_VMX_INSIDE_SMX |
+ FEATURE_ENABLE_VMX_OUTSIDE_SMX))) {
+ printk(BIOS_INFO, "Feature control MSR locked. Rebooting.\n");
+ if (!google_chromeec_gsv_set(EC_CMD_GSV_PAUSE_IN_S5, 1))
+ cold_reset_system();
+ else
+ google_chromeec_reboot();
+ }
+
+ google_chromeec_gsv_set(EC_CMD_GSV_PAUSE_IN_S5, 0);
+#endif
+
+}
+
void broadwell_init_cpus(device_t dev)
{
struct bus *cpu_bus = dev->link_list;
@@ -692,6 +721,8 @@
struct mp_params mp_params;
void *smm_save_area;
+ validate_vmx_lock_status();
+
msr = rdmsr(CORE_THREAD_COUNT_MSR);
num_threads = (msr.lo >> 0) & 0xffff;
num_cores = (msr.lo >> 16) & 0xffff;
diff --git a/src/soc/intel/broadwell/include/soc/msr.h b/src/soc/intel/broadwell/include/soc/msr.h
index 707041a..d723757 100644
--- a/src/soc/intel/broadwell/include/soc/msr.h
+++ b/src/soc/intel/broadwell/include/soc/msr.h
@@ -23,6 +23,9 @@
#define MSR_PIC_MSG_CONTROL 0x2e
#define CORE_THREAD_COUNT_MSR 0x35
#define IA32_FEATURE_CONTROL 0x3a
+#define FEATURE_CONTROL_LOCK_BIT (1 << 0)
+#define FEATURE_ENABLE_VMX_INSIDE_SMX (1 << 1)
+#define FEATURE_ENABLE_VMX_OUTSIDE_SMX (1 << 2)
#define CPUID_VMX (1 << 5)
#define CPUID_SMX (1 << 6)
#define MSR_PLATFORM_INFO 0xce