From a5386e4d40c6c1174082cf3dc773100b4cf62e1a Mon Sep 17 00:00:00 2001
From: caojinhuahw <caojinhua1@huawei.com>
Date: Thu, 6 Nov 2025 16:46:29 +0800
Subject: [PATCH] tests: add some testcase for ub device config

add some ub testcase for xml config

Signed-off-by: caojinhuahw <caojinhua1@huawei.com>
---
 .../caps_7.0.0_aarch64.replies                |  10 +-
 .../iommu-ummu.aarch64-latest.args            |  38 ++++
 tests/qemuxml2argvdata/iommu-ummu.xml         |  29 +++
 .../ub-controller.aarch64-latest.args         |  39 ++++
 tests/qemuxml2argvdata/ub-controller.xml      |  33 +++
 .../ub-hostdev-many.aarch64-latest.args       |  55 +++++
 tests/qemuxml2argvdata/ub-hostdev-many.xml    | 193 ++++++++++++++++++
 .../ub-hostdev-no-iommufd.aarch64-latest.args |  38 ++++
 .../ub-hostdev-no-iommufd.xml                 |  42 ++++
 .../ub-hostdev.aarch64-latest.args            |  40 ++++
 tests/qemuxml2argvdata/ub-hostdev.xml         |  43 ++++
 tests/qemuxml2argvtest.c                      |   7 +
 .../iommu-ummu.aarch64-latest.xml             |  31 +++
 .../ub-hostdev.aarch64-latest.xml             |  44 ++++
 tests/qemuxml2xmltest.c                       |   4 +
 15 files changed, 645 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/iommu-ummu.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/iommu-ummu.xml
 create mode 100644 tests/qemuxml2argvdata/ub-controller.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/ub-controller.xml
 create mode 100644 tests/qemuxml2argvdata/ub-hostdev-many.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/ub-hostdev-many.xml
 create mode 100644 tests/qemuxml2argvdata/ub-hostdev-no-iommufd.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/ub-hostdev-no-iommufd.xml
 create mode 100644 tests/qemuxml2argvdata/ub-hostdev.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/ub-hostdev.xml
 create mode 100644 tests/qemuxml2xmloutdata/iommu-ummu.aarch64-latest.xml
 create mode 100644 tests/qemuxml2xmloutdata/ub-hostdev.aarch64-latest.xml

diff --git a/tests/qemucapabilitiesdata/caps_7.0.0_aarch64.replies b/tests/qemucapabilitiesdata/caps_7.0.0_aarch64.replies
index cdcf4fd76f..4361db9eec 100644
--- a/tests/qemucapabilitiesdata/caps_7.0.0_aarch64.replies
+++ b/tests/qemucapabilitiesdata/caps_7.0.0_aarch64.replies
@@ -6354,6 +6354,10 @@
         {
           "case": "s390-pv-guest",
           "type": "0"
+        },
+        {
+          "case": "iommufd",
+          "type": "0"
         }
       ],
       "members": [
@@ -12625,6 +12629,9 @@
           "features": [
             "unstable"
           ]
+        },
+        {
+          "name": "iommufd"
         }
       ],
       "meta-type": "enum",
@@ -12668,7 +12675,8 @@
         "tls-creds-psk",
         "tls-creds-x509",
         "tls-cipher-suites",
