Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@ export default {

let postVerification = await this.verifyBDFCollision(this.board, this.scenario)
console.log('postVerification: ',postVerification)
/*
if(!postVerification){
let all_errors = configurator.pythonObject.validateScenario(this.board.content, scenarioXMLData)
console.log(all_errors)
Expand All @@ -503,6 +504,7 @@ export default {
}
//i have not find the place to show error messages which is not satisfied with regex yet, i place the error messages in console now
}
*/

this.scenario.vm.map((vmConfig) => {
if (vmConfig['load_order'] === 'POST_LAUNCHED_VM') {
Expand Down
231 changes: 145 additions & 86 deletions misc/config_tools/configurator/pyodide/verifyBDFCollision.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@
from .pyodide import convert_result, nuc11_board, nuc11_scenario


def validate_load_order(base, name, vbdf):
vms = base.xpath('vm')
for vm in vms:
vm_name = vm.xpath('name/text()')[0].strip()
load_order = vm.xpath('load_order/text()')[0].strip()
if vm_name == name and load_order != 'POST_LAUNCHED_VM':
return True
elif vm_name == name and load_order == 'POST_LAUNCHED_VM':
check_ = lambda x: True if (t := int('0x' + x[3:5], 16)) >= 3 and t < 31 else False # 3,1e
return check_(vbdf)


def validate_(bdf):
pat = re.compile(r"([0-9a-fA-F]{1,2}:[0-1][0-9A-Fa-f]\.[0-7]).*")
if (m := re.search(pat, bdf.strip())) and (m1 := m.group(1).strip()):
Expand All @@ -22,93 +34,140 @@ def validate_(bdf):
return ""


def _valid(scenario_etree, bdfs):
vuart_vbdf = scenario_etree.xpath('/acrn-config/hv/DEBUG_OPTIONS/VUART_VBDF/text()')[0].strip()
vuart_vbdf_ = validate_(vuart_vbdf)
return True if bdfs and vuart_vbdf_ and vuart_vbdf_ not in bdfs else False


def validate_pci(board, scenario):
if board.startswith('<?xml version'):
board = '\n'.join(board.split('\n')[1:])
board_etree = etree.fromstring(board)

if scenario.startswith('<?xml version'):
scenario = '\n'.join(scenario.split('\n')[1:])
scenario_etree = etree.fromstring(scenario)

pci_devs_total = board_etree.xpath('/acrn-config/PCI_DEVICE/text()')[0].split('\n')
vbdfs = []
for pci in pci_devs_total:
if not pci:
continue
if m1 := validate_(pci):
if m1.startswith('00:00.0'):
class VBDFValidator:
def __init__(self, board, scenario):
if board.startswith('<?xml version'):
board = '\n'.join(board.split('\n')[1:])
self.board = etree.fromstring(board)
if scenario.startswith('<?xml version'):
scenario = '\n'.join(scenario.split('\n')[1:])
self.scenario = etree.fromstring(scenario)

self.native_ = []
self.vuart_vbdfs = []
self.ivshmem_vbdfs = []

@property
def scenario_root(self):
return self.scenario.xpath('/acrn-config')[0]

@property
def native(self):
pci_devs_total = _board[0].split('\n') if (
_board := self.board.xpath('/acrn-config/PCI_DEVICE/text()')) else []
for pci in pci_devs_total:
if not pci:
continue
vbdfs.append(m1)

return _valid(scenario_etree, vbdfs)


def validate_vuart(scenario):
vbdfs = []
if scenario.startswith('<?xml version'):
scenario = '\n'.join(scenario.split('\n')[1:])
scenario_etree = etree.fromstring(scenario)
vuart_vbdf_list = scenario_etree.xpath('/acrn-config/hv/vuart_connections/vuart_connection')
if not vuart_vbdf_list:
return
for vuart in vuart_vbdf_list:
p = vuart.xpath('endpoint')
from_, to_ = validate_(p[0].xpath('vbdf/text()')[0].strip()), validate_(p[1].xpath('vbdf/text()')[0].strip())
if from_ and to_:
vbdfs.append(from_)
vbdfs.append(to_)

return _valid(scenario_etree, vbdfs)


def validate_ivshmem(scenario):
vbdfs = []
if scenario.startswith('<?xml version'):
scenario = '\n'.join(scenario.split('\n')[1:])
scenario_etree = etree.fromstring(scenario)
ivshmem_vbdf_list = scenario_etree.xpath('/acrn-config/hv/FEATURES/IVSHMEM')
if not ivshmem_vbdf_list:
return
for ivshmem in ivshmem_vbdf_list:
p = ivshmem.xpath('//IVSHMEM_VMS/IVSHMEM_VM')
from_, to_ = validate_(p[0].xpath('VBDF/text()')[0].strip()), validate_(p[1].xpath('VBDF/text()')[0].strip())
if from_ and to_:
vbdfs.append(from_)
vbdfs.append(to_)

return _valid(scenario_etree, vbdfs)


def validate(board, scenario):
pci_result = validate_pci(board, scenario)
vuart_result = validate_vuart(scenario)
ivshmem_result = validate_ivshmem(scenario)
result = {
'pci': pci_result,
'vuart': vuart_result,
'ivshmem': ivshmem_result
}
if vuart_result is None:
del result['vuart']
if ivshmem_result is None:
del result['ivshmem']

print(result)
ret = True
for k, v in result.items():
ret = ret and v
result = {'result': ret}
return convert_result(result)


main = validate
if m1 := validate_(pci):
if m1.startswith('00:00.0'):
continue
self.native_.append(m1)
return self.native_

@property
def vuart_vbdf(self):
_scenario = self.scenario_root.xpath('hv/DEBUG_OPTIONS/VUART_VBDF/text()')
vuart_vbdf_validated = ''
if _scenario:
vuart_vbdf = _scenario[0].strip()
vuart_vbdf_validated = validate_(vuart_vbdf)
bdfs = [vuart_vbdf_validated] if _scenario else []
return bdfs

def validate_native(self, bdfs):
return not set(bdfs) & set(self.native)

def valid_vuart_vbdf(self, bdfs):
return not set(bdfs) & set(self.vuart_vbdf)

def validate_pci(self):
return self.valid_vuart_vbdf(self.native)

def validate_vuart(self):
vuart_connections_list = self.scenario_root.xpath('hv/vuart_connections/vuart_connection') # ***
if not vuart_connections_list:
return
vm_cfg = {}
for conn in vuart_connections_list:
endpoints = conn.xpath('endpoint')
for p in endpoints:
vm_name = p.xpath('vm_name/text()')[0].strip()
vm_vbdf = validate_(p.xpath('vbdf/text()')[0].strip())

if not validate_load_order(self.scenario_root, vm_name, vm_vbdf):
return False
else:
if not vm_cfg.get(vm_name):
vm_cfg[vm_name] = [vm_vbdf]
elif vm_vbdf in vm_cfg[vm_name]:
return False
else:
vm_cfg[vm_name].append(vm_vbdf)

for _, v in vm_cfg.items():
self.vuart_vbdfs.extend(v)
vbdfs = list(set(self.vuart_vbdfs))
if not self.validate_native(vbdfs):
return False
else:
return self.valid_vuart_vbdf(vbdfs)

def validate_ivshmem(self):
ivshmem_vbdf_list = self.scenario_root.xpath('hv/FEATURES/IVSHMEM/IVSHMEM_REGION')
if not ivshmem_vbdf_list:
return
vm_cfg = {}
for ivshmem in ivshmem_vbdf_list:
ivs = ivshmem.xpath('IVSHMEM_VMS/IVSHMEM_VM') # ***
for iv in ivs:
vm_name = iv.xpath('VM_NAME/text()')[0].strip() # ***
vm_vbdf = validate_(iv.xpath('VBDF/text()')[0].strip())

if not validate_load_order(self.scenario_root, vm_name, vm_vbdf):
return False
else:
if not vm_cfg.get(vm_name):
vm_cfg[vm_name] = [vm_vbdf]
elif vm_vbdf in vm_cfg[vm_name]:
return False
else:
vm_cfg[vm_name].append(vm_vbdf)

for _, v in vm_cfg.items():
self.ivshmem_vbdfs.extend(v)
vbdfs = list(set(self.ivshmem_vbdfs))
if not self.validate_native(vbdfs):
return False
else:
return self.valid_vuart_vbdf(vbdfs)

def validate(self):
pci_result = self.validate_pci()
vuart_result = self.validate_vuart()
ivshmem_result = self.validate_ivshmem()
result = {
'pci': pci_result,
'vuart': vuart_result,
'ivshmem': ivshmem_result
}
if vuart_result is None:
del result['vuart']
if ivshmem_result is None:
del result['ivshmem']

print(result)
ret = True
for k, v in result.items():
ret = ret and v
result = {'result': ret}
return convert_result(result)


def _main(board, scenario):
return VBDFValidator(board, scenario).validate()


main = _main


def test():
Expand Down
24 changes: 18 additions & 6 deletions misc/config_tools/schema/checks/vbdf_assignment.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,31 @@

<xs:assert test="every $root in /acrn-config satisfies
every $vm in $root/vm satisfies
every $vbdf in $root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name]/vbdf/text() | $root/hv//IVSHMEM_VM[VM_NAME=$vm/name]/VBDF/text() | $root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart]/VUART_VBDF/text() satisfies
count($root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name and vbdf=$vbdf] | $root/hv//IVSHMEM_VM[VM_NAME=$vm/name and VBDF=$vbdf] | $root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart and VUART_VBDF=$vbdf]) = 1">
<xs:annotation acrn:severity="error" acrn:report-on="$root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name and vbdf=$vbdf] | $root/hv//IVSHMEM_VM[VM_NAME=$vm/name and VBDF=$vbdf] | $root/hv//DEBUG_OPTIONS[VUART_VBDF=$vbdf]">
every $vbdf in $root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name]/vbdf/text() |
$root/hv//IVSHMEM_VM[VM_NAME=$vm/name]/VBDF/text() |
$root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart]/VUART_VBDF/text() satisfies
count($root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name and vbdf=$vbdf] |
$root/hv//IVSHMEM_VM[VM_NAME=$vm/name and VBDF=$vbdf] |
$root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart and VUART_VBDF=$vbdf]) = 1">
<xs:annotation acrn:severity="error"
acrn:report-on="$root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name and vbdf=$vbdf] |
$root/hv//IVSHMEM_VM[VM_NAME=$vm/name and VBDF=$vbdf] |
$root/hv//DEBUG_OPTIONS[VUART_VBDF=$vbdf]">
<xs:documentation>VM "{$vm/name}" contains multiple virtual UART controllers or IVSHMEM interfaces using BDF {$vbdf}. Adjust the BDF of those devices to be unique.</xs:documentation>
</xs:annotation>
</xs:assert>


