diff options
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/msr.h | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/include/intelblocks/vmx.h | 30 | ||||
-rw-r--r-- | src/soc/intel/common/block/vmx/Kconfig | 3 | ||||
-rw-r--r-- | src/soc/intel/common/block/vmx/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/intel/common/block/vmx/vmx.c | 72 |
5 files changed, 107 insertions, 0 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 7aa81f09ea..22e8862e98 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -19,6 +19,7 @@ #define MSR_CORE_THREAD_COUNT 0x35 #define IA32_FEATURE_CONTROL 0x3a #define FEATURE_CONTROL_LOCK (1) +#define FEATURE_ENABLE_VMX (1 << 2) #define CPUID_VMX (1 << 5) #define CPUID_SMX (1 << 6) #define SGX_GLOBAL_ENABLE (1 << 18) diff --git a/src/soc/intel/common/block/include/intelblocks/vmx.h b/src/soc/intel/common/block/include/intelblocks/vmx.h new file mode 100644 index 0000000000..1f6d33656e --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/vmx.h @@ -0,0 +1,30 @@ +/* + * 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 SOC_INTEL_COMMON_BLOCK_VMX_H +#define SOC_INTEL_COMMON_BLOCK_VMX_H + +struct vmx_param { + uint8_t enable; +}; + +/* + * Configure VMX. + */ +void vmx_configure(void); + +/* SOC specific API to get VMX params. + * returns 0, if able to get VMX params; otherwise returns -1 */ +int soc_fill_vmx_param(struct vmx_param *vmx_param); + +#endif /* SOC_INTEL_COMMON_BLOCK_VMX_H */ diff --git a/src/soc/intel/common/block/vmx/Kconfig b/src/soc/intel/common/block/vmx/Kconfig new file mode 100644 index 0000000000..f8dce0791f --- /dev/null +++ b/src/soc/intel/common/block/vmx/Kconfig @@ -0,0 +1,3 @@ +config SOC_INTEL_COMMON_BLOCK_VMX + bool "Enable VMX for virtualization" + default n diff --git a/src/soc/intel/common/block/vmx/Makefile.inc b/src/soc/intel/common/block/vmx/Makefile.inc new file mode 100644 index 0000000000..861e2f97d2 --- /dev/null +++ b/src/soc/intel/common/block/vmx/Makefile.inc @@ -0,0 +1 @@ +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_VMX) += vmx.c diff --git a/src/soc/intel/common/block/vmx/vmx.c b/src/soc/intel/common/block/vmx/vmx.c new file mode 100644 index 0000000000..307ffd9ddb --- /dev/null +++ b/src/soc/intel/common/block/vmx/vmx.c @@ -0,0 +1,72 @@ +/* + * 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. + */ + +#include <console/console.h> +#include <cpu/x86/msr.h> +#include <intelblocks/msr.h> +#include <intelblocks/vmx.h> +#include <soc/cpu.h> +#include <string.h> + +static bool vmx_param_valid; +static struct vmx_param g_vmx_param; + +static const struct vmx_param *get_vmx_param(void) +{ + if (vmx_param_valid) + return &g_vmx_param; + + memset(&g_vmx_param, 0, sizeof(g_vmx_param)); + if (soc_fill_vmx_param(&g_vmx_param) < 0) { + printk(BIOS_ERR, "VMX : Failed to get soc vmx param\n"); + return NULL; + } + vmx_param_valid = true; + printk(BIOS_INFO, "VMX : param.enable = %d\n", g_vmx_param.enable); + + return &g_vmx_param; +} + +static int soc_vmx_enabled(void) +{ + const struct vmx_param *vmx_param = get_vmx_param(); + return vmx_param ? vmx_param->enable : 0; +} + +void vmx_configure(void) +{ + msr_t msr; + struct cpuid_result regs; + + regs = cpuid(1); + + if (!soc_vmx_enabled() || !(regs.ecx & CPUID_VMX)) { + printk(BIOS_ERR, "VMX: pre-conditions not met\n"); + return; + } + + msr = rdmsr(IA32_FEATURE_CONTROL); + + /* Only enable it when it is not locked */ + if ((msr.lo & FEATURE_CONTROL_LOCK) == 0) { + /* Enable VMX */ + msr.lo |= FEATURE_ENABLE_VMX; + wrmsr(IA32_FEATURE_CONTROL, msr); + } + + /* Report current status */ + msr = rdmsr(IA32_FEATURE_CONTROL); + printk(BIOS_DEBUG, "VMX status: %s, %s\n", + (msr.lo & FEATURE_ENABLE_VMX) ? "enabled" : "disabled", + (msr.lo & FEATURE_CONTROL_LOCK) ? "locked" : "unlocked"); +} |