config tool: remove guest_flags in user interface

The concept of guest_flags is hard to understand for users.
So turn guest_flags into several parameters in config tool
user interface, list as below:

GUEST_FLAG_LAPIC_PASSTHROUGH ---> lapic_passthrough
GUEST_FLAG_IO_COMPLETION_POLLING ---> io_completion_polling
GUEST_FLAG_VCAT_ENABLED ---> virtual_cat_support
GUEST_FLAG_SECURE_WORLD_ENABLED ---> secure_world_support
GUEST_FLAG_HIDE_MTRR ---> hide_mtrr_support
GUEST_FLAG_NVMX_ENABLED ---> nested_virtualization_support
GUEST_FLAG_SECURITY_VM ---> security_vm
GUEST_FLAG_RT ---> vm_type(RTVM)
GUEST_FLAG_TEE ---> vm_type(TEE_VM)
GUEST_FLAG_REE ---> vm_type(REE_VM)

In addition, HV global parameter NVMX_ENABLE is removed
from user interface, when config tool detects more than
one VM with nested_virtualization_support, NVMX_ENABLE is
assigned as 'y' automatically.

v1->v2:
*Rebase on the latest xml schema checking change
*Remove "all rights reserved" from the license header in guest_flags.py

v2->v3:
*Change the name of the new config items to CAPITAL_CASE style
*Combine guest flag policy to an XPATH in guest_flags.py
*Use count() to directly deduce NVMX_ENABLED in config_common.xsl and
update `boolean-by-key-value` to process 'true'

v3->v4:
*Change the name of the new config items to lower_case style
*Change guest_flag_node to allocation_vm_node in guest_flags.py
*Separate value case and key case for boolean-by-key-value

Tracked-On: #6690
Signed-off-by: hangliu1 <hang1.liu@linux.intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
hangliu1 2022-02-20 20:52:11 -05:00 committed by acrnsi-robot
parent 1034443796
commit 0068d4e826
8 changed files with 100 additions and 98 deletions

View File

@ -737,12 +737,7 @@ def gen_dsdt(board_etree, scenario_etree, allocation_etree, vm_id, dest_path):
builder.build_value(0))))
objects.add_object("\\", s5_object)
rtvm = False
for guest_flag in scenario_etree.xpath(f"//vm[@id='{vm_id}']/guest_flags/guest_flag/text()"):
if guest_flag == 'GUEST_FLAG_LAPIC_PASSTHROUGH':
rtvm = True
break
rtvm = bool(scenario_etree.xpath(f"//vm[@id='{vm_id}']//lapic_passthrough[text()='y']"))
# RTVM cannot set IRQ because no INTR is sent with LAPIC PT
if rtvm is False:
objects.add_object("\\_SB_", pnp_uart("UAR0", 0, "COM1", 0x3f8, 4))

View File

