Explicit PCI addresses should override those inferred by argument order

I'm currently using microvm.nix to deploy small NixOS VMs using QEMU. I attempted to pass through my computer's iGPU using your documentation. However, setting the PCI address inside the VM to 2.0 causes the VM to fail to start since other devices, in this case virtiofs shares, are already using that address, since they are specified earlier on the command line.

For microvm.nix, this can be fixed by modifying the order of generating the command line, but I fear that down the road, this issue could come up again for a different kind of attached device. Therefore, a more intelligent fix seems preferrable.

Goal

In my opinion, overriding the address of a given device should automatically "reserve" that address, even if other devices are specified first on the command line.

Technical details

Currently, the VM would fail with the following error:

-device vfio-pci,host=0000:00:02.0,multifunction=on,x-igd-opregion=on,x-igd-lpc=on,addr=2.0,x-vga=on: PCI: slot 2 function 0 not available for vfio-pci, in use by vhost-user-fs-pci,id=(null)

when the following arguments are used (unnecessary ones omitted - if any crucial ones are missing, feel free to ask. I haven't used QEMU at such a "low level" before.):

microvm@jellyfin \
    -M microvm,accel=kvm:tcg,acpi=on,mem-merge=on,pcie=on,pic=off,pit=off,usb=off \
    -kernel /nix/store/rgymc3j4lwjnzdyx0mnhibbh39gywb98-linux-6.12.47/bzImage \
    -initrd /nix/store/9ljp0bzxp54mdgsjmp8myshybs5j8lwz-initrd-linux-6.12.47/initrd \
    -device virtio-rng-pci \
    -enable-kvm \
    -device i8042 \
    -append "reboot=t panic=-1 8250.nr_uarts=1 console=ttyS0,115200n8 earlyprint=serial,ttyS0,115200n8 i915.force_probe=7d55 console=ttyS0,115200n8 earlyprint=serial,ttyS0,115200n8 root=fstab loglevel=4 lsm=landlock,yama,bpf init=/nix/store/cgiamjlykzh0pjsdn8rnqk242ljhq1qb-nixos-system-jellyfin-25.11pre-git/init regInfo=/nix/store/xivrwqs0xf2c9lcd2fifh7824kknxx2h-closure-info/registration" \
    -object memory-backend-memfd,id=mem,size=8192M,share=on \
    -chardev socket,id=fs0,path=jellyfin-virtiofs-ro-store.sock \
    -device vhost-user-fs-pci,chardev=fs0,tag=ro-store \
    -device vfio-pci,host=0000:00:02.0,multifunction=on,x-igd-opregion=on,x-igd-lpc=on,addr=2.0,x-vga=on

By default, the PCI passthrough is generated last, so the specified address 2.0 doesn't work. Moving the device specification after -device virtio-rng-pci fixes the issue.

Additional information

The issue was discussed in issue 410 in the microvm.nix repo.

Edited by Daniel P. Berrangé
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information