config_tools: add ivshmem providers

A shared memory region can be provided either by the hypervisor or by the
device model. Before recent schema changes this is telled by the "hv:/" or
"dm:/" prefix.

This patch adds another node under an IVSHMEM region to represent the
provider, following the practice that information in the old-school
encodings is split and put as separate XML nodes.

Tracked-On: #6690
Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
Junjie Mao 2022-03-02 17:13:12 +08:00 committed by acrnsi-robot
parent 609e09cf37
commit f392164b40
10 changed files with 73 additions and 35 deletions

View File

@ -25,7 +25,9 @@
<L1D_VMENTRY_ENABLED>n</L1D_VMENTRY_ENABLED>
<MCE_ON_PSC_DISABLED>n</MCE_ON_PSC_DISABLED>
<IVSHMEM>
<IVSHMEM_REGION name="shm_region_0">
<IVSHMEM_REGION>
<NAME>shm_region_0</NAME>
<PROVIDED_BY>Hypervisor</PROVIDED_BY>
<IVSHMEM_SIZE>2</IVSHMEM_SIZE>
<IVSHMEM_VMS>
<IVSHMEM_VM>

View File

@ -38,7 +38,9 @@
<L1D_VMENTRY_ENABLED>n</L1D_VMENTRY_ENABLED>
<MCE_ON_PSC_DISABLED>n</MCE_ON_PSC_DISABLED>
<IVSHMEM>
<IVSHMEM_REGION name="shm_region_0">
<IVSHMEM_REGION>
<NAME>shm_region_0</NAME>
<PROVIDED_BY>Hypervisor</PROVIDED_BY>
<IVSHMEM_SIZE>2</IVSHMEM_SIZE>
<IVSHMEM_VMS>
<IVSHMEM_VM>

View File

@ -25,7 +25,9 @@
<L1D_VMENTRY_ENABLED>n</L1D_VMENTRY_ENABLED>
<MCE_ON_PSC_DISABLED>n</MCE_ON_PSC_DISABLED>
<IVSHMEM>
<IVSHMEM_REGION name="shm_region_0">
<IVSHMEM_REGION>
<NAME>shm_region_0</NAME>
<PROVIDED_BY>Hypervisor</PROVIDED_BY>
<IVSHMEM_SIZE>2</IVSHMEM_SIZE>
<IVSHMEM_VMS>
<IVSHMEM_VM>

View File

@ -124,12 +124,14 @@ class VirtualUartConnections:
return [new_parent_node]
class SharedMemoryRegions:
class SharedMemoryRegion(namedtuple("SharedMemoryRegion", ["name", "size", "shared_vms"])):
class SharedMemoryRegion(namedtuple("SharedMemoryRegion", ["provided_by", "name", "size", "shared_vms"])):
# The BDF of IVSHMEM PCI functions starts from 00:08.0
next_dev = defaultdict(lambda: 8)
nr_regions = 0
@classmethod
def from_hypervisor_encoding(cls, text, old_xml_etree):
def from_encoding(cls, text, old_xml_etree):
provided_by = "Device Model" if text.startswith("dm:/") else "Hypervisor"
parts = [p.strip() for p in text[text.find("/") + 1 :].split(",")]
name = parts[0]
size = parts[1]
@ -147,22 +149,27 @@ class SharedMemoryRegions:
cls.next_dev[vm_name] += 1
shared_vms.append((vm_name, f"00:{dev:02x}.0"))
return cls(name, size, shared_vms)
return cls(provided_by, name, size, shared_vms)
@classmethod
def from_xml_node(cls, node):
name = node.get("name")
cls.nr_regions += 1
name = node.get("name") if "name" in node.keys() else \
node.find("NAME").text if node.find("NAME") is not None else \
f"shared_memory_region_{nr_regions}"
provided_by = node.find("PROVIDED_BY").text if node.find("PROVIDED_BY") is not None else "Hypervisor"
size = node.find("IVSHMEM_SIZE").text
shared_vms = []
for shared_vm_node in node.find("IVSHMEM_VMS"):
vm_name = shared_vm_node.find("VM_NAME").text
vbdf = shared_vm_node.find("VBDF").text
shared_vms.append((vm_name, vbdf))
return cls(name, size, shared_vms)
return cls(provided_by, name, size, shared_vms)
def format_xml_element(self):
node = etree.Element("IVSHMEM_REGION")
node.set("name", self.name)
etree.SubElement(node, "NAME").text = self.name
etree.SubElement(node, "PROVIDED_BY").text = self.provided_by
etree.SubElement(node, "IVSHMEM_SIZE").text = self.size
vms_node = etree.SubElement(node, "IVSHMEM_VMS")
@ -182,7 +189,7 @@ class SharedMemoryRegions:
if len(ivshmem_region_node) == 0:
# ACRN v2.x format
region = self.SharedMemoryRegion.from_hypervisor_encoding(ivshmem_region_node.text, self.old_xml_etree)
region = self.SharedMemoryRegion.from_encoding(ivshmem_region_node.text, self.old_xml_etree)
self.regions[region.name] = region
else:
# ACRN v3.x format