@ -37,54 +37,6 @@
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="GuestFlagsOptionsType">
<xs:annotation>
<xs:documentation>
- ``0``, ``0UL``, or an empty string means no guest flags are enabled.
- ``GUEST_FLAG_SECURE_WORLD_ENABLED`` specify that the secure world is
enabled
- ``GUEST_FLAG_LAPIC_PASSTHROUGH`` specify that LAPIC is passed through
- ``GUEST_FLAG_IO_COMPLETION_POLLING`` specify that the hypervisor needs
IO polling to completion
- ``GUEST_FLAG_HIDE_MTRR`` specify that MTRR is hidden from the VM
- ``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">
<xs:enumeration value="" />
<xs:enumeration value="0" />
<xs:enumeration value="0UL" />
<xs:enumeration value="GUEST_FLAG_SECURE_WORLD_ENABLED" />
<xs:enumeration value="GUEST_FLAG_LAPIC_PASSTHROUGH" />
<xs:enumeration value="GUEST_FLAG_IO_COMPLETION_POLLING" />
<xs:enumeration value="GUEST_FLAG_HIDE_MTRR" />
<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:enumeration value="GUEST_FLAG_TEE" />
<xs:enumeration value="GUEST_FLAG_REE" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="GuestFlagsInfo">
<xs:sequence>
<xs:element name="guest_flag" type="GuestFlagsOptionsType" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Select all applicable flags for the VM.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:assert test="count(guest_flag[text() = 'GUEST_FLAG_NVMX_ENABLED']) = 0 or count(guest_flag[text() = 'GUEST_FLAG_LAPIC_PASSTHROUGH']) > 0">
<xs:annotation>
<xs:documentation>If the GUEST_FLAG_NVMX_ENABLED is set, GUEST_FLAG_LAPIC_PASSTHROUGH must be set as well.</xs:documentation>
</xs:annotation>
</xs:assert>
</xs:complexType>
<xs:complexType name="CPUAffinityConfiguration">
<xs:sequence>
<xs:element name="pcpu_id" type="xs:integer" default="2" maxOccurs="unbounded">
@ -100,11 +52,11 @@ to.</xs:documentation>
<xs:sequence>
<xs:element name="vcpu_clos" type="xs:integer" default="0" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>By default (``GUEST_FLAG_VCAT_ENABLED`` is not specified):
<xs:documentation>By default (``virtual_cat_support`` 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:
If ``virtual_cat_support`` 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>

View File

@ -119,11 +119,6 @@ support RDT or CDP, setting this option to ``y`` is ignored.</xs:documentation>
<xs:documentation>Enable Hyper-V.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="NVMX_ENABLED" type="Boolean" default="n">
<xs:annotation>
<xs:documentation>Enable nested virtualization.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="IOMMU_ENFORCE_SNP" type="Boolean" default="n">
<xs:annotation>
<xs:documentation>Specify if the IOMMU enforces snoop behavior
@ -159,7 +154,6 @@ Machine Check Error on Page Size Change.</xs:documentation>
</xs:element>
</xs:all>
<xs:assert test="not (RDT/RDT_ENABLED = 'y' and SSRAM/SSRAM_ENABLED = 'y')"/>
<xs:assert test="not (NVMX_ENABLED = 'y' and not (SCHEDULER = 'SCHED_NOOP'))"/>
</xs:complexType>
<xs:complexType name="MemoryOptionsType">
@ -329,9 +323,39 @@ hypervisor console ``vm_list`` command.</xs:documentation>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="guest_flags" type="GuestFlagsInfo" minOccurs="0">
<xs:annotation acrn:multiselect="y">
<xs:documentation>Select all applicable flags for the VM.</xs:documentation>
<xs:element name="lapic_passthrough" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify LAPIC to passthrough.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="io_completion_polling" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify Polling mode for IO Completion.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="nested_virtualization_support" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify nested virtualization support for KVM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="virtual_cat_support" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify virtual CAT support for VM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="secure_world_support" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify secure world support for trustry OS.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="hide_mtrr_support" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify MTRR capability to hide for VM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="security_vm" type="Boolean" default="n" minOccurs="0">
<xs:annotation>
<xs:documentation>Specify TPM2 FIXUP for VM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="cpu_affinity" type="CPUAffinityConfiguration" minOccurs="0">
@ -417,9 +441,9 @@ its ``id`` attribute. When it is enabled, specify which target VM's vUART the cu
</xs:all>
<xs:attribute name="id" type="xs:integer" />
<xs:assert test="load_order != 'SERVICE_VM' or count(guest_flags[guest_flag = 'GUEST_FLAG_LAPIC_PASSTHROUGH']) = 0 or count(guest_flags[guest_flag = 'GUEST_FLAG_NVMX_ENABLED']) > 0">
<xs:assert test="load_order != 'SERVICE_VM' or count(//lapic_passthrough[text() = 'y']) = 0 or count(//nested_virtualization_support[text() = 'y']) > 0">
<xs:annotation>
<xs:documentation>Service VM cannot use LAPIC passthrough unless GUEST_FLAG_NVMX_ENABLED is set.</xs:documentation>
<xs:documentation>Service VM cannot use LAPIC passthrough unless nested_virtualization_support is set.</xs:documentation>
</xs:annotation>
</xs:assert>
</xs:complexType>
@ -446,12 +470,6 @@ to launch post-launched User VMs.</xs:documentation>
<xs:attribute name="board" type="xs:string" use="required" />
<xs:attribute name="scenario" type="xs:string" use="required" />
<xs:assert test="count(//guest_flag[text() = 'GUEST_FLAG_NVMX_ENABLED']) = 0 or //NVMX_ENABLED = 'y'">
<xs:annotation>
<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()">
@ -460,17 +478,17 @@ to launch post-launched User VMs.</xs:documentation>
</xs:annotation>
</xs:assert>
<xs:assert test="if (count(//guest_flag[text() = 'GUEST_FLAG_VCAT_ENABLED']) > 0)
<xs:assert test="if (count(//virtual_cat_support[text() = 'y']) > 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:documentation>Per VM virtual_cat_support 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'])
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and $vm/virtual_cat_support[text() = 'y'])
then count($vm/clos/vcpu_clos) > 1
else true()
)
@ -481,7 +499,7 @@ to launch post-launched User VMs.</xs:documentation>
</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
then count(vm[virtual_cat_support[text() = 'y'] 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>
@ -490,7 +508,7 @@ to launch post-launched User VMs.</xs:documentation>
<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'])
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and $vm/virtual_cat_support[text() = 'y'])
then count($vm[clos/vcpu_clos[. &gt;= count($vm/..//CLOS_MASK)]]) = 0
else true()
)
@ -502,7 +520,7 @@ to launch post-launched User VMs.</xs:documentation>
<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'])
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and $vm/virtual_cat_support[text() = 'y'])
then count($vm/clos/vcpu_clos) = count(distinct-values($vm/clos/vcpu_clos))
else true()
)
@ -514,7 +532,7 @@ to launch post-launched User VMs.</xs:documentation>
<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']))
if (//RDT_ENABLED = 'y' and //VCAT_ENABLED = 'y' and ($vm1/virtual_cat_support[text() = 'y'] or $vm2/virtual_cat_support[text() = 'y']))
then count($vm1/clos/vcpu_clos[. = $vm2/clos/vcpu_clos]) = 0
else true()
)

View File

@ -0,0 +1,38 @@
#!/usr/bin/env python3
#
# Copyright (C) 2022 Intel Corporation.
#
# SPDX-License-Identifier: BSD-3-Clause
#
import sys, os, re
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'library'))
import common, lib.error, lib.lib
from collections import namedtuple
class GuestFlagPolicy(namedtuple("GuestFlagPolycy", ["condition", "guest_flag"])):
pass
policies = [
GuestFlagPolicy(".//lapic_passthrough = 'y'", "GUEST_FLAG_LAPIC_PASSTHROUGH"),
GuestFlagPolicy(".//io_completion_polling = 'y'", "GUEST_FLAG_IO_COMPLETION_POLLING"),
GuestFlagPolicy(".//virtual_cat_support = 'y'", "GUEST_FLAG_VCAT_ENABLED"),
GuestFlagPolicy(".//secure_world_support = 'y'", "GUEST_FLAG_SECURE_WORLD_ENABLED"),
GuestFlagPolicy(".//hide_mtrr_support = 'y'", "GUEST_FLAG_HIDE_MTRR"),
GuestFlagPolicy(".//nested_virtualization_support = 'y'", "GUEST_FLAG_NVMX_ENABLED"),
GuestFlagPolicy(".//security_vm = 'y'", "GUEST_FLAG_SECURITY_VM"),
GuestFlagPolicy(".//vm_type = 'RTVM'", "GUEST_FLAG_RT"),
GuestFlagPolicy(".//vm_type = 'TEE'", "GUEST_FLAG_TEE"),
GuestFlagPolicy(".//vm_type = 'REE'", "GUEST_FLAG_REE"),
]
def fn(board_etree, scenario_etree, allocation_etree):
for vm_node in scenario_etree.xpath("//vm"):
vm_id = vm_node.get('id')
allocation_vm_node = common.get_node(f"/acrn-config/vm[@id = '{vm_id}']", allocation_etree)
if allocation_vm_node is None:
allocation_vm_node = common.append_node("/acrn-config/vm", None, allocation_etree, id = vm_id)
for policy in policies:
if vm_node.xpath(policy.condition):
common.append_node("./guest_flags/guest_flag", str(policy.guest_flag), allocation_vm_node)
common.append_node("./guest_flags/guest_flag",'GUEST_FLAG_STATIC_VM', allocation_vm_node)

