Matt DeVillier has uploaded this change for review. ( https://review.coreboot.org/25331
Change subject: soc/intel/common/block: add VMX support ......................................................................
soc/intel/common/block: add VMX support
Enable VMX (and SMX) if supported by CPU and enabled in board devicetree. Check lock bit unset before enabling VMX.
Change-Id: Ic57eac45e9c65baa4479735c6d70a7eb685f080e Signed-off-by: Matt DeVillier matt.devillier@gmail.com --- M src/soc/intel/common/block/include/intelblocks/msr.h A src/soc/intel/common/block/include/intelblocks/vmx.h A src/soc/intel/common/block/vmx/Kconfig A src/soc/intel/common/block/vmx/Makefile.inc A src/soc/intel/common/block/vmx/vmx.c 5 files changed, 132 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/31/25331/1
diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h index 7aa81f0..ea29bed 100644 --- a/src/soc/intel/common/block/include/intelblocks/msr.h +++ b/src/soc/intel/common/block/include/intelblocks/msr.h @@ -19,6 +19,8 @@ #define MSR_CORE_THREAD_COUNT 0x35 #define IA32_FEATURE_CONTROL 0x3a #define FEATURE_CONTROL_LOCK (1) +#define FEATURE_ENABLE_VMX (1 << 2) +#define FEATURE_ENABLE_SMX (1 << 1) #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 0000000..6336498 --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/vmx.h @@ -0,0 +1,32 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * 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 0000000..f8dce07 --- /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 0000000..861e2f9 --- /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 0000000..c7c594d --- /dev/null +++ b/src/soc/intel/common/block/vmx/vmx.c @@ -0,0 +1,94 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * + * 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 <assert.h> +#include <console/console.h> +#include <cpu/x86/msr.h> +//#include <cpu/x86/mtrr.h> +//#include <cpu/intel/microcode.h> +//#include <intelblocks/mp_init.h> +#include <intelblocks/msr.h> +#include <intelblocks/vmx.h> +//#include <intelblocks/systemagent.h> +#include <soc/cpu.h> +//#include <soc/pci_devs.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; +} + +static int is_vmx_supported(struct cpuid_result regs) +{ + /* Check that VMX is supported */ + if (!(regs.ecx & CPUID_VMX)) { + printk(BIOS_DEBUG, "CPU doesn't support VMX\n"); + return 0; + } + return 1; +} + +void vmx_configure(void) +{ + msr_t msr; + struct cpuid_result regs; + + regs = cpuid(1); + + if (!soc_vmx_enabled() || !is_vmx_supported(regs)) { + 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 (and SMX, if supported) */ + msr.lo |= FEATURE_ENABLE_VMX; + if (regs.ecx & CPUID_SMX) + msr.lo |= FEATURE_ENABLE_SMX; + wrmsr(IA32_FEATURE_CONTROL, msr); + } else { + printk(BIOS_ERR, "VMX: feature control locked, cannot set\n"); + } + + /* 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"); +}