QEMU supports multiple methods to perform device hotplug.
- ACPI Hotplug on pci bus 0. (pcie.0 on virt or pci.0 on pc).
- SHPC Based hotplug
- PCIe Native hotplug
The following config options have to be enabled
CONFIG_HOTPLUG_PCI_PCIE=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_ACPI=y
CONFIG_HOTPLUG_PCI_SHPC=y
Using virt here as it support all three types of hotplug
qemu-system-x86_64 \
-bios ./qboot/bios.bin \
-kernel ./linux/arch/x86_64/boot/bzImage -append 'console=hvc0 root=/dev/pmem0p3 rw rootfstype=ext4 data=ordered rcupdate.rcu_expedited=1 tsc=reliable no_timer_check noapictimer' \
-device nvdimm,id=nvdimm1,memdev=bootmem -object memory-backend-file,id=bootmem,share=on,mem-path./clear.img,size=9161408512 \
-nographic \
-nodefaults \
-L . \
-net none \
-machine virt,accel=kvm,kernel_irqchip,nvdimm \
-smp 4 \
-m 1024,slots=10,maxmem=16384M \
-monitor telnet:127.0.0.1:55555,server,nowait \
-device virtio-serial-pci,id=virtio-serial0 -device virtconsole,chardev=charconsole0,id=console0 -chardev stdio,id=charconsole0 \
-device pcie-root-port,id=rp50,bus=pcie.0,chassis=1,addr=5.0,multifunction=on,pref64-reserve=32M \
-device pcie-root-port,id=rp51,bus=pcie.0,chassis=2,addr=5.1 \
-device pcie-pci-bridge,id=br0,addr=10.0 \
Based on where you hotplug the device you get different hotplug paths
- Hotplug to bus 0 -> ACPI hotplug
- Hotplug to pcie-pci-rbridge -> SHPC hotplug
- Hotplug to the root-port -> PCIE hotplug
Connect to the qemu monitor and run this appropriate hotplug commands
nc -N 127.0.0.1 55555
device_add virtio-net-pci
device_add vfio-pci,host=b3:00.0
device_add virtio-net-pci,bus=br0,addr=02.0
device_add vfio-pci,host=b3:00.0,bus=br0,addr=03.0
device_add virtio-net-pci,bus=rp51
device_add vfio-pci,host=b3:00.0,bus=rp50
https://www.linux-kvm.org/images/d/d7/02x07-Aspen-Michael_Roth-QEMU_Hotplug_infrastructure.pdf