From: Christian Brauner Date: Thu, 14 May 2026 06:13:00 +0000 (+0200) Subject: vmspawn: multifunction-pack pcie-root-ports on pcie.0 (#42077) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8e6ad359e36ff360e5b2fd39320944b44b1fb035;p=thirdparty%2Fsystemd.git vmspawn: multifunction-pack pcie-root-ports on pcie.0 (#42077) The pre-allocated pcie-root-port block in run_virtual_machine() places every port directly on pcie.0 with an auto-assigned PCI address. A minimal VM already costs 4 builtin + 10 hotplug spares = 14 pcie.0 slots, on top of 3 implicit virtio devices (virtio-rng-pci, virtio-balloon, virtio-serial-pci) for another 3. pcie.0 has 32 device-numbers; q35 reserves 0x00 (host bridge) and 0x1f (ICH9 LPC), leaving ~30 auto-assignable slots. TEST-64-UDEV-STORAGE- nvme_basic pushes 20 '-device nvme' lines through $SYSTEMD_VMSPAWN_QEMU_EXTRA, which vmspawn does not see — total demand 14 + 3 + 20 = 37 > 30. Bus realization fails after QEMU's chardev has already emitted the QMP greeting, and the monitor socket POLLHUPs while we are mid-feature-probe, reported as 'QMP connection dropped during feature probing'. Pack the root ports as multifunction devices, 8 per pcie.0 device- number (QEMU docs/pcie.txt:84, 117-120, 255-258). Function 0 of each group carries multifunction=on; functions 1-7 ride the same slot via addr=N.F. Each function remains independently hot-pluggable so vmspawn's QMP device_add machinery is unaffected. 14 ports collapse to 2 pcie.0 slots; the nvme_basic budget becomes 2 + 3 + 20 = 25. The chassis/slot properties (used for ACPI hotplug identity) stay as i+1 — they live in a uint8_t namespace independent of the PCI BDF and are still unique. Base PCI slot 0x10 sits above the auto-assigned virtio devices (which land at 0x01-0x03 in config order) and below the q35 LPC reservation at 0x1f. While here, rebuild the slot-count formula to match what assign_pcie_ports() actually allocates. The +1 'SCSI controller' term was bogus — virtio-scsi-pci comes from the hotplug-spares pool via hotplug_port_owner[] in vmspawn-qmp.c, never from a builtin port (see the comment in assign_pcie_ports()). The +1 'network' and +1 'vsock' terms are now conditional on arg_network_stack and use_vsock. Bind volumes were missing entirely. And the per-drive accounting now mirrors assign_pcie_ports()'s skip-SCSI behaviour: non-SCSI drives (root + extras + bind volumes) take one builtin port each, SCSI drives take none — they share a controller drawn from the hotplug pool at device-add time. Tighten the cap from UINT8_MAX to 192 (24 packed device-numbers × 8) so we cannot claim more than 24 slots on pcie.0 regardless of how many extras/runtime-mounts a caller asks for. Signed-off-by: Christian Brauner (Amutable) --- 8e6ad359e36ff360e5b2fd39320944b44b1fb035