hv/config-tools: add the support for vCAT

Add the VCAT_ENABLED element to RDTType so that user can enable/disable vCAT globally

Add the GUEST_FLAG_VCAT_ENABLED guest flag to enable/disable vCAT per-VM.

  Currently we have the following per-VM clos element in scenario file for RDT use:
    <clos>
      <vcpu_clos>0</vcpu_clos>
      <vcpu_clos>0</vcpu_clos>
    </clos>

  When the GUEST_FLAG_VCAT_ENABLED guest flag is not specified, clos is for RDT use,
  vcpu_clos is per-CPU and it configures each CPU in VMs to a desired CLOS ID.

  When the GUEST_FLAG_VCAT_ENABLED guest flag is specified, vCAT is enabled for this VM,
  clos is for vCAT use, vcpu_clos is not per-CPU anymore in this case, just a list of
  physical CLOSIDs (minimum 2) that are assigned to VMs for vCAT use. Each vcpu_clos
  will be mapped to a virtual CLOSID, the first vcpu_clos is mapped to virtual CLOSID
  0 and the second is mapped to virtual CLOSID 1, etc

Add xs:assert to prevent any problems with invalid configuration data for vCAT:

  If any GUEST_FLAG_VCAT_ENABLED guest flag is specified, both RDT_ENABLED and VCAT_ENABLED
  must be 'y'

  If VCAT_ENABLED is 'y', RDT_ENABLED must be 'y' and CDP_ENABLED must be 'n'

  For a vCAT VM, vcpu_clos cannot be set to CLOSID 0, CLOSID 0 is reserved to be used by hypervisor

  For a vCAT VM, number of clos/vcpu_clos elements must be greater than 1

  For a vCAT VM, each clos/vcpu_clos must be less than L2/L3 COS_MAX

  For a vCAT VM, its clos/vcpu_clos elements cannot contain duplicate values

  There should not be any CLOS IDs overlap between a vCAT VM and any other VMs

Tracked-On: #5917
Signed-off-by: dongshen <dongsheng.x.zhang@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
dongshen 2021-09-14 18:59:09 -07:00 committed by wenlingz
parent 66bbf6f751
commit 368f158b46
9 changed files with 107 additions and 12 deletions

View File

@ -57,6 +57,7 @@
#define GUEST_FLAG_RT (1UL << 4U) /* Whether the vm is RT-VM */
#define GUEST_FLAG_NVMX_ENABLED (1UL << 5U) /* Whether this VM supports nested virtualization */
#define GUEST_FLAG_SECURITY_VM (1UL << 6U) /* Whether this VM needs to do security-vm related fixup (TPM2 and SMBIOS pt) */
#define GUEST_FLAG_VCAT_ENABLED (1UL << 7U) /* Whether this VM supports vCAT */
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
#define VIRTUAL_SLEEP_CTL_ADDR 0x400U /* Pre-launched VM uses ACPI reduced HW mode and sleep control register */

View File

@ -23,7 +23,7 @@ DATACHECK_SCHEMA_FILE = SOURCE_ROOT_DIR + 'misc/config_tools/schema/datachecks.x
PY_CACHES = ["__pycache__", "../board_config/__pycache__", "../scenario_config/__pycache__"]
GUEST_FLAG = ["0", "0UL", "GUEST_FLAG_SECURE_WORLD_ENABLED", "GUEST_FLAG_LAPIC_PASSTHROUGH",
"GUEST_FLAG_IO_COMPLETION_POLLING", "GUEST_FLAG_NVMX_ENABLED", "GUEST_FLAG_HIDE_MTRR",
"GUEST_FLAG_RT", "GUEST_FLAG_SECURITY_VM"]
"GUEST_FLAG_RT", "GUEST_FLAG_SECURITY_VM", "GUEST_FLAG_VCAT_ENABLED"]
MULTI_ITEM = ["guest_flag", "pcpu_id", "vcpu_clos", "input", "block", "network", "pci_dev", "shm_region", "communication_vuart"]

View File