View File

@ -150,13 +150,13 @@ def alloc_device_irqs(board_etree, scenario_etree, allocation_etree):
device_nodes.discard(device_node)
# Raise error when any pre-launched VM with LAPIC passthrough requires any interrupt line.
lapic_passthru_flag = common.get_node("guest_flags[guest_flag='GUEST_FLAG_LAPIC_PASSTHROUGH']", vm)
lapic_passthru_flag = common.get_node("lapic_passthrough[text() = 'y']", vm)
if lapic_passthru_flag is not None and irq_allocation[vm_id]:
for irq, devices in irq_allocation[vm_id].items():
print(f"Interrupt line {irq} is used by the following device(s).")
for device in devices:
print(f"\t{device}")
raise lib.error.ResourceError(f"Pre-launched VM {vm_id} with LAPIC_PASSTHROUGH flag cannot use interrupt lines.")
raise lib.error.ResourceError(f"Pre-launched VM {vm_id} with lapic_passthrough flag cannot use interrupt lines.")
elif lib.lib.is_service_vm(load_order):
service_vm_id = vm_id

View File

@ -54,11 +54,17 @@
<xsl:param name="value" />
<xsl:choose>
<xsl:when test="($value = 'y') or ($key = 'RELEASE')">
<xsl:when test="($value = 'true') or ($value = 'y')">
<xsl:call-template name="entry-by-key-value">
<xsl:with-param name="key" select="$key" />
<xsl:with-param name="value" select="'y'" />
</xsl:call-template>
</xsl:when>
<xsl:when test="($key = 'RELEASE')">
<xsl:call-template name="entry-by-key-value">
<xsl:with-param name="key" select="$key" />
<xsl:with-param name="value" select="$value" />
</xsl:call-template>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:text># CONFIG_</xsl:text>

