config tool: ivshmem: new design for ivshmem

According to the new design of DX, implement ivshmem configuration
and generate hv related files.

Tracked-On: #6690
Signed-off-by: Yuanyuan Zhao <yuanyuan.zhao@linux.intel.com>
Reviewed-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
Yuanyuan Zhao 2022-02-14 06:33:21 +00:00 committed by acrnsi-robot
parent 3d5c3c4754
commit 9670caabf0
8 changed files with 138 additions and 89 deletions

View File

@ -139,39 +139,83 @@ Read more about the available scheduling options in :ref:`cpu_sharing`.</xs:docu
<xs:union memberTypes="None SerialConsoleType" /> <xs:union memberTypes="None SerialConsoleType" />
</xs:simpleType> </xs:simpleType>
<xs:simpleType name="IVSHMEMRegionType"> <xs:simpleType name="VMNameType">
<xs:annotation>
<xs:documentation>Either empty or a string naming the shared region,
its size, and the VM IDs that can access it, such as ``hv:/shm_region_0, 2, 0:2``.
See :ref:`ivshmem-hv` for more information.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string"> <xs:restriction base="xs:string">
<xs:pattern value="|((hv)|(dm)):/\w+,\s?\d+\s?,\s?\d\s?(:\s?\d\s?)+" /> <xs:pattern value="([a-zA-Z0-9_\-]){1,15}" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="VBDFType">
<xs:restriction base="xs:string">
<xs:pattern value="[0-9A-Fa-f]{1,2}:[0-1][0-9A-Fa-f].[0-7]" />
</xs:restriction> </xs:restriction>
</xs:simpleType> </xs:simpleType>
<xs:complexType name="IVSHMEMVM">
<xs:sequence>
<xs:element name="VM_NAME" type="VMNameType">
<xs:annotation>
<xs:documentation>Name of the VM which use this IVSHMEM.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="VBDF" type = "VBDFType">
<xs:annotation>
<xs:documentation>Bus, Device and function of the virtual
device in VM . Set in hex.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="IVSHMEMVMS">
<xs:sequence>
<xs:element name="IVSHMEM_VM" type="IVSHMEMVM" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>Set each VM which use this IVSHMEM.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="IVSHMEMSize">
<xs:restriction base="xs:integer">
<xs:enumeration value="2" />
<xs:enumeration value="4" />
<xs:enumeration value="8" />
<xs:enumeration value="16" />
<xs:enumeration value="32" />
<xs:enumeration value="64" />
<xs:enumeration value="128" />
<xs:enumeration value="256" />
<xs:enumeration value="512" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="IVSHMEMRegionType">
<xs:sequence>
<xs:element name="IVSHMEM_SIZE" type="IVSHMEMSize" default="2">
<xs:annotation>
<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: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:complexType>
<xs:complexType name="IVSHMEMInfo"> <xs:complexType name="IVSHMEMInfo">
<xs:sequence> <xs:sequence>
<xs:element name="IVSHMEM_ENABLED" type="Boolean" default="n"> <xs:element name="IVSHMEM_REGION" type="IVSHMEMRegionType" minOccurs="0" maxOccurs="unbounded">
<xs:annotation> <xs:annotation>
<xs:documentation>Enable inter-VM shared memory (IVSHMEM) <xs:documentation>Set a inter-VM shared memory.</xs:documentation>
feature.</xs:documentation> </xs:annotation>
</xs:annotation> </xs:element>
</xs:element>
<xs:element name="IVSHMEM_REGION" type="IVSHMEMRegionType" maxOccurs="unbounded">
<xs:annotation>
<xs:documentation>A comma-separated list with the inter-VM shared memory region name,
size, and VM IDs that may communicate using this shared region:
* Prefix the region ``name`` with ``hv:/`` (for an hv-land solution).
(See :ref:`ivshmem-hld` for details.)
* Specify the region ``size`` in MB. Must be a power of 2, e.g., 2, 4,
8, 16, up to 512.
* Specify all VM IDs that may use this shared memory area,
separated by a ``:``. For example, use ``0:2`` to share this area between
VMs 0 and 2, or ``0:1:2`` (to let VMs 0, 1, and 2 share this area).</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence> </xs:sequence>
</xs:complexType> </xs:complexType>

View File

