On 11/4/2026 3:59 AM, Ard Biesheuvel wrote:
>
>
> On Mon, 2 Nov 2026, at 19:12, Tushar Dave wrote:
>> Introduce a fixed BAR fw_cfg blob exporter that serializes PCI
>> device and BAR information into the "etc/fixed-bars" fw_cfg file.
>>
>> The blob contains an entry for every PCI function with memory BARs.
>> Each entry carries the device's vendor and device ID, whether it
>> has a fixed BAR configuration, and its firmware device path. Fixed
>> BAR entries also include the configured BAR address, size, and type
>> information for each BAR.
>>
>> Document the format in docs/specs/pci-fixed-bars.rst.
>>
>> Signed-off-by: Tushar Dave <[email protected]>
>> ---
>> docs/specs/index.rst | 1 +
>> docs/specs/pci-fixed-bars.rst | 75 ++++++++
>> hw/pci/meson.build | 1 +
>> hw/pci/pci-fixed-bar-blob.c | 308 +++++++++++++++++++++++++++++++++
>> include/hw/pci/pci-fixed-bar.h | 63 +++++++
>> 5 files changed, 448 insertions(+)
>> create mode 100644 docs/specs/pci-fixed-bars.rst
>> create mode 100644 hw/pci/pci-fixed-bar-blob.c
>> create mode 100644 include/hw/pci/pci-fixed-bar.h
>>
> ...
>> diff --git a/hw/pci/pci-fixed-bar-blob.c b/hw/pci/pci-fixed-bar-blob.c
>> new file mode 100644
>> index 0000000000..dc94debfad
>> --- /dev/null
>> +++ b/hw/pci/pci-fixed-bar-blob.c
> ...
>> +/*
>> + * EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL's CheckDevice interface
>> + * (UEFI PI Spec 1.2 Vol 5) only passes VendorId/DeviceId/RevisionId/
>> + * SubsystemVendorId/SubsystemDeviceId, no BDF — so in EDK2 we can't
>> + * match a blob entry to a specific device directly using BDF. To work
>> + * around that, we prepare the blob entries in the same order PciBusDxe
>> + * discovers devices, so matching by VID:DID inherently works.
>
> This sounds rather fragile.
>
> Could you elaborate on what order this is, and why it is reasonable to
> rely on that approach being stable?
PciBusDxe discovers devices using the conventional PCI enumeration
order: devices and functions in ascending order on each bus, visiting
a bridge's secondary bus immediately after discovering the bridge
(depth-first), and root bridges one after another. CheckDevice() is
called for every function discovered, including bridges. QEMU exports
the entries in the same order. For each VendorId/DeviceId pair,
IncompatiblePciDeviceSupportDxe maintains a counter, and each
CheckDevice() call for a matching device consumes the next
corresponding entry from the blob. Accordingly, the blob contains an
entry for every function with a memory BAR, whether fixed or not, to
keep the matching simple and in sync.
I think relying on this order is reasonable because it is determined
by the PCI topology configured on the QEMU command line. Since devices
with fixed BARs cannot be hot-plugged, they are always present at
boot, and the resulting discovery order remains stable across boots
of a given VM.
-Tushar