diff options
author | Matt DeVillier <matt.devillier@gmail.com> | 2016-12-14 16:12:43 -0600 |
---|---|---|
committer | Nico Huber <nico.h@gmx.de> | 2016-12-27 02:30:08 +0100 |
commit | ed6fe2f64b37d0c6161b23b20980f91e0be7a1ea (patch) | |
tree | 99aa4d662a9210e157672d26b801c0a1fc78ccf4 /src/cpu/intel/common | |
parent | 2a5897526463dfe00feb06d99f850c2874d1d257 (diff) |
cpu/intel/common: Add/Use common function to set virtualization
Migrate duplicated enable_vmx() method from multiple CPUs to common
folder. Add common virtualization option for CPUs which support it.
Note that this changes the default to enable virtualization on CPUs
that support it.
Change-Id: Ib110bed6c9f5508e3f867dcdc6f341fc50e501d1
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/17874
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins)
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"); +} |