diff options
Diffstat (limited to 'src/cpu/intel/common')
-rw-r--r-- | src/cpu/intel/common/Kconfig | 23 | ||||
-rw-r--r-- | src/cpu/intel/common/Makefile.inc | 1 | ||||
-rw-r--r-- | src/cpu/intel/common/common.h | 20 | ||||
-rw-r--r-- | src/cpu/intel/common/common_init.c | 71 |
4 files changed, 115 insertions, 0 deletions
diff --git a/src/cpu/intel/common/Kconfig b/src/cpu/intel/common/Kconfig new file mode 100644 index 0000000000..739333e4aa --- /dev/null +++ b/src/cpu/intel/common/Kconfig @@ -0,0 +1,23 @@ +config CPU_INTEL_COMMON + bool + +if CPU_INTEL_COMMON + +config ENABLE_VMX + bool "Enable VMX for virtualization" + default y + +config SET_VMX_LOCK_BIT + bool "Set lock bit after configuring VMX" + depends on ENABLE_VMX + default y + help + Although the Intel manual says you must set the lock bit in addition + to the VMX bit in order for VMX to work, this isn't strictly true, so + we have the option to leave it unlocked and allow the OS (e.g. Linux) + to manage things itself. This is beneficial for testing purposes as + there is no need to reflash the firmware just to toggle the lock bit. + However, leaving the lock bit unset will break Windows' detection of + VMX support and built-in virtualization features like Hyper-V. + +endif diff --git a/src/cpu/intel/common/Makefile.inc b/src/cpu/intel/common/Makefile.inc new file mode 100644 index 0000000000..1e94ec92e4 --- /dev/null +++ b/src/cpu/intel/common/Makefile.inc @@ -0,0 +1 @@ +ramstage-y += common_init.c diff --git a/src/cpu/intel/common/common.h b/src/cpu/intel/common/common.h new file mode 100644 index 0000000000..0d0b954886 --- /dev/null +++ b/src/cpu/intel/common/common.h @@ -0,0 +1,20 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CPU_INTEL_COMMON_H +#define _CPU_INTEL_COMMON_H + +void set_vmx(void); + +#endif diff --git a/src/cpu/intel/common/common_init.c b/src/cpu/intel/common/common_init.c new file mode 100644 index 0000000000..da7b82651f --- /dev/null +++ b/src/cpu/intel/common/common_init.c @@ -0,0 +1,71 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <console/console.h> +#include <cpu/x86/msr.h> +#include "common.h" + +#define IA32_FEATURE_CONTROL 0x3a +#define CPUID_VMX (1 << 5) +#define CPUID_SMX (1 << 6) + +void set_vmx(void) +{ + struct cpuid_result regs; + msr_t msr; + int enable = IS_ENABLED(CONFIG_ENABLE_VMX); + int lock = IS_ENABLED(CONFIG_SET_VMX_LOCK_BIT); + + regs = cpuid(1); + /* Check that the VMX is supported before reading or writing the MSR. */ + if (!((regs.ecx & CPUID_VMX) || (regs.ecx & CPUID_SMX))) { + printk(BIOS_DEBUG, "CPU doesn't support VMX; exiting\n"); + return; + } + + msr = rdmsr(IA32_FEATURE_CONTROL); + + if (msr.lo & (1 << 0)) { + printk(BIOS_ERR, "VMX is locked, so %s will do nothing\n", __func__); + /* VMX locked. If we set it again we get an illegal + * instruction + */ + return; + } + + /* The IA32_FEATURE_CONTROL MSR may initialize with random values. + * It must be cleared regardless of VMX config setting. + */ + msr.hi = msr.lo = 0; + + if (enable) { + msr.lo |= (1 << 2); + if (regs.ecx & CPUID_SMX) + msr.lo |= (1 << 1); + } + + wrmsr(IA32_FEATURE_CONTROL, msr); + + if (lock) { + /* Set lock bit */ + msr.lo |= (1 << 0); + wrmsr(IA32_FEATURE_CONTROL, msr); + } + + printk(BIOS_DEBUG, "VMX status: %s, %s\n", enable ? "enabled" : "disabled", + lock ? "locked" : "unlocked"); +} |