The following call tree exposes a bug in the lifetime (ie. too late
creation) of PciIoDevice->DevicePath. The bug can be triggered when
PciBusDxe is built into OVMF, with qemu/KVM device assignment of
a PCI-express device on the default 440FX machine type. OVMF
correctly discovers that the device is PCIe and begins probing
extended configuration space for the device. The root bridge
has no way to access extended config space and correctly errors,
sending us into the error reporting chain seen below. It's
possible that this error path could also be reproduced on physical
hardware when a PCI-to-PCIe bridge is present.
- CreatePciIoDevice() allocates a zeroed out PCI_IO_DEVICE structure.
- PciIoConfigRead() tries to access the (extended) config space, and
- PciIoConfigRead() wants to report a status code (read error) for the
- Unfortuantely, PciIoDevice->DevicePath is still NULL at that point.
- The ASSERT() in ReportStatusCodeWithDevicePath() fires.
Fix it by moving CreatePciDevicePath() into CreatePciIoDevice(),
allowing PciIoDevice->DevicePath to be initialized before we
begin probing the device capabilities: