diff --git a/misc/config_tools/board_inspector/cpuparser/cpuids.py b/misc/config_tools/board_inspector/cpuparser/cpuids.py
index b8a074f2e..b2af4d101 100644
--- a/misc/config_tools/board_inspector/cpuparser/cpuids.py
+++ b/misc/config_tools/board_inspector/cpuparser/cpuids.py
@@ -19,11 +19,19 @@ class LEAF_0(CPUID):
leaf = 0x0
max_leaf = cpuidfield(EAX, 31, 0, doc="Highest value the CPUID recognizes for returning basic processor information")
+ @property
+ def cpuid_level(self):
+ return hex(self.regs.eax)
+
@property
def vendor(self):
"""Vendor identification string"""
return struct.pack('III', self.regs.ebx, self.regs.edx, self.regs.ecx)
+ attribute_bits = [
+ "cpuid_level",
+ ]
+
class LEAF_1(CPUID):
"""Basic CPUID Information
diff --git a/misc/config_tools/board_inspector/cpuparser/msr.py b/misc/config_tools/board_inspector/cpuparser/msr.py
new file mode 100644
index 000000000..f6f8f9729
--- /dev/null
+++ b/misc/config_tools/board_inspector/cpuparser/msr.py
@@ -0,0 +1,206 @@
+# Copyright (C) 2022 Intel Corporation.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from cpuparser.platformbase import MSR, msrfield
+
+class MSR_IA32_MISC_ENABLE(MSR):
+ addr = 0x1a0
+ fast_string = msrfield(1, 0, doc=None)
+
+ capability_bits = [
+ "fast_string",
+ ]
+
+class MSR_IA32_VMX_PROCBASED_CTLS2(MSR):
+ addr = 0x0000048B
+
+ @property
+ def vmx_procbased_ctls2_vapic(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 0)
+
+ @property
+ def vmx_procbased_ctls2_ept(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 1)
+
+ @property
+ def vmx_procbased_ctls2_vpid(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 5)
+
+ @property
+ def vmx_procbased_ctls2_rdtscp(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 3)
+
+ @property
+ def vmx_procbased_ctls2_unrestrict(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 7)
+
+ capability_bits = [
+ "vmx_procbased_ctls2_vapic",
+ "vmx_procbased_ctls2_ept",
+ "vmx_procbased_ctls2_vpid",
+ "vmx_procbased_ctls2_rdtscp",
+ "vmx_procbased_ctls2_unrestrict",
+ ]
+
+class MSR_IA32_VMX_PINBASED_CTLS(MSR):
+ addr = 0x00000481
+
+ @property
+ def vmx_pinbased_ctls_irq_exit(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 0)
+
+ capability_bits = [
+ "vmx_pinbased_ctls_irq_exit",
+ ]
+
+class MSR_IA32_VMX_PROCBASED_CTLS(MSR):
+ addr = 0x00000482
+
+ @property
+ def vmx_procbased_ctls_tsc_off(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 3)
+
+ @property
+ def vmx_procbased_ctls_tpr_shadow(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 21)
+
+ @property
+ def vmx_procbased_ctls_io_bitmap(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 25)
+
+ @property
+ def vmx_procbased_ctls_msr_bitmap(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 28)
+
+ @property
+ def vmx_procbased_ctls_hlt(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 7)
+
+ @property
+ def vmx_procbased_ctls_secondary(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 31)
+
+ @property
+ def ept(self):
+ is_ept_supported = False
+ if ((self.value >> 32) & (1 << 31)) != 0:
+ msr_val = MSR_IA32_VMX_PROCBASED_CTLS2.rdmsr(self.cpu_id)
+ if msrfield.is_ctrl_setting_allowed(msr_val.value, 1 << 1):
+ is_ept_supported = True
+ return is_ept_supported
+
+ @property
+ def apicv(self):
+ features = 0
+ vapic_feature_tpr_shadow = 1 << 3
+ vapic_feature_virt_access = 1 << 0
+ vapic_feature_vx2apic_mode = 1 << 5
+ vapic_feature_virt_reg = 1 << 1
+ vapic_feature_intr_delivery = 1 << 2
+ vapic_feature_post_intr = 1 << 4
+
+ if msrfield.is_ctrl_setting_allowed(self.value, 1 << 21):
+ features |= vapic_feature_tpr_shadow
+
+ msr_val = MSR_IA32_VMX_PROCBASED_CTLS2.rdmsr(self.cpu_id)
+ if msrfield.is_ctrl_setting_allowed(msr_val.value, 1 << 0):
+ features |= vapic_feature_virt_access
+ if msrfield.is_ctrl_setting_allowed(msr_val.value, 1 << 4):
+ features |= vapic_feature_vx2apic_mode
+ if msrfield.is_ctrl_setting_allowed(msr_val.value, 1 << 8):
+ features |= vapic_feature_virt_reg
+ if msrfield.is_ctrl_setting_allowed(msr_val.value, 1 << 9):
+ features |= vapic_feature_intr_delivery
+
+ msr_val = MSR_IA32_VMX_PINBASED_CTLS.rdmsr(self.cpu_id)
+ if msrfield.is_ctrl_setting_allowed(msr_val.value, 1 << 7):
+ features |= vapic_feature_post_intr
+
+ apicv_basic_feature = (vapic_feature_tpr_shadow | vapic_feature_virt_access | vapic_feature_vx2apic_mode)
+ return (features & apicv_basic_feature) == apicv_basic_feature
+
+ capability_bits = [
+ "ept",
+ "apicv",
+ "vmx_procbased_ctls_tsc_off",
+ "vmx_procbased_ctls_tpr_shadow",
+ "vmx_procbased_ctls_io_bitmap",
+ "vmx_procbased_ctls_msr_bitmap",
+ "vmx_procbased_ctls_hlt",
+ "vmx_procbased_ctls_secondary",
+ ]
+
+class MSR_IA32_VMX_EPT_VPID_CAP(MSR):
+ addr = 0x0000048C
+
+ invept = msrfield(1, 20)
+ ept_2mb_page = msrfield(1, 16)
+ vmx_ept_1gb_page = msrfield(1, 17)
+ invvpid = msrfield(1, 32) and msrfield(1, 41) and msrfield(1, 42)
+
+ capability_bits = [
+ "invept",
+ "invvpid",
+ "ept_2mb_page",
+ "vmx_ept_1gb_page",
+ ]
+
+class MSR_IA32_VMX_MISC(MSR):
+ addr = 0x00000485
+ unrestricted_guest = msrfield(1, 5)
+
+ capability_bits = [
+ "unrestricted_guest",
+ ]
+
+class MSR_IA32_VMX_BASIC(MSR):
+ addr = 0x00000480
+ set_32bit_addr_width = msrfield(1, 48)
+
+ capability_bits = [
+ "set_32bit_addr_width",
+ ]
+
+class MSR_IA32_VMX_EXIT_CTLS(MSR):
+ addr = 0x00000483
+
+ @property
+ def vmx_exit_ctls_ack_irq(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 15)
+
+ @property
+ def vmx_exit_ctls_save_pat(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 18)
+
+ @property
+ def vmx_exit_ctls_load_pat(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 19)
+
+ @property
+ def vmx_exit_ctls_host_addr64(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 9)
+
+ capability_bits = [
+ "vmx_exit_ctls_ack_irq",
+ "vmx_exit_ctls_save_pat",
+ "vmx_exit_ctls_load_pat",
+ "vmx_exit_ctls_host_addr64",
+ ]
+
+class MSR_IA32_VMX_ENTRY_CTLS(MSR):
+ addr = 0x00000484
+
+ @property
+ def vmx_entry_ctls_load_pat(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 14)
+
+ @property
+ def vmx_entry_ctls_ia32e_mode(self):
+ return msrfield.is_vmx_cap_supported(self, 1 << 9)
+
+ capability_bits = [
+ "vmx_entry_ctls_load_pat",
+ "vmx_entry_ctls_ia32e_mode",
+ ]
diff --git a/misc/config_tools/board_inspector/cpuparser/platformbase.py b/misc/config_tools/board_inspector/cpuparser/platformbase.py
index 154f66289..73552a836 100644
--- a/misc/config_tools/board_inspector/cpuparser/platformbase.py
+++ b/misc/config_tools/board_inspector/cpuparser/platformbase.py
@@ -12,6 +12,7 @@ import functools
import inspect
import operator
import textwrap
+import logging
from collections import namedtuple
_wrapper = textwrap.TextWrapper(width=78, initial_indent=' ', subsequent_indent=' ')
@@ -135,8 +136,17 @@ class MSR(object):
return self.value != other.value
@classmethod
- def rdmsr(cls, cpu_id):
- r = cls(bits.rdmsr(cpu_id, cls.addr))
+ def rdmsr(cls, cpu_id: int) -> int:
+ try:
+ with open(f'/dev/cpu/{cpu_id}/msr', 'rb') as msr_reader:
+ msr_reader.seek(cls.addr)
+ r = msr_reader.read(8)
+ r = cls(int.from_bytes(r, 'little'))
+ except IOError:
+ logging.critical(f"Missing CPU MSR file at /dev/cpu/{cpu_id}/msr. Check the value of CONFIG_X86_MSR " \
+ "in the kernel config. Set it to 'Y' and rebuild the kernel. Then rerun the Board Inspector.")
+ sys.exit(1)
+
r.cpu_id = cpu_id
return r
@@ -187,15 +197,14 @@ class MSR(object):
return s
class msrfield(property):
+
def __init__(self, msb, lsb, doc=None):
self.msb = msb
self.lsb = lsb
-
- max_value = (1 << (msb - lsb + 1)) - 1
- field_mask = max_value << lsb
+ bit_mask = self.msb << self.lsb
def getter(self):
- return (self.value & field_mask) >> lsb
+ return (self.value & bit_mask) != 0
def setter(self, value):
if value > max_value:
@@ -209,3 +218,14 @@ class msrfield(property):
self.value = (self.value & ~field_mask) | (value << lsb)
super(msrfield, self).__init__(getter, setter, doc=doc)
+
+ def is_vmx_cap_supported(self, bits):
+ vmx_msr = self.value
+ vmx_msr_bin = int.to_bytes(vmx_msr, 8, 'big')
+ vmx_msr_low = int.from_bytes(vmx_msr_bin[4:], 'big')
+ vmx_msr_high = int.from_bytes(vmx_msr_bin[:4], 'big')
+ return ((vmx_msr_high & bits) == bits) and ((vmx_msr_low & bits) == 0)
+
+ @staticmethod
+ def is_ctrl_setting_allowed(msr_val, ctrl):
+ return ((msr_val >> 32) & ctrl) == ctrl
diff --git a/misc/config_tools/board_inspector/extractors/10-processors.py b/misc/config_tools/board_inspector/extractors/10-processors.py
index 73d9997a3..150f806da 100644
--- a/misc/config_tools/board_inspector/extractors/10-processors.py
+++ b/misc/config_tools/board_inspector/extractors/10-processors.py
@@ -7,6 +7,7 @@ import logging
import lxml.etree
from cpuparser import parse_cpuid, get_online_cpu_ids
+from cpuparser.msr import *
from extractors.helpers import add_child, get_node
level_types = {
@@ -52,7 +53,16 @@ def extract_model(processors_node, cpu_id, family_id, model_id, core_type, nativ
if getattr(leaf_data, cap) == 1:
add_child(n, "capability", id=cap)
- leaves = [(0x80000008, 0)]
+ msr_regs = [MSR_IA32_MISC_ENABLE, MSR_IA32_VMX_BASIC, MSR_IA32_VMX_PINBASED_CTLS,
+ MSR_IA32_VMX_PROCBASED_CTLS, MSR_IA32_VMX_EXIT_CTLS, MSR_IA32_VMX_ENTRY_CTLS,
+ MSR_IA32_VMX_MISC, MSR_IA32_VMX_PROCBASED_CTLS2, MSR_IA32_VMX_EPT_VPID_CAP]
+ for msr_reg in msr_regs:
+ msr_data = msr_reg.rdmsr(cpu_id)
+ for cap in msr_data.capability_bits:
+ if getattr(msr_data, cap) == 1:
+ add_child(n, "capability", id=cap)
+
+ leaves = [(0, 0), (0x80000008, 0)]
for leaf in leaves:
leaf_data = parse_cpuid(leaf[0], leaf[1], cpu_id)
for cap in leaf_data.attribute_bits:
diff --git a/misc/config_tools/board_inspector/schema/checks/platform_capabilities.xsd b/misc/config_tools/board_inspector/schema/checks/platform_capabilities.xsd
index 6af0241e6..bfb8d322a 100644
--- a/misc/config_tools/board_inspector/schema/checks/platform_capabilities.xsd
+++ b/misc/config_tools/board_inspector/schema/checks/platform_capabilities.xsd
@@ -5,7 +5,262 @@
- Intel(R) Virtualization Technology Extension shall be enabled in BIOS.
+ Virtual Machine Extensions (VMX) feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ Long mode (x86-64, 64-bit) feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ The width of the physical addresses used for the VMXON region is limited to 32bit. "Intel 64 architecture" feature is not enabled. ACRN requires this feature to function properly.
+
+
+
+
+
+ Instruction CPUID time stamp counter, nominal core crystal clock information leaf and processor frequency information leaf are not supported. ACRN requires this feature to function properly.
+
+
+
+
+
+ "Zero linear/physical address size" feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ "1GB large page(Physical-address width > 39)" feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ "Fast string" feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ Enhanced rep movsb/stosb feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ Invariant TSC feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ TSC deadline feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ NX feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ SMEP feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ SMAP feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ MTRR feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ CLFLUSHOPT feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ x2APIC feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ POPCNT feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ SSE feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ RDRAND feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ INVEPT is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ Unrestricted guest is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ EPT feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ EPT does not support 2MB large pages on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ INVVPID feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ APICV feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability External-interrupt exiting for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Use TSC offsetting for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Use TPR shadow for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Use I/O bitmaps for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Use MSR bitmaps for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability HLT exiting for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Activate secondary controls for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability acknowledge interrupt on exit feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability save IA32_PAT on VM exit feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability load IA32_PAT on VM exit feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Host address-space size on VM exit feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability IA32_PAT MSR load on VM entry feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability IA-32e mode guest support after VM entry feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Virtualize APIC accesses for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Enable EPT for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Enable VPID for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Enable RDTSCP for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.
+
+
+
+
+
+ VMX capability Unrestricted guest for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.