View File

@ -1,5 +1,7 @@
<?xml version="1.0"?>
<xs:schema xml:id="root" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:schema xml:id="root"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:acrn="https://projectacrn.org">
<xs:simpleType name="Boolean">
<xs:annotation>
@ -152,7 +154,7 @@ Read more about the available scheduling options in :ref:`cpu_sharing`.</xs:docu
<xs:simpleType name="VMNameType">
<xs:restriction base="xs:string">
<xs:pattern value="([a-zA-Z0-9_\-]){1,15}" />
</xs:restriction>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="VBDFType">
@ -161,10 +163,17 @@ Read more about the available scheduling options in :ref:`cpu_sharing`.</xs:docu
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="ProviderType">
<xs:restriction base="xs:string">
<xs:enumeration value="Hypervisor" />
<xs:enumeration value="Device Model" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="IVSHMEMVM">
<xs:sequence>
<xs:element name="VM_NAME" type="VMNameType">
<xs:annotation>
<xs:annotation>
<xs:documentation>Name of the VM which use this IVSHMEM.</xs:documentation>
</xs:annotation>
</xs:element>
@ -202,21 +211,35 @@ device in VM . Set in hex.</xs:documentation>
</xs:simpleType>
<xs:complexType name="IVSHMEMRegionType">
<xs:sequence>
<xs:all>
<xs:element name="NAME">
<xs:annotation acrn:title="Name">
<xs:documentation>Name of the shared memory region.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="\w+" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="PROVIDED_BY" type="ProviderType" default="Hypervisor">
<xs:annotation acrn:title="Emulated by">
<xs:documentation>Whether the shared memory region is emulated by the hypervisor or device model.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="IVSHMEM_SIZE" type="IVSHMEMSize" default="2">
<xs:annotation>
<xs:annotation acrn:title="Size">
<xs:documentation>Memory size of inter-VM shared memory (IVSHMEM)
in megabytes. The value should be a power of 2
and no more than 512.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="IVSHMEM_VMS" type="IVSHMEMVMS">
<xs:annotation>
<xs:annotation acrn:title="Shared VMs">
<xs:documentation>Set all VMs which use this IVSHMEM.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:all>
</xs:complexType>
<xs:complexType name="IVSHMEMInfo">

View File

@ -97,7 +97,10 @@ def get_ivshmem_regions_by_tree(etree):
ivshmem_regions = etree.xpath("//IVSHMEM_REGION")
shmem_regions = {}
for idx in range(len(ivshmem_regions)):
shm_name = ivshmem_regions[idx].get('name')
provided_by = common.get_node("./PROVIDED_BY/text()", ivshmem_regions[idx])
if provided_by != "Hypervisor":
continue
shm_name = common.get_node("./NAME/text()", ivshmem_regions[idx])
if shm_name is None:
continue
shm_size = common.get_node("./IVSHMEM_SIZE/text()", ivshmem_regions[idx])
@ -117,7 +120,7 @@ def get_ivshmem_enabled_by_tree(etree):
if len(ivshmem_vms) != 0:
shmem_enabled = 'y'
return shmem_enabled
def is_pre_launched_vm(vm_type):
if vm_type == 'PRE_LAUNCHED_VM':
return True

View File

@ -143,7 +143,7 @@
<xsl:call-template name="boolean-by-key-value">
<xsl:with-param name="key" select="'IVSHMEM_ENABLED'" />
<xsl:with-param name="value" select="count(//hv//IVSHMEM/IVSHMEM_REGION) > 0" />
<xsl:with-param name="value" select="count(//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']) > 0" />
</xsl:call-template>
</xsl:template>

13
misc/config_tools/xforms/ivshmem_cfg.h.xsl Executable file → Normal file
View File