@ -1044,7 +1044,7 @@ def check_target_connection(vm_id, target_vm_id, target_uart_id, vm_visited, leg
raise TargetError("target vm{}'s vuart{} is not present".format(target_vm_id ,target_uart_id))
def vcpu_clos_check(cpus_per_vm, clos_per_vm, prime_item, item):
def vcpu_clos_check(cpus_per_vm, clos_per_vm, guest_flags, prime_item, item):
if not board_cfg_lib.is_rdt_enabled():
return
@ -1052,6 +1052,9 @@ def vcpu_clos_check(cpus_per_vm, clos_per_vm, prime_item, item):
common_clos_max = board_cfg_lib.get_common_clos_max()
for vm_i,vcpus in cpus_per_vm.items():
if vm_i in guest_flags and "GUEST_FLAG_VCAT_ENABLED" in guest_flags[vm_i]:
continue
clos_per_vm_len = 0
if vm_i in clos_per_vm:
clos_per_vm_len = len(clos_per_vm[vm_i])

View File

@ -400,7 +400,7 @@ class VmInfo:
scenario_cfg_lib.load_vm_check(self.load_vm, "load_vm")
scenario_cfg_lib.guest_flag_check(self.guest_flags, "guest_flags", "guest_flag")
err_dic = scenario_cfg_lib.vm_cpu_affinity_check(self.scenario_info, self.cpus_per_vm, "pcpu_id")
scenario_cfg_lib.vcpu_clos_check(self.cpus_per_vm, self.clos_per_vm, "clos", "vcpu_clos")
scenario_cfg_lib.vcpu_clos_check(self.cpus_per_vm, self.clos_per_vm, self.guest_flags, "clos", "vcpu_clos")
self.mem_info.check_item()
self.os_cfg.check_item()

View File

@ -39,6 +39,7 @@
- ``GUEST_FLAG_RT`` specify that the VM is an RT-VM (real-time)
- ``GUEST_FLAG_NVMX_ENABLED`` specify that the VM supports nested virtualization
- ``GUEST_FLAG_SECURITY_VM`` specify that the VM needs to do security-vm related
- ``GUEST_FLAG_VCAT_ENABLED`` specify that the VM supports CAT virtualization
fixup (TPM2 passthrough and SMBIOS passthrough)</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
@ -52,6 +53,7 @@
<xs:enumeration value="GUEST_FLAG_RT" />
<xs:enumeration value="GUEST_FLAG_NVMX_ENABLED" />
<xs:enumeration value="GUEST_FLAG_SECURITY_VM" />
<xs:enumeration value="GUEST_FLAG_VCAT_ENABLED" />
</xs:restriction>
</xs:simpleType>
@ -85,9 +87,14 @@ to.</xs:documentation>
<xs:sequence>
<xs:element name="vcpu_clos" type="xs:integer" default="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Configure each CPU in VMs to a desired CLOS ID in the ``VM`` section of the
scenario file. Follow :ref:`rdt_detection_capabilities`
to identify the maximum supported CLOS ID that can be used.</xs:documentation>
<xs:documentation>By default (``GUEST_FLAG_VCAT_ENABLED`` is not specified):
vcpu_clos is per-CPU and it configures each CPU in VMs to a desired CLOS ID in the ``VM`` section of the
scenario file. Follow :ref:`rdt_detection_capabilities` to identify the maximum supported CLOS ID that can be used.
If ``GUEST_FLAG_VCAT_ENABLED`` is specified:
vcpu_clos is not per-CPU anymore, just a list of physical CLOSIDs (minimum 2) that are assigned to VMs
for vCAT use. Each vcpu_clos will be mapped to a virtual CLOSID, the first vcpu_clos is mapped to virtual
CLOSID 0 and the second is mapped to virtual CLOSID 1, etc.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>

View File

@ -487,6 +487,79 @@ to launch post-launched User VMs.</xs:documentation>
<xs:documentation>Per VM GUEST_FLAG_NVMX_ENABLED can be set only if CONFIG_NVMX_ENABLED is set.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="if (//VCAT_ENABLED = 'y')
then (//CDP_ENABLED = 'n' and //RDT_ENABLED = 'y')
else true()">
<xs:annotation>
<xs:documentation>vCAT can be enabled only when RDT_ENABLED is 'y' and CDP_ENABLED is 'n'</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="if (count(//guest_flag[text() = 'GUEST_FLAG_VCAT_ENABLED']) > 0)
then //RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y'
else true()">
<xs:annotation>
<xs:documentation>Per VM GUEST_FLAG_VCAT_ENABLED can be set only when RDT_ENABLED is 'y' and VCAT_ENABLED is 'y'.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $vm in vm satisfies
(
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and $vm/guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED'])
then count($vm/clos/vcpu_clos) > 1
else true()
)
">
<xs:annotation>
<xs:documentation>For a vCAT VM, number of clos/vcpu_clos elements must be greater than 1!</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y')
then count(vm[guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED'] and count(clos/vcpu_clos[. = 0])]) = 0
else true()">
<xs:annotation>
<xs:documentation>For a vCAT VM, vcpu_clos cannot be set to CLOSID 0, CLOSID 0 is reserved to be used by hypervisor</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $vm in vm satisfies
(
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and $vm/guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED'])
then count($vm[clos/vcpu_clos[. &gt;= count($vm/..//CLOS_MASK)]]) = 0
else true()
)
">
<xs:annotation>
<xs:documentation>For a vCAT VM, each clos/vcpu_clos must be less than L2/L3 COS_MAX!</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $vm in vm satisfies
(
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and $vm/guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED'])
then count($vm/clos/vcpu_clos) = count(distinct-values($vm/clos/vcpu_clos))
else true()
)
">
<xs:annotation>
<xs:documentation>For a vCAT VM, its clos/vcpu_clos elements cannot contain duplicate values</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="every $vm1 in vm, $vm2 in $vm1/following-sibling::vm satisfies
(
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and ($vm1/guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED'] or $vm2/guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED']))
then count($vm1/clos/vcpu_clos[. = $vm2/clos/vcpu_clos]) = 0
else true()
)
">
<xs:annotation>
<xs:documentation>if RDT_ENABLED is 'y', there should not be any CLOS IDs overlap between a vCAT VM and any other VMs</xs:documentation>
</xs:annotation>
</xs:assert>
</xs:complexType>
<xs:element name="acrn-config" type="ACRNConfigType" />

View File

@ -188,8 +188,14 @@ RDT, setting this option to ``y`` is ignored.</xs:documentation>
<xs:annotation>
<xs:documentation>Specify whether to enable Code and Data Prioritization (CDP).
CDP is an extension of CAT. Set to 'y' to enable the feature or 'n' to disable it.
The 'y' will be ignored when hardware does not support CDP. Default
value ``n``.</xs:documentation>
The 'y' will be ignored when hardware does not support CDP.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="VCAT_ENABLED" type="Boolean" default="n">
<xs:annotation>
<xs:documentation>Specify whether to enable CAT virtualization (vCAT).
Set to 'y' to enable the feature or 'n' to disable it.
The 'y' will be ignored when hardware does not support CAT.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="CLOS_MASK" type="xs:string" minOccurs="0" maxOccurs="unbounded">

View File

@ -94,10 +94,15 @@
<xsl:with-param name="value" select="RDT/RDT_ENABLED" />
</xsl:call-template>
<xsl:if test="RDT/RDT_ENABLED = 'y'">
<xsl:if test="acrn:is-rdt-enabled()">
<xsl:call-template name="boolean-by-key-value">
<xsl:with-param name="key" select="'CDP_ENABLED'" />
<xsl:with-param name="value" select="RDT/CDP_ENABLED" />
<xsl:with-param name="key" select="'CDP_ENABLED'" />
<xsl:with-param name="value" select="RDT/CDP_ENABLED" />
</xsl:call-template>
<xsl:call-template name="boolean-by-key-value">
<xsl:with-param name="key" select="'VCAT_ENABLED'" />
<xsl:with-param name="value" select="RDT/VCAT_ENABLED" />
</xsl:call-template>
</xsl:if>

View File

@ -356,7 +356,7 @@
<func:function name="acrn:is-rdt-enabled">
<xsl:choose>
<xsl:when test="//RDT_ENABLED = 'y'">
<xsl:when test="acrn:is-rdt-supported() and //RDT_ENABLED = 'y'">
<func:result select="true()" />
</xsl:when>
<xsl:otherwise>