View File

@ -116,8 +116,9 @@
<xsl:with-param name="key" select="'HYPERV_ENABLED'" />
</xsl:call-template>
<xsl:call-template name="boolean-by-key">
<xsl:call-template name="boolean-by-key-value">
<xsl:with-param name="key" select="'NVMX_ENABLED'" />
<xsl:with-param name="value" select="count(//vm[nested_virtualization_support = 'y']) > 0" />
</xsl:call-template>
<xsl:call-template name="boolean-by-key">

View File

@ -91,7 +91,7 @@
</xsl:if>
<xsl:value-of select="acrn:initializer('vm_prio', priority)" />
<xsl:value-of select="acrn:initializer('companion_vm_id', concat(companion_vmid, 'U'))" />
<xsl:apply-templates select="guest_flags" />
<xsl:call-template name="guest_flags" />
<xsl:if test="acrn:is-rdt-enabled()">
<xsl:apply-templates select="clos" />
@ -156,17 +156,9 @@
</xsl:choose>
</xsl:template>
<xsl:template match="guest_flags">
<xsl:if test="guest_flag">
<xsl:choose>
<xsl:when test="guest_flag = '' or guest_flag = '0' or guest_flag = '0UL'">
<xsl:value-of select="acrn:initializer('guest_flags', 'GUEST_FLAG_STATIC_VM')" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="acrn:initializer('guest_flags', concat('(GUEST_FLAG_STATIC_VM|', acrn:string-join(guest_flag, '|', '', ''),')'))" />
</xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:template name="guest_flags">
<xsl:variable name="vm_id" select="@id" />
<xsl:value-of select="acrn:initializer('guest_flags', concat('(', acrn:string-join(//allocation-data/acrn-config/vm[@id=$vm_id]/guest_flags/guest_flag, '|', '', ''),')'))" />
</xsl:template>
<xsl:template match="clos">
@ -175,7 +167,7 @@
<xsl:value-of select="acrn:initializer('num_pclosids', concat(count(vcpu_clos), 'U'))" />
<xsl:if test="acrn:is-vcat-enabled() and ../guest_flags[guest_flag = 'GUEST_FLAG_VCAT_ENABLED']">
<xsl:if test="acrn:is-vcat-enabled() and ../virtual_cat_support[text() = 'y']">
<xsl:variable name="rdt_res_str" select="acrn:get-normalized-closinfo-rdt-res-str()" />
<xsl:variable name="closid" select="vcpu_clos[1]" />