<!-- $root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart and VUART_VBDF=$vbdf]">-->
<xs:assert test="every $root in /acrn-config satisfies
every $vm in $root/vm[./load_order/text()='SERVICE_VM'] satisfies
every $vbdf in $root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name]/vbdf/text() | $root/hv//IVSHMEM_VM[VM_NAME=$vm/name]/VBDF/text() | $root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart]/VUART_VBDF/text() satisfies
every $vbdf in $root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name]/vbdf/text() |
$root/hv//IVSHMEM_VM[VM_NAME=$vm/name]/VBDF/text() |
$root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE='Vuart']/VUART_VBDF/text() satisfies
contains(/acrn-config//PCI_DEVICE/text(), $vbdf) = false()">
<xs:annotation acrn:severity="error" acrn:report-on="$root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name and vbdf=$vbdf] | $root/hv//IVSHMEM_VM[VM_NAME=$vm/name and VBDF=$vbdf] | $root/hv//DEBUG_OPTIONS[SERIAL_CONSOLE=Vuart]/VUART_VBDF=$vbdf]">
<xs:annotation acrn:severity="error"
acrn:report-on="$root/hv//vuart_connection[type='pci']/endpoint[vm_name=$vm/name and vbdf=$vbdf] |
$root/hv//IVSHMEM_VM[VM_NAME=$vm/name and VBDF=$vbdf] |
$root/hv//DEBUG_OPTIONS/SERIAL_CONSOLE">
<xs:documentation>VM "{$vm/name}" virtual UART controllers or IVSHMEM interfaces using BDF {$vbdf} conflict with native PCI device. Adjust the BDF of those devices to be unique.</xs:documentation>
</xs:annotation>
</xs:assert>
Expand Down
4 changes: 2 additions & 2 deletions misc/config_tools/schema/config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
</xs:annotation>
</xs:element>

<xs:element name="VUART_VBDF" type="VBDFType">
<xs:element name="VUART_VBDF" type="VBDFType" minOccurs="0">
<xs:annotation acrn:title="Virtual UART BDF"
acrn:defaults="[f'00:{i:02x}.0' for i in range(16, 24)]"
acrn:unique-among="//vuart_connection/endpoint[vm_name=$parent/vm_name]/vbdf/text()"
acrn:widget-hidden="{{ rootFormData.SERIAL_CONSOLE.default===None }}"
acrn:widget-options="'placeholder':'00:[device].[function], e.g. 00:1c.0. All fields are in hexadecimal.'">
<xs:documentation>Specify the virtual Bus:Device.Function (BDF) for each PCI virtual UART. Virtual BDF is automatically assigned when the configuration is saved and can be changed if needed.</xs:documentation>
</xs:annotation>
Expand Down
33 changes: 33 additions & 0 deletions misc/config_tools/xforms/lib.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,39 @@
<func:result select="$idx" />
</func:function>

<func:function name="acrn:sos-vuart-index-in-pci-dev">
<xsl:variable name="sos_name" select="//config-data/acrn-config/vm[load_order='SERVICE_VM']/name"/>
<xsl:variable name="sos_vuart_num">
<xsl:value-of select="count(//hv/vuart_connections/vuart_connection[type/text()='pci']/endpoint[vm_name/text()=$sos_name])"/>
</xsl:variable>
<func:result select="$sos_vuart_num" />
</func:function>

<func:function name="acrn:sos-vuart-index">
<xsl:variable name="sos_name" select="//config-data/acrn-config/vm[load_order='SERVICE_VM']/name"/>
<xsl:variable name="console_vuart_num">
<xsl:choose>
<xsl:when test="count(//config-data/acrn-config/vm/console_vuart) > 0">
<xsl:value-of select="1" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="0" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="sos_vuart_num">
<xsl:value-of select="count(//vuart_connection[type = 'pci']/endpoint[vm_name = $sos_name])"/>
</xsl:variable>
<!-- <xsl:variable name="sos_ivshmem_num">-->
<!-- <xsl:value-of select="count(//IVSHMEM_VM[VM_NAME = $sos_name])"/>-->
<!-- </xsl:variable>-->
<xsl:variable name="sos_legacy_num">
<xsl:value-of select="count(//vuart_connection[type = 'legacy']/endpoint[vm_name = $sos_name])"/>
</xsl:variable>
<!-- <func:result select="$console_vuart_num + $sos_ivshmem_num + $sos_vuart_num + $sos_legacy_num" />-->
<func:result select="$console_vuart_num + $sos_vuart_num + $sos_legacy_num" />
</func:function>

<func:function name="acrn:pci-dev-num">
<xsl:param name="vmid" />
<xsl:for-each select="//config-data/acrn-config/vm[@id = $vmid]">
Expand Down
4 changes: 2 additions & 2 deletions misc/config_tools/xforms/pci_dev.c.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<xsl:call-template name="ivshmem_shm_mem" />
<xsl:apply-templates select="console_vuart" />
<xsl:call-template name="communication_vuart" />
<xsl:call-template name="sos_vuart"/>
<xsl:if test="acrn:is-pre-launched-vm(load_order)">
<xsl:apply-templates select="pci_devs" />
</xsl:if>
Expand Down Expand Up @@ -144,13 +145,12 @@
<xsl:value-of select="$newline" />
</xsl:if>
</xsl:for-each>
<xsl:call-template name="sos_vuart"/>
</xsl:template>

<xsl:template name="sos_vuart">

<xsl:if test="//DEBUG_OPTIONS/SERIAL_CONSOLE/text() = 'Vuart'">
<xsl:variable name="vuart_id" select="last()"/>
<xsl:variable name="vuart_id" select="acrn:sos-vuart-index-in-pci-dev()+1"/>
<xsl:choose>
<xsl:when test="acrn:is-service-vm(load_order)">
<xsl:text>{</xsl:text>
Expand Down
7 changes: 7 additions & 0 deletions misc/config_tools/xforms/vm_configurations.c.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,13 @@
<xsl:text>},</xsl:text>
<xsl:value-of select="$newline" />
</xsl:for-each>
<xsl:choose>
<xsl:when test="acrn:is-service-vm(load_order) and acrn:console-is-vuart()">
<xsl:variable name="vuart_id" select="acrn:sos-vuart-index()"/>
<xsl:value-of select="acrn:initializer(concat('vuart[', $vuart_id, ']'), '{}')" />
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>

<xsl:template name="pci_dev_num">
Expand Down
Loading