@ -38,14 +38,14 @@ def insert_vuart_to_dev_dict(scenario_etree, devdict, used):
used.append(free_bdf) used.append(free_bdf)
def insert_ivsheme_to_dev_dict(scenario_etree, devdict, vm_id, used): def insert_ivsheme_to_dev_dict(scenario_etree, devdict, vm_id, used):
shmem_regions = lib.lib.get_shmem_regions(scenario_etree) shmem_regions = lib.lib.get_ivshmem_regions_by_tree(scenario_etree)
if vm_id not in shmem_regions: if vm_id not in shmem_regions:
return return
shmems = shmem_regions.get(vm_id) shmems = shmem_regions.get(vm_id)
for shm in shmems.values(): for shm in shmems.values():
free_bdf = find_unused_bdf(used) bdf = lib.lib.BusDevFunc.from_str(shm.get('vbdf'))
devdict[f"{IVSHMEM}_{shm.get('id')}"] = free_bdf devdict[f"{IVSHMEM}_{shm.get('id')}"] = bdf
used.append(free_bdf) used.append(bdf)
def insert_pt_devs_to_dev_dict(vm_node_etree, devdict, used): def insert_pt_devs_to_dev_dict(vm_node_etree, devdict, used):
""" """

View File

@ -126,7 +126,7 @@ def insert_legacy_vuart_to_dev_dict(vm_node, devdict_io_port):
devdict_io_port[(f"{LEGACY_VUART}_{vuart_id}", "base")] = LEGACY_VUART_IO_PORT_SIZE devdict_io_port[(f"{LEGACY_VUART}_{vuart_id}", "base")] = LEGACY_VUART_IO_PORT_SIZE
def insert_ivsheme_to_dev_dict(scenario_etree, devdict_32bits, devdict_64bits, vm_id): def insert_ivsheme_to_dev_dict(scenario_etree, devdict_32bits, devdict_64bits, vm_id):
shmem_regions = lib.lib.get_shmem_regions(scenario_etree) shmem_regions = lib.lib.get_ivshmem_regions_by_tree(scenario_etree)
if vm_id not in shmem_regions: if vm_id not in shmem_regions:
return return
shmems = shmem_regions.get(vm_id) shmems = shmem_regions.get(vm_id)

View File

@ -89,29 +89,35 @@ def get_native_ttys():
native_ttys[tty] = tmp_dic native_ttys[tty] = tmp_dic
return native_ttys return native_ttys
def get_shmem_regions(etree): def get_ivshmem_regions_by_tree(etree):
ivshmem_enabled = common.get_node("//IVSHMEM_ENABLED/text()", etree) ivshmem_enabled = get_ivshmem_enabled_by_tree(etree)
if ivshmem_enabled == 'n': if ivshmem_enabled == 'n':
return {} return {}
# <IVSHMEM_REGION> format is shm_name, shm_size, VM IDs
# example: hv:/shm_region_0, 2, 0:2
ivshmem_regions = etree.xpath("//IVSHMEM_REGION") ivshmem_regions = etree.xpath("//IVSHMEM_REGION")
shmem_regions = {} shmem_regions = {}
for idx in range(len(ivshmem_regions)): for idx in range(len(ivshmem_regions)):
shm_string = ivshmem_regions[idx].text shm_name = ivshmem_regions[idx].get('name')
if shm_string is None: if shm_name is None:
continue continue
shm_string_list = shm_string.split(',') shm_size = common.get_node("./IVSHMEM_SIZE/text()", ivshmem_regions[idx])
shm_name = shm_string_list[0].strip() shm_vm_list = ivshmem_regions[idx].xpath(".//IVSHMEM_VM")
shm_size = shm_string_list[1].strip() for shm_vm in shm_vm_list:
vmid_list = [vm_id.strip() for vm_id in shm_string_list[2].split(':')] vm_name = common.get_node("./VM_NAME/text()", shm_vm)
for vm_id in vmid_list: vm_id = common.get_node(f"//vm[name = '{vm_name}']/@id", etree)
vbdf = common.get_node("./VBDF/text()", shm_vm)
if vm_id not in shmem_regions: if vm_id not in shmem_regions:
shmem_regions[vm_id] = {} shmem_regions[vm_id] = {}
shmem_regions[vm_id][shm_name] = {'id' : str(idx), 'size' : shm_size} shmem_regions[vm_id][shm_name] = {'id' : str(idx), 'size' : shm_size, 'vbdf' : vbdf}
return shmem_regions return shmem_regions
def get_ivshmem_enabled_by_tree(etree):
ivshmem_vms = etree.xpath("//IVSHMEM_VM")
shmem_enabled = 'n'
if len(ivshmem_vms) != 0:
shmem_enabled = 'y'
return shmem_enabled
def is_pre_launched_vm(vm_type): def is_pre_launched_vm(vm_type):
if vm_type in PRE_LAUNCHED_VMS_TYPE: if vm_type in PRE_LAUNCHED_VMS_TYPE:
return True return True

View File

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

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

