From: Tushar Dave <tdave@nvidia.com>
To: qemu-devel@nongnu.org
Cc: alwilliamson@nvidia.com, jgg@nvidia.com, skolothumtho@nvidia.com,
qemu-arm@nongnu.org, peter.maydell@linaro.org, mst@redhat.com,
marcel.apfelbaum@gmail.com, devel@edk2.groups.io
Subject: [RFC PATCH 8/8] hw/arm/virt: add pci-pre-enum machine property
Date: Fri, 8 May 2026 13:37:17 -0500 [thread overview]
Message-ID: <20260508183717.193630-9-tdave@nvidia.com> (raw)
In-Reply-To: <20260508183717.193630-1-tdave@nvidia.com>
Add a "pci-pre-enum" option for the virt machine. When enabled, QEMU
performs PCI enumeration and programs BARs before handing control to
firmware.
This is intended for use with the "fixed-bars" property, where the
user assigns fixed BAR addresses and expects firmware to preserve the
configuration.
pci-pre-enum is exposed as a separate machine property rather than
being implied by the presence of fixed-bars. This allows QEMU's PCI
enumeration path to be exercised independently (for example, to
verify that QEMU produces the same device enumeration as EDK2)
without requiring any device to specify fixed BARs.
When enabled, a "pci-enum-done" property is added to the PCI node in
the device tree to indicate to firmware (e.g. EDK2) that PCI
enumeration has already been performed.
When disabled (default), behavior is unchanged.
Signed-off-by: Tushar Dave <tdave@nvidia.com>
---
hw/arm/virt.c | 70 +++++++++++++++++++++++++++++++++++++++++--
include/hw/arm/virt.h | 1 +
2 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 55f41c7e46..7d41bfc457 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -52,6 +52,7 @@
#include "system/whpx.h"
#include "system/qtest.h"
#include "system/system.h"
+#include "system/reset.h"
#include "hw/core/loader.h"
#include "qapi/error.h"
#include "qemu/bitops.h"
@@ -94,6 +95,8 @@
#include "hw/cxl/cxl.h"
#include "hw/cxl/cxl_host.h"
#include "qemu/guest-random.h"
+#include "hw/pci/pci-resource.h"
+#include "hw/pci/pci-enumerate.h"
static GlobalProperty arm_virt_compat_defaults[] = {
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
@@ -1697,6 +1700,10 @@ static void create_pcie(VirtMachineState *vms)
qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 1);
create_pcie_irq_map(ms, vms->gic_phandle, irq, nodename);
+ if (vms->pci_pre_enum) {
+ qemu_fdt_setprop_cell(ms->fdt, nodename, "pci-enum-done", 1);
+ }
+
if (vms->iommu) {
vms->iommu_phandle = qemu_fdt_alloc_phandle(ms->fdt);
@@ -1832,6 +1839,20 @@ static void virt_build_smbios(VirtMachineState *vms)
}
}
+static void virt_pci_apply_fix_bar_after_reset(void *opaque)
+{
+ VirtMachineState *vms = opaque;
+ PciFixedBarMmioParams mmio = {
+ .mmio32_base = vms->memmap[VIRT_PCIE_MMIO].base,
+ .mmio32_size = vms->memmap[VIRT_PCIE_MMIO].size,
+ .mmio64_base = vms->memmap[VIRT_HIGH_PCIE_MMIO].base,
+ .mmio64_size = vms->memmap[VIRT_HIGH_PCIE_MMIO].size,
+ };
+
+ pci_enumerate_bus(vms->bus);
+ pci_fixed_bar_allocator(vms->bus, &mmio);
+}
+
static
void virt_machine_done(Notifier *notifier, void *data)
{
@@ -1864,11 +1885,30 @@ void virt_machine_done(Notifier *notifier, void *data)
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as, ms, cpu) < 0) {
exit(1);
}
-
- pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus,
- &error_abort);
+ /*
+ * In pci-pre-enum mode, EDK2 does not perform PCI enumeration or
+ * resource assignment (PcdPciDisableBusEnumeration = TRUE). All root
+ * bridges are marked ResourceAssigned, meaning the topology and
+ * MMIO/MMIO64 apertures provided by QEMU are treated as final.
+ *
+ * In this mode, each root bridge is consumed as an independent resource
+ * domain. Exposing additional root bridges (e.g. PXB extra roots) that
+ * share identical MMIO/MMIO64 apertures creates duplicate resource domains
+ * with overlapping address spaces, which is invalid in this mode.
+ *
+ * Therefore, extra root bridges are not exposed in pre-enumeration mode.
+ */
+ if (!vms->pci_pre_enum) {
+ pci_bus_add_fw_cfg_extra_pci_roots(vms->fw_cfg, vms->bus,
+ &error_abort);
+ }
virt_acpi_setup(vms);
+
+ if (vms->pci_pre_enum) {
+ qemu_register_reset(virt_pci_apply_fix_bar_after_reset, vms);
+ }
+
virt_build_smbios(vms);
}
@@ -2988,6 +3028,20 @@ static void virt_set_mte(Object *obj, bool value, Error **errp)
vms->mte = value;
}
+static bool virt_get_pci_pre_enum(Object *obj, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+
+ return vms->pci_pre_enum;
+}
+
+static void virt_set_pci_pre_enum(Object *obj, bool value, Error **errp)
+{
+ VirtMachineState *vms = VIRT_MACHINE(obj);
+
+ vms->pci_pre_enum = value;
+}
+
static char *virt_get_gic_version(Object *obj, Error **errp)
{
VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -3726,6 +3780,13 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data)
"in ACPI table header."
"The string may be up to 8 bytes in size");
+ object_class_property_add_bool(oc, "pci-pre-enum",
+ virt_get_pci_pre_enum,
+ virt_set_pci_pre_enum);
+ object_class_property_set_description(oc, "pci-pre-enum",
+ "Set on/off to enable/disable PCI enumeration and resource assignment"
+ " in QEMU. When enabled, QEMU programs BARs (including fixed-bars"
+ " addresses) before handing control to firmware.");
}
static void virt_instance_init(Object *obj)
@@ -3768,6 +3829,9 @@ static void virt_instance_init(Object *obj)
/* MTE is disabled by default. */
vms->mte = false;
+ /* PCI pre-enumeration disabled by default */
+ vms->pci_pre_enum = false;
+
/* Supply kaslr-seed and rng-seed by default */
vms->dtb_randomness = true;
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 410df857c7..0786f4a4fc 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -187,6 +187,7 @@ struct VirtMachineState {
MemoryRegion *sysmem;
MemoryRegion *secure_sysmem;
bool pci_preserve_config;
+ bool pci_pre_enum;
hwaddr override_pcie_mmio_base;
hwaddr override_pcie_mmio_size;
};
--
2.34.1
next prev parent reply other threads:[~2026-05-08 20:43 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-08 18:37 [RFC PATCH 0/8] hw/arm/virt, hw/pci: PCI pre-enumeration and fixed BAR allocation Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 1/8] hw/pci: add fixed-bars property to allow fixed BAR addresses Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 2/8] hw/pci: enumerate PCI bus and program bridge bus numbers Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 3/8] hw/pci: introduce allocator for fixed BAR placement Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 4/8] hw/pci: pack remaining BARs and update bridge windows Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 5/8] hw/pci: allocate remaining BARs for buses without fixed BARs Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 6/8] hw/pci: finalize bridge prefetch windows after BAR allocation Tushar Dave
2026-05-08 18:37 ` [RFC PATCH 7/8] hw/arm/virt: add pcie-mmio-window machine property Tushar Dave
2026-05-08 18:37 ` Tushar Dave [this message]
2026-05-11 7:46 ` [RFC PATCH 0/8] hw/arm/virt, hw/pci: PCI pre-enumeration and fixed BAR allocation Peter Maydell
2026-05-11 12:26 ` Jason Gunthorpe
2026-05-11 18:38 ` Mohamed Mediouni
2026-05-11 20:28 ` Jason Gunthorpe
2026-05-11 9:09 ` Michael S. Tsirkin
2026-05-11 18:10 ` Tushar Dave
2026-05-11 22:09 ` Michael S. Tsirkin
2026-05-11 11:43 ` [edk2-devel] " Ard Biesheuvel
2026-05-12 17:25 ` Tushar Dave
2026-05-12 23:06 ` Alex Williamson
2026-05-12 23:12 ` Michael S. Tsirkin
2026-05-12 23:57 ` Alex Williamson
2026-05-13 11:36 ` Jason Gunthorpe
2026-05-13 14:25 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260508183717.193630-9-tdave@nvidia.com \
--to=tdave@nvidia.com \
--cc=alwilliamson@nvidia.com \
--cc=devel@edk2.groups.io \
--cc=jgg@nvidia.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=skolothumtho@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.