config_tools: add CPU capability checks

Add CPU capability checks.
If a feature is not supported on this processor, the board inspector
will show error message because it would impact ACRN’s ability
to function properly.

v3-->v4:
Update the error messages.

v2-->v3:
1. For VMX features, split each feature as a separate property, capability
checks in XML schema will then check all those features.
2. Use the class names instead of addresses, and invoke the rdmsr method
of each class.

v1-->v2:
1. Define each register as a class inheriting the `MSR` class defined
in platformbase.py, and define each bit as fields of that class.
2. The board inspector simply collects the CPU capability and attribute,
and the XSD does the actual check

Tracked-On: #6689
Signed-off-by: Kunhui-Li <kunhuix.li@intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
Kunhui-Li 2022-03-08 16:26:40 +08:00 committed by acrnsi-robot
parent 29e3dd7163
commit 7dfc3c683c
5 changed files with 507 additions and 8 deletions

View File

@ -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

View File

@ -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",
]

View File

@ -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

View File

@ -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:

View File

@ -5,7 +5,262 @@
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx'])">
<xs:annotation acrn:severity="error">
<xs:documentation>Intel(R) Virtualization Technology Extension shall be enabled in BIOS.</xs:documentation>
<xs:documentation>Virtual Machine Extensions (VMX) feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='intel_64'])">
<xs:annotation acrn:severity="error">
<xs:documentation>Long mode (x86-64, 64-bit) feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies not($model/capability[@id='set_32bit_addr_width'])">
<xs:annotation acrn:severity="error">
<xs:documentation>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.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies compare($model/attribute[@id='cpuid_level'], '0x15') &gt;= 0">
<xs:annotation acrn:severity="error">
<xs:documentation>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.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model
satisfies (($model/attribute[@id='physical_address_bits']) != 0 and ($model/attribute[@id='linear_address_bits']) != 0)">
<xs:annotation acrn:severity="error">
<xs:documentation>"Zero linear/physical address size" feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model
satisfies not(($model/attribute[@id='physical_address_bits']) > 39 and (not($model/capability[@id='gbyte_pages'])
or not($model/capability[@id='vmx_ept_1gb_page'])))">
<xs:annotation acrn:severity="error">
<xs:documentation>"1GB large page(Physical-address width > 39)" feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='fast_string'])">
<xs:annotation acrn:severity="error">
<xs:documentation>"Fast string" feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='erms'])">
<xs:annotation acrn:severity="error">
<xs:documentation>Enhanced rep movsb/stosb feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='invariant_tsc'])">
<xs:annotation acrn:severity="error">
<xs:documentation>Invariant TSC feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='tsc_deadline'])">
<xs:annotation acrn:severity="error">
<xs:documentation>TSC deadline feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='execute_disable'])">
<xs:annotation acrn:severity="error">
<xs:documentation>NX feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='smep'])">
<xs:annotation acrn:severity="error">
<xs:documentation>SMEP feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='smap'])">
<xs:annotation acrn:severity="error">
<xs:documentation>SMAP feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='mtrr'])">
<xs:annotation acrn:severity="error">
<xs:documentation>MTRR feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='clflushopt'])">
<xs:annotation acrn:severity="error">
<xs:documentation>CLFLUSHOPT feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='x2apic'])">
<xs:annotation acrn:severity="error">
<xs:documentation>x2APIC feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='popcnt'])">
<xs:annotation acrn:severity="error">
<xs:documentation>POPCNT feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='sse'])">
<xs:annotation acrn:severity="error">
<xs:documentation>SSE feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='rdrand'])">
<xs:annotation acrn:severity="error">
<xs:documentation>RDRAND feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='invept'])">
<xs:annotation acrn:severity="error">
<xs:documentation>INVEPT is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='unrestricted_guest'])">
<xs:annotation acrn:severity="error">
<xs:documentation>Unrestricted guest is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='ept'])">
<xs:annotation acrn:severity="error">
<xs:documentation>EPT feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='ept_2mb_page'])">
<xs:annotation acrn:severity="error">
<xs:documentation>EPT does not support 2MB large pages on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='invvpid'])">
<xs:annotation acrn:severity="error">
<xs:documentation>INVVPID feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='apicv'])">
<xs:annotation acrn:severity="error">
<xs:documentation>APICV feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_pinbased_ctls_irq_exit'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability External-interrupt exiting for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls_tsc_off'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Use TSC offsetting for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls_tpr_shadow'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Use TPR shadow for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls_io_bitmap'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Use I/O bitmaps for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls_msr_bitmap'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Use MSR bitmaps for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls_hlt'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability HLT exiting for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls_secondary'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Activate secondary controls for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_exit_ctls_ack_irq'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability acknowledge interrupt on exit feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_exit_ctls_save_pat'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability save IA32_PAT on VM exit feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_exit_ctls_load_pat'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability load IA32_PAT on VM exit feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_exit_ctls_host_addr64'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Host address-space size on VM exit feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_entry_ctls_load_pat'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability IA32_PAT MSR load on VM entry feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_entry_ctls_ia32e_mode'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability IA-32e mode guest support after VM entry feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls2_vapic'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Virtualize APIC accesses for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls2_ept'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Enable EPT for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls2_vpid'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Enable VPID for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls2_rdtscp'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Enable RDTSCP for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $model in processors/model satisfies exists($model/capability[@id='vmx_procbased_ctls2_unrestrict'])">
<xs:annotation acrn:severity="error">
<xs:documentation>VMX capability Unrestricted guest for VM execution controls feature is not supported on this processor. ACRN requires this feature to function properly.</xs:documentation>
</xs:annotation>
</xs:assert>