acrn-hypervisor/misc/config_tools/board_inspector/cpuparser/msr.py
Junjie Mao a6614e7e2f config_tools: board_inspector: refactors MSR utilities
In v3.0 the msrfield class has its initializer changed in a way that is
incompatible with the parameter names or the getter/setter. When introduced
from the BITS project, that class allows specifying an MSR field of
arbitrary length by being given the index of the most and least significant
bits.

This patch restores the original behavior of that msrfield class and moves
the use-case specific methods, namely is_vmx_cap_supported and
is_ctrl_setting_allowed, to a helper class.

Parsing of the VMX capability reporting MSRs in msr.py are updated
accordingly, and brief documentation of the MSR fields are added as well.

Tracked-On: #7948
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
2022-08-05 07:36:40 +08:00

258 lines
7.7 KiB
Python

# 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(0, 0, doc="Fast-strings enable")
capability_bits = [
"fast_string",
]
class MSR_IA32_FEATURE_CONTROL(MSR):
addr = 0x03a
lock = msrfield(0, 0, doc="Lock bit")
vmx_outside_smx = msrfield(2, 2, doc="Enable VMX outside SMX operation")
@property
def disable_vmx(self):
return self.lock and not self.vmx_outside_smx
capability_bits = [
"disable_vmx",
]
class VMXCapabilityReportingMSR(MSR):
def get_field_idx(self, field):
if isinstance(field, int):
return field
if isinstance(field, str):
return getattr(type(self), field).lsb
assert False, f"Invalid field type: {field}, {type(field)}"
def allows_0_setting(self, field):
field_idx = self.get_field_idx(field)
if field_idx >= 32:
return False
bit_mask = (1 << field_idx)
return (self.value & bit_mask) == 0
def allows_1_setting(self, field):
field_idx = self.get_field_idx(field)
if field_idx >= 32:
return False
bit_mask = (1 << field_idx)
high = self.value >> 32
return (high & bit_mask) == bit_mask
def allows_flexible_setting(self, field):
field_idx = self.get_field_idx(field)
return self.allows_0_setting(field_idx) and self.allows_1_setting(field_idx)
class MSR_IA32_VMX_PROCBASED_CTLS2(VMXCapabilityReportingMSR):
addr = 0x0000048B
vapic_access = msrfield(0, 0, doc="Virtualize APIC accesses")
ept = msrfield(1, 1, doc="Enable EPT")
rdtscp = msrfield(3, 3, doc="Enable RDTSCP")
vx2apic = msrfield(4, 4, doc="Virtualize x2APIC mode")
vpid = msrfield(5, 5, doc="Enable VPID")
unrestricted_guest = msrfield(7, 7, doc="Unrestricted guest")
apic_reg_virt = msrfield(8, 8, doc="APIC-register virtualization")
@property
def vmx_procbased_ctls2_vapic(self):
return self.allows_flexible_setting("vapic_access")
@property
def vmx_procbased_ctls2_ept(self):
return self.allows_flexible_setting("ept")
@property
def vmx_procbased_ctls2_vpid(self):
return self.allows_flexible_setting("vpid")
@property
def vmx_procbased_ctls2_rdtscp(self):
return self.allows_flexible_setting("rdtscp")
@property
def vmx_procbased_ctls2_unrestrict(self):
return self.allows_flexible_setting("unrestricted_guest")
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(VMXCapabilityReportingMSR):
addr = 0x00000481
irq_exiting = msrfield(0, 0, doc="External-interrupt existing")
@property
def vmx_pinbased_ctls_irq_exit(self):
return self.allows_flexible_setting("irq_exiting")
capability_bits = [
"vmx_pinbased_ctls_irq_exit",
]
class MSR_IA32_VMX_PROCBASED_CTLS(VMXCapabilityReportingMSR):
addr = 0x00000482
tsc_offsetting = msrfield(3, 3, doc="Use TSC offsetting")
hlt_exiting = msrfield(7, 7, doc="HLT exiting")
tpr_shadow = msrfield(21, 21, doc="Use TPR shadow")
io_bitmaps = msrfield(25, 25, doc="Use I/O bitmaps")
msr_bitmaps = msrfield(28, 28, doc="Use MSR bitmaps")
secondary_ctrls = msrfield(31, 31, doc="Activate secondary controls")
@property
def vmx_procbased_ctls_tsc_off(self):
return self.allows_flexible_setting("tsc_offsetting")
@property
def vmx_procbased_ctls_tpr_shadow(self):
return self.allows_flexible_setting("tpr_shadow")
@property
def vmx_procbased_ctls_io_bitmap(self):
return self.allows_flexible_setting("io_bitmaps")
@property
def vmx_procbased_ctls_msr_bitmap(self):
return self.allows_flexible_setting("msr_bitmaps")
@property
def vmx_procbased_ctls_hlt(self):
return self.allows_flexible_setting("hlt_exiting")
@property
def vmx_procbased_ctls_secondary(self):
return self.allows_flexible_setting("secondary_ctrls")
@property
def ept(self):
if self.allows_1_setting("secondary_ctrls"):
ctls2 = MSR_IA32_VMX_PROCBASED_CTLS2.rdmsr(self.cpu_id)
return ctls2.allows_1_setting("ept")
return False
@property
def apicv(self):
if not self.allows_1_setting("tpr_shadow"):
return False
ctls2 = MSR_IA32_VMX_PROCBASED_CTLS2.rdmsr(self.cpu_id)
return \
ctls2.allows_1_setting("vapic_access") and \
ctls2.allows_1_setting("vx2apic")
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(20, 20, doc="INVEPT instruction supported")
ept_2mb_page = msrfield(16, 16, doc="EPT 2-Mbyte page supported")
vmx_ept_1gb_page = msrfield(17, 17, doc="EPT 1-Gbyte page supported")
invvpid_inst = msrfield(32, 32, doc="INVVPID instruction supported")
invvpid_single_context = msrfield(41, 41, doc="single-context INVVPID type supported")
invvpid_all_context = msrfield(42, 42, doc="all-context INVVPID type supported")
@property
def invvpid(self):
return self.invvpid_inst and self.invvpid_single_context and self.invvpid_all_context
capability_bits = [
"invept",
"invvpid",
"ept_2mb_page",
"vmx_ept_1gb_page",
]
class MSR_IA32_VMX_MISC(MSR):
addr = 0x00000485
stores_lma_on_exit = msrfield(5, 5, doc="VM exits stores the value of IA32_EFER.LMA into the 'IA-32e mode guest' VM-entry control")
capability_bits = [
"stores_lma_on_exit",
]
class MSR_IA32_VMX_BASIC(MSR):
addr = 0x00000480
set_32bit_addr_width = msrfield(48, 48, doc="Addresses of VMXON, VMCS and referenced structures limited to 32-bit")
capability_bits = [
"set_32bit_addr_width",
]
class MSR_IA32_VMX_EXIT_CTLS(VMXCapabilityReportingMSR):
addr = 0x00000483
host_addr_size = msrfield(9, 9, doc="Host address-space size")
ack_irq_on_exit = msrfield(15, 15, doc="Acknowledge interrupt on exit")
save_pat = msrfield(18, 18, doc="Save IA32_PAT")
load_pat = msrfield(19, 19, doc="Load IA32_PAT")
@property
def vmx_exit_ctls_ack_irq(self):
return self.allows_flexible_setting("ack_irq_on_exit")
@property
def vmx_exit_ctls_save_pat(self):
return self.allows_flexible_setting("save_pat")
@property
def vmx_exit_ctls_load_pat(self):
return self.allows_flexible_setting("load_pat")
@property
def vmx_exit_ctls_host_addr64(self):
return self.allows_flexible_setting("host_addr_size")
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(VMXCapabilityReportingMSR):
addr = 0x00000484
ia32e_mode_guest = msrfield(9, 9, doc="IA-32e mode guest")
load_pat = msrfield(14, 14, doc="Load IA32_PAT")
@property
def vmx_entry_ctls_load_pat(self):
return self.allows_flexible_setting("load_pat")
@property
def vmx_entry_ctls_ia32e_mode(self):
return self.allows_flexible_setting("ia32e_mode_guest")
capability_bits = [
"vmx_entry_ctls_load_pat",
"vmx_entry_ctls_ia32e_mode",
]