@ -26,23 +26,22 @@
</xsl:template> </xsl:template>
<xsl:template match="config-data/acrn-config"> <xsl:template match="config-data/acrn-config">
<xsl:if test="./hv/FEATURES/IVSHMEM/IVSHMEM_ENABLED = 'y'"> <xsl:if test="count(//hv//IVSHMEM/IVSHMEM_REGION) > 0">
<!-- Included headers --> <!-- Included headers -->
<xsl:value-of select="acrn:include('ivshmem.h')" /> <xsl:value-of select="acrn:include('ivshmem.h')" />
<xsl:value-of select="acrn:include('asm/pgtable.h')" /> <xsl:value-of select="acrn:include('asm/pgtable.h')" />
<xsl:call-template name="ivshmem_shm_region_name" /> <xsl:call-template name="ivshmem_shm_region_name" />
<xsl:call-template name="ivshmem_shm_mem" /> <xsl:call-template name="ivshmem_shm_mem" />
<xsl:apply-templates select="hv/FEATURES/IVSHMEM" /> <xsl:apply-templates select="hv//IVSHMEM" />
<xsl:call-template name="ivshmem_shm_region" /> <xsl:call-template name="ivshmem_shm_region" />
</xsl:if> </xsl:if>
</xsl:template> </xsl:template>
<xsl:template name ="ivshmem_shm_region_name"> <xsl:template name ="ivshmem_shm_region_name">
<xsl:for-each select="hv/FEATURES/IVSHMEM/IVSHMEM_REGION"> <xsl:for-each select="hv//IVSHMEM/IVSHMEM_REGION">
<xsl:if test="text()"> <xsl:variable name="region" select="@name" />
<xsl:value-of select="acrn:define(concat('IVSHMEM_SHM_REGION_', position() - 1), concat($quot, substring-before(text(), ','), $quot), '')" /> <xsl:value-of select="acrn:define(concat('IVSHMEM_SHM_REGION_', position() - 1), concat($quot, 'hv:/', $region, $quot), '')" />
</xsl:if>
</xsl:for-each> </xsl:for-each>
<xsl:value-of select="$newline" /> <xsl:value-of select="$newline" />
</xsl:template> </xsl:template>
@ -50,21 +49,22 @@
<xsl:template name ="ivshmem_shm_mem"> <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="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:value-of select="$newline" />
<xsl:variable name="memsize" select="sum(dyn:map(//IVSHMEM_REGION, 'acrn:parse-shmem-size(.)'))" /> <xsl:variable name="memsize" select="sum(//IVSHMEM_REGION/IVSHMEM_SIZE)" />
<xsl:value-of select="acrn:define('IVSHMEM_SHM_SIZE', concat('0x', acrn:convert-num-base(string($memsize), 10, 16), '00000UL'))" /> <xsl:value-of select="acrn:define('IVSHMEM_SHM_SIZE', concat('0x', acrn:convert-num-base(string($memsize), 10, 16), '00000UL'))" />
</xsl:template> </xsl:template>
<xsl:template match="IVSHMEM"> <xsl:template match="IVSHMEM">
<xsl:value-of select="acrn:define('IVSHMEM_DEV_NUM', sum(dyn:map(//IVSHMEM_REGION, 'acrn:count-shmem-dev-num(.)')), 'UL')" /> <xsl:variable name="dev" select="count(//hv//IVSHMEM/IVSHMEM_REGION/IVSHMEM_VMS/IVSHMEM_VM)" />
<xsl:value-of select="acrn:define('IVSHMEM_DEV_NUM', string($dev), 'UL')" />
</xsl:template> </xsl:template>
<xsl:template name ="ivshmem_shm_region"> <xsl:template name ="ivshmem_shm_region">
<xsl:value-of select="acrn:comment('All user defined memory regions')" /> <xsl:value-of select="acrn:comment('All user defined memory regions')" />
<xsl:value-of select="$newline" /> <xsl:value-of select="$newline" />
<xsl:value-of select="acrn:define('IVSHMEM_SHM_REGIONS', '', ' \')" /> <xsl:value-of select="acrn:define('IVSHMEM_SHM_REGIONS', '', ' \')" />
<xsl:for-each select="hv/FEATURES/IVSHMEM/IVSHMEM_REGION"> <xsl:for-each select="hv//IVSHMEM/IVSHMEM_REGION">
<xsl:if test="text()"> <xsl:if test="text()">
<xsl:variable name="memsize" select="acrn:parse-shmem-size(text())" /> <xsl:variable name="memsize" select="IVSHMEM_SIZE" />
<xsl:text>{ \</xsl:text> <xsl:text>{ \</xsl:text>
<xsl:value-of select="$newline" /> <xsl:value-of select="$newline" />
<xsl:value-of select="acrn:initializer('name', concat('IVSHMEM_SHM_REGION_', position() - 1, ', \'), true())" /> <xsl:value-of select="acrn:initializer('name', concat('IVSHMEM_SHM_REGION_', position() - 1, ', \'), true())" />

View File

@ -304,17 +304,16 @@
</func:function> </func:function>
<!-- End of C code templates--> <!-- End of C code templates-->
<!-- Scenario-specific functions--> <func:function name="acrn:shmem-index">
<func:function name="acrn:parse-shmem-size">
<xsl:param name="v" /> <xsl:param name="v" />
<xsl:if test="$v and $v != 'n' and $v != 'y'"> <xsl:variable name="idx">
<func:result select="acrn:string-to-num(substring-before(substring-after($v, ','), ','), 10)" /> <xsl:for-each select="//hv//IVSHMEM/IVSHMEM_REGION">
</xsl:if> <xsl:if test="@name = $v">
</func:function> <xsl:value-of select="position() - 1" />
</xsl:if>
<func:function name="acrn:count-shmem-dev-num"> </xsl:for-each>
<xsl:param name="v" /> </xsl:variable>
<func:result select="string-length($v) - string-length(translate($v, ':', ''))" /> <func:result select="$idx" />
</func:function> </func:function>
<func:function name="acrn:pci-dev-num"> <func:function name="acrn:pci-dev-num">
@ -323,8 +322,9 @@
<xsl:variable name="vmtype" select="./vm_type" /> <xsl:variable name="vmtype" select="./vm_type" />
<xsl:variable name="ivshmem"> <xsl:variable name="ivshmem">
<xsl:choose> <xsl:choose>
<xsl:when test="../hv/FEATURES/IVSHMEM/IVSHMEM_ENABLED = 'y'"> <xsl:when test="count(//hv//IVSHMEM/IVSHMEM_REGION) > 0">
<xsl:value-of select="count(../hv/FEATURES/IVSHMEM/IVSHMEM_REGION[contains(substring-after(substring-after(text(), ','), ','), $vmid)])" /> <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:when> </xsl:when>
<xsl:otherwise> <xsl:otherwise>
<xsl:value-of select="0" /> <xsl:value-of select="0" />

View File

@ -141,29 +141,28 @@
<xsl:template name="ivshmem_shm_mem"> <xsl:template name="ivshmem_shm_mem">
<xsl:variable name="vm_id" select="@id" /> <xsl:variable name="vm_id" select="@id" />
<xsl:variable name="vm_name" select="name" />
<xsl:variable name="vm_type" select="vm_type" /> <xsl:variable name="vm_type" select="vm_type" />
<xsl:for-each select="//hv/FEATURES/IVSHMEM/IVSHMEM_REGION/text()"> <xsl:for-each select="//hv//IVSHMEM/IVSHMEM_REGION/IVSHMEM_VMS/IVSHMEM_VM[VM_NAME = $vm_name]">
<xsl:if test="contains(substring-after(substring-after(current(), ','), ','), $vm_id)"> <xsl:text>{</xsl:text>
<xsl:variable name="dev_name" select="concat('IVSHMEM_', position() - 1)" /> <xsl:value-of select="$newline" />
<xsl:text>{</xsl:text> <xsl:value-of select="acrn:initializer('emu_type', 'PCI_DEV_TYPE_HVEMUL', '')" />
<xsl:value-of select="$newline" /> <xsl:value-of select="acrn:initializer('vdev_ops', '&amp;vpci_ivshmem_ops', '')" />
<xsl:value-of select="acrn:initializer('emu_type', 'PCI_DEV_TYPE_HVEMUL', '')" /> <xsl:choose>
<xsl:value-of select="acrn:initializer('vdev_ops', '&amp;vpci_ivshmem_ops', '')" /> <xsl:when test="acrn:is-post-launched-vm($vm_type)">
<xsl:choose> <xsl:value-of select="acrn:initializer('vbdf.value', 'UNASSIGNED_VBDF', '')" />
<xsl:when test="acrn:is-post-launched-vm($vm_type)"> </xsl:when>
<xsl:value-of select="acrn:initializer('vbdf.value', 'UNASSIGNED_VBDF', '')" /> <xsl:otherwise>
</xsl:when> <xsl:variable name="dev_name" select="concat('IVSHMEM_', acrn:shmem-index(../../@name))" />
<xsl:otherwise> <xsl:value-of select="acrn:initializer('vbdf.bits', acrn:get-vbdf($vm_id, $dev_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: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:value-of select="acrn:initializer(concat('vbar_base[', @id,']'), concat(text(), 'UL'), '')" /> </xsl:for-each>
</xsl:for-each> </xsl:otherwise>
</xsl:otherwise> </xsl:choose>
</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_', position() - 1), '')" /> <xsl:text>},</xsl:text>
<xsl:text>},</xsl:text> <xsl:value-of select="$newline" />
<xsl:value-of select="$newline" />
</xsl:if>
</xsl:for-each> </xsl:for-each>
</xsl:template> </xsl:template>