On Thu, Aug 14, 2025 at 07:54:11PM -0700, Nathan Chen via Devel wrote:
> Add support for parsing multiple IOMMU devices from
> the VM definition when "smmuv3Dev" is the IOMMU model.
>
> Signed-off-by: Nathan Chen <[email protected]>
> ---
> src/conf/domain_conf.c | 153 ++++++++++++++++++++++++++----
> src/conf/domain_conf.h | 9 +-
> src/conf/domain_validate.c | 32 ++++---
> src/conf/schemas/domaincommon.rng | 4 +-
> src/libvirt_private.syms | 2 +
> src/qemu/qemu_alias.c | 15 ++-
> src/qemu/qemu_command.c | 146 ++++++++++++++--------------
> src/qemu/qemu_domain_address.c | 35 +++----
> src/qemu/qemu_driver.c | 8 +-
> src/qemu/qemu_postparse.c | 11 ++-
> src/qemu/qemu_validate.c | 2 +-
> 11 files changed, 284 insertions(+), 133 deletions(-)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index dc222887d4..5ea4d6424b 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -16446,6 +16447,112 @@ virDomainInputDefFind(const virDomainDef *def,
> }
>
>
> +bool
> +virDomainIOMMUDefEquals(const virDomainIOMMUDef *a,
> + const virDomainIOMMUDef *b)
> +{
> + if (a->model != b->model ||
> + a->intremap != b->intremap ||
> + a->caching_mode != b->caching_mode ||
> + a->eim != b->eim ||
> + a->iotlb != b->iotlb ||
> + a->aw_bits != b->aw_bits ||
> + a->parent_idx != b->parent_idx ||
> + a->accel != b->accel ||
> + a->dma_translation != b->dma_translation)
> + return false;
> +
> + switch (a->info.type) {
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI:
> + if (a->info.addr.pci.domain != b->info.addr.pci.domain ||
> + a->info.addr.pci.bus != b->info.addr.pci.bus ||
> + a->info.addr.pci.slot != b->info.addr.pci.slot ||
> + a->info.addr.pci.function != b->info.addr.pci.function) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
> + if (a->info.addr.drive.controller != b->info.addr.drive.controller ||
> + a->info.addr.drive.bus != b->info.addr.drive.bus ||
> + a->info.addr.drive.unit != b->info.addr.drive.unit) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL:
> + if (a->info.addr.vioserial.controller !=
> b->info.addr.vioserial.controller ||
> + a->info.addr.vioserial.bus != b->info.addr.vioserial.bus ||
> + a->info.addr.vioserial.port != b->info.addr.vioserial.port) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID:
> + if (a->info.addr.ccid.controller != b->info.addr.ccid.controller ||
> + a->info.addr.ccid.slot != b->info.addr.ccid.slot) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA:
> + if (a->info.addr.isa.iobase != b->info.addr.isa.iobase ||
> + a->info.addr.isa.irq != b->info.addr.isa.irq) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM:
> + if (a->info.addr.dimm.slot != b->info.addr.dimm.slot) {
> + return false;
> + }
> +
> + if (a->info.addr.dimm.base != b->info.addr.dimm.base) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW:
> + if (a->info.addr.ccw.cssid != b->info.addr.ccw.cssid ||
> + a->info.addr.ccw.ssid != b->info.addr.ccw.ssid ||
> + a->info.addr.ccw.devno != b->info.addr.ccw.devno) {
> + return false;
> + }
> + break;
> +
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB:
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO:
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390:
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO:
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE:
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_UNASSIGNED:
> + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST:
> + break;
> + }
> +
> + if (a->info.acpiIndex != b->info.acpiIndex) {
> + return false;
> + }
Most of this should go away if you use virDomainDeviceInfoAddressIsEqual
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|