ACPI PCI hotplug of a PCI device using a bar > 2M fails on ARM
with a resource allocation failure in the guest kernel (Linux):
qemu-system-aarch64 [..] -device pcie-root-port,id=rp1,bus=pcie.0 \
-global acpi-ged.acpi-pci-hotplug-with-bridge-support=on \
-pflash /usr/share/edk2/aarch64/QEMU_EFI-silent-pflash.qcow2
(qemu) device_add pci-testdev,bus=rp1,membar=4M
[ 55.106283] pci 0000:01:00.0: [1b36:0005] type 00 class 0x00ff00
conventional PCI endpoint
[ 55.107627] pci 0000:01:00.0: BAR 0 [mem 0x00000000-0x00000fff]
[ 55.107864] pci 0000:01:00.0: BAR 1 [io 0x0000-0x00ff]
[ 55.108015] pci 0000:01:00.0: BAR 2 [mem 0x00000000-0x003fffff 64bit pref]
[ 55.118609] pci 0000:01:00.0: BAR 2 [mem size 0x00400000 64bit pref]: can't
assign; no space
[ 55.118653] pci 0000:01:00.0: BAR 2 [mem size 0x00400000 64bit pref]: failed
to assign
[ 55.118671] pci 0000:01:00.0: BAR 0 [mem 0x10000000-0x10000fff]: assigned
[ 55.122828] pci 0000:01:00.0: BAR 1 [io 0x1000-0x10ff]: assigned
[ 55.127090] pci 0000:01:00.0: BAR 0 [mem 0x10000000-0x10000fff]: releasing
[ 55.127098] pci 0000:01:00.0: BAR 2 [mem size 0x00400000 64bit pref]: can't
assign; no space
[ 55.127102] pci 0000:01:00.0: BAR 2 [mem size 0x00400000 64bit pref]: failed
to assign
[ 55.127106] pci 0000:01:00.0: BAR 0 [mem 0x10000000-0x10000fff]: assigned
This behavior is exactly the same on x86 - except the busses are created
with a default window size of 256M there. If the PCI devices being
hotplugged use a bar > 256M you get the same failure like on ARM.
The workaround on x86 is to specify "pref64-reserve=" for the PCIe
root-port. On ARM this is currently ignored.
The following patch changes ACPI DSM #5 to return 0 (only when
ACPI HP is used) which basically tells the guest kernel to keep
all PCI resource allocations.
------->8
From 92cd64b8398f13e51b67ff8baf62f15cac300c94 Mon Sep 17 00:00:00 2001
From: Sebastian Ott <[email protected]>
Date: Wed, 20 May 2026 10:39:26 -0400
Subject: [PATCH] hw/arm/virt: preserve config for ACPI PCI hotplug
Change ACPI DSM #5 to return 0 when ACPI PCI hotplug is used
to tell the guest kernel to keep all PCI resource allocations.
This allows to use the pref64-reserve= option for pcie-root-ports
and thus enables hotplug of PCI devices with a barsize > 2M.
Signed-off-by: Sebastian Ott <[email protected]>
---
hw/arm/virt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b090233893..293a0c2163 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1094,6 +1094,7 @@ static inline DeviceState
*create_acpi_ged(VirtMachineState *vms)
pcihp_region_index = sysbus_mmio_map_name(sbdev,
ACPI_PCIHP_REGION_NAME,
vms->memmap[VIRT_ACPI_PCIHP].base);
assert(pcihp_region_index >= 0);
+ vms->pci_preserve_config = true;
}
sysbus_connect_irq(sbdev, 0, qdev_get_gpio_in(vms->gic, irq));
--
2.53.0