-        "x-remote-object"
+        "x-remote-object",
+        "iommufd"
       ]
     },
     {
diff --git a/tests/qemuxml2argvdata/iommu-ummu.aarch64-latest.args b/tests/qemuxml2argvdata/iommu-ummu.aarch64-latest.args
new file mode 100644
index 0000000000..e23d90cb52
--- /dev/null
+++ b/tests/qemuxml2argvdata/iommu-ummu.aarch64-latest.args
@@ -0,0 +1,38 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-ub-ummu \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-ub-ummu/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-ub-ummu/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-ub-ummu/.config \
+/usr/bin/qemu-system-aarch64 \
+-name guest=ub-ummu,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-ub-ummu/master-key.aes"}' \
+-blockdev '{"driver":"file","filename":"/efi.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \
+-machine virt,usb=off,gic-version=3,ummu=on,dump-guest-core=off,memory-backend=mach-virt.ram,pflash0=libvirt-pflash0-format \
+-accel kvm \
+-cpu host \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-object '{"qom-type":"iommufd","id":"iommufd1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd2"}' \
+-uuid 0c7da38a-634b-4e7e-bd46-4cf65b101619 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-kernel /aarch64.kernel \
+-initrd /aarch64.initrd \
+-append 'rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/iommu-ummu.xml b/tests/qemuxml2argvdata/iommu-ummu.xml
new file mode 100644
index 0000000000..ea249d831c
--- /dev/null
+++ b/tests/qemuxml2argvdata/iommu-ummu.xml
@@ -0,0 +1,29 @@
+<domain type='kvm'>
+  <name>ub-ummu</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufds>2</iommufds>
+  <os>
+    <type arch='aarch64' machine='virt'>hvm</type>
+    <loader type='pflash'>/efi.fd</loader>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <gic version='3'/>
+  </features>
+  <cpu mode='host-passthrough' check='none'/>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+    <iommu model='ummu'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/ub-controller.aarch64-latest.args b/tests/qemuxml2argvdata/ub-controller.aarch64-latest.args
new file mode 100644
index 0000000000..f7cf175ccf
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-controller.aarch64-latest.args
@@ -0,0 +1,39 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-ub-controller \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-ub-controller/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-ub-controller/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-ub-controller/.config \
+/usr/bin/qemu-system-aarch64 \
+-name guest=ub-controller,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-ub-controller/master-key.aes"}' \
+-blockdev '{"driver":"file","filename":"/efi.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \
+-machine virt,usb=off,gic-version=3,dump-guest-core=off,memory-backend=mach-virt.ram,pflash0=libvirt-pflash0-format \
+-accel kvm \
+-cpu host \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-object '{"qom-type":"iommufd","id":"iommufd1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd2"}' \
+-uuid 0c7da38a-634b-4e7e-bd46-4cf65b101619 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-kernel /aarch64.kernel \
+-initrd /aarch64.initrd \
+-append 'rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on' \
+-device '{"driver":"ubc","id":"ubc.1","guid":"cc08-a000-0-2-000000-0000000000000001","eid":1,"portnum":10}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/ub-controller.xml b/tests/qemuxml2argvdata/ub-controller.xml
new file mode 100644
index 0000000000..6c453bd563
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-controller.xml
@@ -0,0 +1,33 @@
+<domain type="kvm">
+  <name>ub-controller</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory>1048576</memory>
+  <currentMemory>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufds>2</iommufds>
+  <os>
+    <type arch="aarch64" machine="virt">hvm</type>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <loader type="pflash">/efi.fd</loader>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+  </os>
+  <features>
+    <gic version='3'/>
+    <acpi/>
+  </features>
+  <cpu mode='host-passthrough' check='none'>
+  </cpu>
+  <clock offset="utc"/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+	<controller type='ub' index='1' model='ubc'>
+	    <ports num='10'>
+	    </ports>
+        <address type='ub' eid='0x1' guid='cc08-a000-0-2-000000-0000000000000001'/>
+    </controller>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/ub-hostdev-many.aarch64-latest.args b/tests/qemuxml2argvdata/ub-hostdev-many.aarch64-latest.args
new file mode 100644
index 0000000000..20476d7191
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-hostdev-many.aarch64-latest.args
@@ -0,0 +1,55 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-ub-vhostdev-many \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-ub-vhostdev-many/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-ub-vhostdev-many/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-ub-vhostdev-many/.config \
+/usr/bin/qemu-system-aarch64 \
+-name guest=ub-vhostdev-many,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-ub-vhostdev-many/master-key.aes"}' \
+-blockdev '{"driver":"file","filename":"/efi.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \
+-machine virt,usb=off,gic-version=3,dump-guest-core=off,memory-backend=mach-virt.ram,pflash0=libvirt-pflash0-format \
+-accel kvm \
+-cpu host \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-object '{"qom-type":"iommufd","id":"iommufd1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd2"}' \
+-uuid 0c7da38a-634b-4e7e-bd46-4cf65b101619 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-kernel /aarch64.kernel \
+-initrd /aarch64.initrd \
+-append 'rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on' \
+-device '{"driver":"ubc","id":"ubc.1","guid":"cc08-a000-0-2-000000-0000000000000000","eid":1,"portnum":16}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000001","id":"hostdev0","guid":"cc08-a000-0-2-000000-0000000000000001","eid":3,"portnum":1,"port0":"ubc.1:0","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000002","id":"hostdev1","guid":"cc08-a000-0-2-000000-0000000000000002","eid":4,"portnum":1,"port0":"ubc.1:1","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000003","id":"hostdev2","guid":"cc08-a000-0-2-000000-0000000000000003","eid":5,"portnum":1,"port0":"ubc.1:2","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000004","id":"hostdev3","guid":"cc08-a000-0-2-000000-0000000000000004","eid":6,"portnum":1,"port0":"ubc.1:3","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000005","id":"hostdev4","guid":"cc08-a000-0-2-000000-0000000000000005","eid":7,"portnum":1,"port0":"ubc.1:4","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000006","id":"hostdev5","guid":"cc08-a000-0-2-000000-0000000000000006","eid":8,"portnum":1,"port0":"ubc.1:5","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000007","id":"hostdev6","guid":"cc08-a000-0-2-000000-0000000000000007","eid":9,"portnum":1,"port0":"ubc.1:6","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000008","id":"hostdev7","guid":"cc08-a000-0-2-000000-0000000000000008","eid":10,"portnum":1,"port0":"ubc.1:7","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000009","id":"hostdev8","guid":"cc08-a000-0-2-000000-0000000000000009","eid":11,"portnum":1,"port0":"ubc.1:8","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000010","id":"hostdev9","guid":"cc08-a000-0-2-000000-0000000000000010","eid":12,"portnum":1,"port0":"ubc.1:9","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000011","id":"hostdev10","guid":"cc08-a000-0-2-000000-0000000000000011","eid":13,"portnum":1,"port0":"ubc.1:10","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000012","id":"hostdev11","guid":"cc08-a000-0-2-000000-0000000000000012","eid":14,"portnum":1,"port0":"ubc.1:11","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000013","id":"hostdev12","guid":"cc08-a000-0-2-000000-0000000000000013","eid":15,"portnum":1,"port0":"ubc.1:12","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000014","id":"hostdev13","guid":"cc08-a000-0-2-000000-0000000000000014","eid":16,"portnum":1,"port0":"ubc.1:13","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000015","id":"hostdev14","guid":"cc08-a000-0-2-000000-0000000000000015","eid":17,"portnum":1,"port0":"ubc.1:14","iommufd":"iommufd1"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000016","id":"hostdev15","guid":"cc08-a000-0-2-000000-0000000000000016","eid":18,"portnum":1,"port0":"ubc.1:15","iommufd":"iommufd1"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/ub-hostdev-many.xml b/tests/qemuxml2argvdata/ub-hostdev-many.xml
new file mode 100644
index 0000000000..44e3ad4521
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-hostdev-many.xml
@@ -0,0 +1,193 @@
+<domain type="kvm">
+  <name>ub-vhostdev-many</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory>1048576</memory>
+  <currentMemory>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufds>2</iommufds>
+  <os>
+    <type arch="aarch64" machine="virt">hvm</type>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <loader type="pflash">/efi.fd</loader>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+  </os>
+  <features>
+    <gic version='3'/>
+    <acpi/>
+  </features>
+  <cpu mode='host-passthrough' check='none'>
+  </cpu>
+  <clock offset="utc"/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+	<controller type='ub' index='1' model='ubc'>
+	    <ports num='16'>
+	    </ports>
+        <address type='ub' eid='0x1' guid='cc08-a000-0-2-000000-0000000000000000'/>
+    </controller>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000001"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='0'/>
+        </ports>
+	    <address type='ub' eid='0x3' guid="cc08-a000-0-2-000000-0000000000000001"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000002"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='1'/>
+        </ports>
+	    <address type='ub' eid='0x4' guid="cc08-a000-0-2-000000-0000000000000002"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000003"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='2'/>
+        </ports>
+	    <address type='ub' eid='0x5' guid="cc08-a000-0-2-000000-0000000000000003"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000004"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='3'/>
+        </ports>
+	    <address type='ub' eid='0x6' guid="cc08-a000-0-2-000000-0000000000000004"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000005"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='4'/>
+        </ports>
+	    <address type='ub' eid='0x7' guid="cc08-a000-0-2-000000-0000000000000005"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000006"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='5'/>
+        </ports>
+	    <address type='ub' eid='0x8' guid="cc08-a000-0-2-000000-0000000000000006"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000007"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='6'/>
+        </ports>
+	    <address type='ub' eid='0x9' guid="cc08-a000-0-2-000000-0000000000000007"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000008"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='7'/>
+        </ports>
+	    <address type='ub' eid='0xa' guid="cc08-a000-0-2-000000-0000000000000008"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000009"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='8'/>
+        </ports>
+	    <address type='ub' eid='0xb' guid="cc08-a000-0-2-000000-0000000000000009"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000010"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='9'/>
+        </ports>
+	    <address type='ub' eid='0xc' guid="cc08-a000-0-2-000000-0000000000000010"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000011"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='10'/>
+        </ports>
+	    <address type='ub' eid='0xd' guid="cc08-a000-0-2-000000-0000000000000011"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000012"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='11'/>
+        </ports>
+	    <address type='ub' eid='0xe' guid="cc08-a000-0-2-000000-0000000000000012"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000013"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='12'/>
+        </ports>
+	    <address type='ub' eid='0xf' guid="cc08-a000-0-2-000000-0000000000000013"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000014"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='13'/>
+        </ports>
+	    <address type='ub' eid='0x10' guid="cc08-a000-0-2-000000-0000000000000014"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000015"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='14'/>
+        </ports>
+	    <address type='ub' eid='0x11' guid="cc08-a000-0-2-000000-0000000000000015"/>
+    </hostdev>
+    <hostdev mode='subsystem' type='ub' managed='yes' iommufd='1'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000016"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='15'/>
+        </ports>
+	    <address type='ub' eid='0x12' guid="cc08-a000-0-2-000000-0000000000000016"/>
+    </hostdev>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/ub-hostdev-no-iommufd.aarch64-latest.args b/tests/qemuxml2argvdata/ub-hostdev-no-iommufd.aarch64-latest.args
new file mode 100644
index 0000000000..11d1009d85
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-hostdev-no-iommufd.aarch64-latest.args
@@ -0,0 +1,38 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev-no-iommuf \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev-no-iommuf/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev-no-iommuf/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev-no-iommuf/.config \
+/usr/bin/qemu-system-aarch64 \
+-name guest=ub-hostdev-no-iommufd,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-ub-hostdev-no-iommuf/master-key.aes"}' \
+-blockdev '{"driver":"file","filename":"/efi.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \
+-machine virt,usb=off,gic-version=3,dump-guest-core=off,memory-backend=mach-virt.ram,pflash0=libvirt-pflash0-format \
+-accel kvm \
+-cpu host \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid 0c7da38a-634b-4e7e-bd46-4cf65b101619 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-kernel /aarch64.kernel \
+-initrd /aarch64.initrd \
+-append 'rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on' \
+-device '{"driver":"ubc","id":"ubc.1","guid":"cc08-a000-0-2-000000-0000000000000001","eid":1,"portnum":16}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000002","id":"hostdev0","guid":"cc08-a000-0-2-000000-0000000000000002","eid":3,"portnum":1,"port0":"ubc.1:0"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/ub-hostdev-no-iommufd.xml b/tests/qemuxml2argvdata/ub-hostdev-no-iommufd.xml
new file mode 100644
index 0000000000..a3a9f1b019
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-hostdev-no-iommufd.xml
@@ -0,0 +1,42 @@
+<domain type="kvm">
+  <name>ub-hostdev-no-iommufd</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory>1048576</memory>
+  <currentMemory>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch="aarch64" machine="virt">hvm</type>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <loader type="pflash">/efi.fd</loader>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+  </os>
+  <features>
+    <gic version='3'/>
+    <acpi/>
+  </features>
+  <cpu mode='host-passthrough' check='none'>
+  </cpu>
+  <clock offset="utc"/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+	<controller type='ub' index='1' model='ubc'>
+	    <ports num='16'>
+	    </ports>
+        <address type='ub' eid='0x1' guid='cc08-a000-0-2-000000-0000000000000001'/>
+    </controller>
+    <hostdev mode='subsystem' type='ub' managed='yes'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000002"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='0'/>
+        </ports>
+	    <address type='ub' eid='0x3' guid="cc08-a000-0-2-000000-0000000000000002"/>
+    </hostdev>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/ub-hostdev.aarch64-latest.args b/tests/qemuxml2argvdata/ub-hostdev.aarch64-latest.args
new file mode 100644
index 0000000000..da206e3e87
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-hostdev.aarch64-latest.args
@@ -0,0 +1,40 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev/.local/share \
+XDG_CACHE_HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev/.cache \
+XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-ub-hostdev/.config \
+/usr/bin/qemu-system-aarch64 \
+-name guest=ub-hostdev,debug-threads=on \
+-S \
+-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain--1-ub-hostdev/master-key.aes"}' \
+-blockdev '{"driver":"file","filename":"/efi.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \
+-blockdev '{"node-name":"libvirt-pflash0-format","read-only":false,"driver":"raw","file":"libvirt-pflash0-storage"}' \
+-machine virt,usb=off,gic-version=3,dump-guest-core=off,memory-backend=mach-virt.ram,pflash0=libvirt-pflash0-format \
+-accel kvm \
+-cpu host \
+-m size=1048576k \
+-object '{"qom-type":"memory-backend-ram","id":"mach-virt.ram","size":1073741824}' \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-object '{"qom-type":"iommufd","id":"iommufd1"}' \
+-object '{"qom-type":"iommufd","id":"iommufd2"}' \
+-uuid 0c7da38a-634b-4e7e-bd46-4cf65b101619 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-kernel /aarch64.kernel \
+-initrd /aarch64.initrd \
+-append 'rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on' \
+-device '{"driver":"ubc","id":"ubc.1","guid":"cc08-a000-0-2-000000-0000000000000001","eid":1,"portnum":16}' \
+-audiodev '{"id":"audio1","driver":"none"}' \
+-device '{"driver":"vfio-ub","host":"cc08-a000-0-2-000000-0000000000000002","id":"hostdev0","guid":"cc08-a000-0-2-000000-0000000000000002","eid":3,"portnum":1,"port0":"ubc.1:0"}' \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/ub-hostdev.xml b/tests/qemuxml2argvdata/ub-hostdev.xml
new file mode 100644
index 0000000000..d47047701c
--- /dev/null
+++ b/tests/qemuxml2argvdata/ub-hostdev.xml
@@ -0,0 +1,43 @@
+<domain type="kvm">
+  <name>ub-hostdev</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory>1048576</memory>
+  <currentMemory>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufds>2</iommufds>
+  <os>
+    <type arch="aarch64" machine="virt">hvm</type>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <loader type="pflash">/efi.fd</loader>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+  </os>
+  <features>
+    <gic version='3'/>
+    <acpi/>
+  </features>
+  <cpu mode='host-passthrough' check='none'>
+  </cpu>
+  <clock offset="utc"/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+	<controller type='ub' index='1' model='ubc'>
+	    <ports num='16'>
+	    </ports>
+        <address type='ub' eid='0x1' guid='cc08-a000-0-2-000000-0000000000000001'/>
+    </controller>
+    <hostdev mode='subsystem' type='ub' managed='yes'>
+        <driver name='vfio'/>
+	    <source>
+	        <address guid="cc08-a000-0-2-000000-0000000000000002"/>
+	    </source>
+        <ports num='1'>
+            <port index='0' teid='0x1' tport='0'/>
+        </ports>
+	    <address type='ub' eid='0x3' guid="cc08-a000-0-2-000000-0000000000000002"/>
+    </hostdev>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index b2ea2191dc..160dac876f 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -2410,6 +2410,13 @@ mymain(void)
     DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown-disabled", "s390x");
     DO_TEST_CAPS_ARCH_VER("s390-async-teardown-disabled", "s390x", "6.0.0");
 
+    /* for ub test */
+    DO_TEST_CAPS_ARCH_LATEST("ub-controller", "aarch64");
+    DO_TEST_CAPS_ARCH_LATEST("ub-hostdev", "aarch64");
+    DO_TEST_CAPS_ARCH_LATEST("ub-hostdev-many", "aarch64");
+    DO_TEST_CAPS_ARCH_LATEST("ub-hostdev-no-iommufd", "aarch64");
+    DO_TEST_CAPS_ARCH_LATEST("iommu-ummu", "aarch64");
+
     qemuTestDriverFree(&driver);
     virFileWrapperClearPrefixes();
 
diff --git a/tests/qemuxml2xmloutdata/iommu-ummu.aarch64-latest.xml b/tests/qemuxml2xmloutdata/iommu-ummu.aarch64-latest.xml
new file mode 100644
index 0000000000..592e389c61
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/iommu-ummu.aarch64-latest.xml
@@ -0,0 +1,31 @@
+<domain type='kvm'>
+  <name>ub-ummu</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufds>2</iommufds>
+  <os>
+    <type arch='aarch64' machine='virt'>hvm</type>
+    <loader type='pflash'>/efi.fd</loader>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <gic version='3'/>
+  </features>
+  <cpu mode='host-passthrough' check='none'/>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <audio id='1' type='none'/>
+    <iommu model='ummu'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/ub-hostdev.aarch64-latest.xml b/tests/qemuxml2xmloutdata/ub-hostdev.aarch64-latest.xml
new file mode 100644
index 0000000000..f658cc8f96
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/ub-hostdev.aarch64-latest.xml
@@ -0,0 +1,44 @@
+<domain type='kvm'>
+  <name>ub-hostdev</name>
+  <uuid>0c7da38a-634b-4e7e-bd46-4cf65b101619</uuid>
+  <memory unit='KiB'>1048576</memory>
+  <currentMemory unit='KiB'>1048576</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <iommufds>2</iommufds>
+  <os>
+    <type arch='aarch64' machine='virt'>hvm</type>
+    <loader type='pflash'>/efi.fd</loader>
+    <kernel>/aarch64.kernel</kernel>
+    <initrd>/aarch64.initrd</initrd>
+    <cmdline>rdinit=init console=ttyAMA0 earlycon=pl011,0x9000000 acpi=on</cmdline>
+    <boot dev='hd'/>
+  </os>
+  <features>
+    <acpi/>
+    <gic version='3'/>
+  </features>
+  <cpu mode='host-passthrough' check='none'/>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>restart</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-aarch64</emulator>
+    <controller type='ub' index='1' model='ubc'>
+      <ports num='16'/>
+      <address type='ub' eid='0x1' guid='cc08-a000-0-2-000000-0000000000000001'/>
+    </controller>
+    <controller type='pci' index='0' model='pcie-root'/>
+    <audio id='1' type='none'/>
+    <hostdev mode='subsystem' type='ub' managed='yes'>
+      <driver name='vfio'/>
+      <source>
+        <address guid='cc08-a000-0-2-000000-0000000000000002'/>
+      </source>
+      <ports num='1'>
+        <port index='0' teid='0x1' tport='0'/>
+      </ports>
+      <address type='ub' eid='0x3' guid='cc08-a000-0-2-000000-0000000000000002'/>
+    </hostdev>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 1010b68ebc..7e5b5a7ce1 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -1029,6 +1029,10 @@ mymain(void)
     DO_TEST_CAPS_ARCH_LATEST("s390-async-teardown-disabled", "s390x");
     DO_TEST_CAPS_ARCH_VER("s390-async-teardown-disabled", "s390x", "6.0.0");
 
+    /* for ub test */
+    DO_TEST_CAPS_ARCH_LATEST("ub-hostdev", "aarch64");
+    DO_TEST_CAPS_ARCH_LATEST("iommu-ummu", "aarch64");
+
  cleanup:
     qemuTestDriverFree(&driver);
     virFileWrapperClearPrefixes();
-- 
2.51.0.windows.1