@ -26,7 +26,7 @@
</xsl:template>
<xsl:template match="config-data/acrn-config">
<xsl:if test="count(//hv//IVSHMEM/IVSHMEM_REGION) > 0">
<xsl:if test="count(//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']) > 0">
<!-- Included headers -->
<xsl:value-of select="acrn:include('ivshmem.h')" />
<xsl:value-of select="acrn:include('asm/pgtable.h')" />
@ -39,9 +39,8 @@
</xsl:template>
<xsl:template name ="ivshmem_shm_region_name">
<xsl:for-each select="hv//IVSHMEM/IVSHMEM_REGION">
<xsl:variable name="region" select="@name" />
<xsl:value-of select="acrn:define(concat('IVSHMEM_SHM_REGION_', position() - 1), concat($quot, 'hv:/', $region, $quot), '')" />
<xsl:for-each select="hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']">
<xsl:value-of select="acrn:define(concat('IVSHMEM_SHM_REGION_', position() - 1), concat($quot, 'hv:/', NAME, $quot), '')" />
</xsl:for-each>
<xsl:value-of select="$newline" />
</xsl:template>
@ -49,12 +48,12 @@
<xsl:template name ="ivshmem_shm_mem">
<xsl:value-of select="acrn:comment('The IVSHMEM_SHM_SIZE is the sum of all memory regions. The size range of each memory region is [2MB, 512MB] and is a power of 2.')" />
<xsl:value-of select="$newline" />
<xsl:variable name="memsize" select="sum(//IVSHMEM_REGION/IVSHMEM_SIZE)" />
<xsl:variable name="memsize" select="sum(//IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']/IVSHMEM_SIZE)" />
<xsl:value-of select="acrn:define('IVSHMEM_SHM_SIZE', concat('0x', acrn:convert-num-base(string($memsize), 10, 16), '00000UL'))" />
</xsl:template>
<xsl:template match="IVSHMEM">
<xsl:variable name="dev" select="count(//hv//IVSHMEM/IVSHMEM_REGION/IVSHMEM_VMS/IVSHMEM_VM)" />
<xsl:variable name="dev" select="count(//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']/IVSHMEM_VMS/IVSHMEM_VM)" />
<xsl:value-of select="acrn:define('IVSHMEM_DEV_NUM', string($dev), 'UL')" />
</xsl:template>
@ -62,7 +61,7 @@
<xsl:value-of select="acrn:comment('All user defined memory regions')" />
<xsl:value-of select="$newline" />
<xsl:value-of select="acrn:define('IVSHMEM_SHM_REGIONS', '', ' \')" />
<xsl:for-each select="hv//IVSHMEM/IVSHMEM_REGION">
<xsl:for-each select="hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']">
<xsl:if test="text()">
<xsl:variable name="memsize" select="IVSHMEM_SIZE" />
<xsl:text>{ \</xsl:text>

View File

@ -307,8 +307,8 @@
<func:function name="acrn:shmem-index">
<xsl:param name="v" />
<xsl:variable name="idx">
<xsl:for-each select="//hv//IVSHMEM/IVSHMEM_REGION">
<xsl:if test="@name = $v">
<xsl:for-each select="//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']">
<xsl:if test="NAME = $v">
<xsl:value-of select="position() - 1" />
</xsl:if>
</xsl:for-each>
@ -322,9 +322,9 @@
<xsl:variable name="vmtype" select="./load_order" />
<xsl:variable name="ivshmem">
<xsl:choose>
<xsl:when test="count(//hv//IVSHMEM/IVSHMEM_REGION) > 0">
<xsl:when test="count(//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']) > 0">
<xsl:variable name="vm_name" select="./name" />
<xsl:value-of select="count(//hv//IVSHMEM/IVSHMEM_REGION/IVSHMEM_VMS/IVSHMEM_VM/VM_NAME[text() = $vm_name])" />
<xsl:value-of select="count(//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']/IVSHMEM_VMS/IVSHMEM_VM/VM_NAME[text() = $vm_name])" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0" />

View File

@ -143,7 +143,7 @@
<xsl:variable name="vm_id" select="@id" />
<xsl:variable name="vm_name" select="name" />
<xsl:variable name="load_order" select="load_order" />
<xsl:for-each select="//hv//IVSHMEM/IVSHMEM_REGION/IVSHMEM_VMS/IVSHMEM_VM[VM_NAME = $vm_name]">
<xsl:for-each select="//hv//IVSHMEM/IVSHMEM_REGION[PROVIDED_BY = 'Hypervisor']/IVSHMEM_VMS/IVSHMEM_VM[VM_NAME = $vm_name]">
<xsl:text>{</xsl:text>
<xsl:value-of select="$newline" />
<xsl:value-of select="acrn:initializer('emu_type', 'PCI_DEV_TYPE_HVEMUL', '')" />
@ -153,14 +153,14 @@
<xsl:value-of select="acrn:initializer('vbdf.value', 'UNASSIGNED_VBDF', '')" />
</xsl:when>
<xsl:otherwise>
<xsl:variable name="dev_name" select="concat('IVSHMEM_', acrn:shmem-index(../../@name))" />
<xsl:variable name="dev_name" select="concat('IVSHMEM_', acrn:shmem-index(ancestor::IVSHMEM_REGION/NAME))" />
<xsl:value-of select="acrn:initializer('vbdf.bits', acrn:get-vbdf($vm_id, $dev_name), '')" />
<xsl:for-each select="//vm[@id = $vm_id]/device[@name = $dev_name]/bar">
<xsl:value-of select="acrn:initializer(concat('vbar_base[', @id,']'), concat(text(), 'UL'), '')" />
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="acrn:initializer('shm_region_name', concat('IVSHMEM_SHM_REGION_', acrn:shmem-index(../../@name)), '')" />
<xsl:value-of select="acrn:initializer('shm_region_name', concat('IVSHMEM_SHM_REGION_', acrn:shmem-index(ancestor::IVSHMEM_REGION/NAME)), '')" />
<xsl:text>},</xsl:text>
<xsl:value-of select="$newline" />
</xsl:for-each>