<p>Matt DeVillier has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/25331">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/common/block: add VMX support<br><br>Enable VMX (and SMX) if supported by CPU and enabled in board<br>devicetree. Check lock bit unset before enabling VMX.<br><br>Change-Id: Ic57eac45e9c65baa4479735c6d70a7eb685f080e<br>Signed-off-by: Matt DeVillier <matt.devillier@gmail.com><br>---<br>M src/soc/intel/common/block/include/intelblocks/msr.h<br>A src/soc/intel/common/block/include/intelblocks/vmx.h<br>A src/soc/intel/common/block/vmx/Kconfig<br>A src/soc/intel/common/block/vmx/Makefile.inc<br>A src/soc/intel/common/block/vmx/vmx.c<br>5 files changed, 132 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/31/25331/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/intel/common/block/include/intelblocks/msr.h b/src/soc/intel/common/block/include/intelblocks/msr.h</span><br><span>index 7aa81f0..ea29bed 100644</span><br><span>--- a/src/soc/intel/common/block/include/intelblocks/msr.h</span><br><span>+++ b/src/soc/intel/common/block/include/intelblocks/msr.h</span><br><span>@@ -19,6 +19,8 @@</span><br><span> #define MSR_CORE_THREAD_COUNT      0x35</span><br><span> #define IA32_FEATURE_CONTROL    0x3a</span><br><span> #define  FEATURE_CONTROL_LOCK   (1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  FEATURE_ENABLE_VMX        (1 << 2)</span><br><span style="color: hsl(120, 100%, 40%);">+#define  FEATURE_ENABLE_SMX     (1 << 1)</span><br><span> #define  CPUID_VMX            (1 << 5)</span><br><span> #define  CPUID_SMX            (1 << 6)</span><br><span> #define  SGX_GLOBAL_ENABLE    (1 << 18)</span><br><span>diff --git a/src/soc/intel/common/block/include/intelblocks/vmx.h b/src/soc/intel/common/block/include/intelblocks/vmx.h</span><br><span>new file mode 100644</span><br><span>index 0000000..6336498</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/common/block/include/intelblocks/vmx.h</span><br><span>@@ -0,0 +1,32 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017 Intel Corporation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifndef SOC_INTEL_COMMON_BLOCK_VMX_H</span><br><span style="color: hsl(120, 100%, 40%);">+#define SOC_INTEL_COMMON_BLOCK_VMX_H</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct vmx_param {</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t enable;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Configure VMX.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+void vmx_configure(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* SOC specific API to get VMX params.</span><br><span style="color: hsl(120, 100%, 40%);">+ * returns 0, if able to get VMX params; otherwise returns -1 */</span><br><span style="color: hsl(120, 100%, 40%);">+int soc_fill_vmx_param(struct vmx_param *vmx_param);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif        /* SOC_INTEL_COMMON_BLOCK_VMX_H */</span><br><span>diff --git a/src/soc/intel/common/block/vmx/Kconfig b/src/soc/intel/common/block/vmx/Kconfig</span><br><span>new file mode 100644</span><br><span>index 0000000..f8dce07</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/common/block/vmx/Kconfig</span><br><span>@@ -0,0 +1,3 @@</span><br><span style="color: hsl(120, 100%, 40%);">+config SOC_INTEL_COMMON_BLOCK_VMX</span><br><span style="color: hsl(120, 100%, 40%);">+ bool "Enable VMX for virtualization"</span><br><span style="color: hsl(120, 100%, 40%);">+        default n</span><br><span>diff --git a/src/soc/intel/common/block/vmx/Makefile.inc b/src/soc/intel/common/block/vmx/Makefile.inc</span><br><span>new file mode 100644</span><br><span>index 0000000..861e2f9</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/common/block/vmx/Makefile.inc</span><br><span>@@ -0,0 +1 @@</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_VMX) += vmx.c</span><br><span>diff --git a/src/soc/intel/common/block/vmx/vmx.c b/src/soc/intel/common/block/vmx/vmx.c</span><br><span>new file mode 100644</span><br><span>index 0000000..c7c594d</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/intel/common/block/vmx/vmx.c</span><br><span>@@ -0,0 +1,94 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017 Intel Corporation.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+//#include <assert.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+//#include <cpu/x86/mtrr.h></span><br><span style="color: hsl(120, 100%, 40%);">+//#include <cpu/intel/microcode.h></span><br><span style="color: hsl(120, 100%, 40%);">+//#include <intelblocks/mp_init.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <intelblocks/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <intelblocks/vmx.h></span><br><span style="color: hsl(120, 100%, 40%);">+//#include <intelblocks/systemagent.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/cpu.h></span><br><span style="color: hsl(120, 100%, 40%);">+//#include <soc/pci_devs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static bool vmx_param_valid;</span><br><span style="color: hsl(120, 100%, 40%);">+static struct vmx_param g_vmx_param;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct vmx_param *get_vmx_param(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (vmx_param_valid)</span><br><span style="color: hsl(120, 100%, 40%);">+          return &g_vmx_param;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    memset(&g_vmx_param, 0, sizeof(g_vmx_param));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (soc_fill_vmx_param(&g_vmx_param) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printk(BIOS_ERR, "VMX : Failed to get soc vmx param\n");</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     vmx_param_valid = true;</span><br><span style="color: hsl(120, 100%, 40%);">+       printk(BIOS_INFO, "VMX : param.enable = %d\n", g_vmx_param.enable);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return &g_vmx_param;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int soc_vmx_enabled(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    const struct vmx_param *vmx_param = get_vmx_param();</span><br><span style="color: hsl(120, 100%, 40%);">+  return vmx_param ? vmx_param->enable : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int is_vmx_supported(struct cpuid_result regs)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Check that VMX is supported */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(regs.ecx & CPUID_VMX)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            printk(BIOS_DEBUG, "CPU doesn't support VMX\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void vmx_configure(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   msr_t msr;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct cpuid_result regs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   regs = cpuid(1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!soc_vmx_enabled() || !is_vmx_supported(regs)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printk(BIOS_ERR, "VMX: pre-conditions not met\n");</span><br><span style="color: hsl(120, 100%, 40%);">+          return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msr = rdmsr(IA32_FEATURE_CONTROL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Only enable it when it is not locked */</span><br><span style="color: hsl(120, 100%, 40%);">+    if ((msr.lo & FEATURE_CONTROL_LOCK) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Enable VMX (and SMX, if supported) */</span><br><span style="color: hsl(120, 100%, 40%);">+              msr.lo |= FEATURE_ENABLE_VMX;</span><br><span style="color: hsl(120, 100%, 40%);">+         if (regs.ecx & CPUID_SMX)</span><br><span style="color: hsl(120, 100%, 40%);">+                 msr.lo |= FEATURE_ENABLE_SMX;</span><br><span style="color: hsl(120, 100%, 40%);">+         wrmsr(IA32_FEATURE_CONTROL, msr);</span><br><span style="color: hsl(120, 100%, 40%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_ERR, "VMX: feature control locked, cannot set\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Report current status */</span><br><span style="color: hsl(120, 100%, 40%);">+   msr = rdmsr(IA32_FEATURE_CONTROL);</span><br><span style="color: hsl(120, 100%, 40%);">+    printk(BIOS_DEBUG, "VMX status: %s, %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          (msr.lo & FEATURE_ENABLE_VMX) ? "enabled" : "disabled",</span><br><span style="color: hsl(120, 100%, 40%);">+               (msr.lo & FEATURE_CONTROL_LOCK) ? "locked" : "unlocked");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/25331">change 25331</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/25331"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ic57eac45e9c65baa4479735c6d70a7eb685f080e </div>
<div style="display:none"> Gerrit-Change-Number: 25331 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Matt DeVillier <matt.devillier@gmail.com> </div>