mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-03 20:59:53 +00:00
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>
258 lines
7.7 KiB
Python
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",
|
|
]
|