\r
@param[in] NoExtendedConfigSpace No Extended Config Space.\r
\r
+ @param[in] BusMin Minimum Bus number, inclusive.\r
+\r
+ @param[in] BusMax Maximum Bus number, inclusive.\r
+\r
@param[in] Io IO aperture.\r
\r
@param[in] Mem MMIO aperture.\r
IN UINT64 AllocationAttributes,\r
IN BOOLEAN DmaAbove4G,\r
IN BOOLEAN NoExtendedConfigSpace,\r
+ IN UINTN BusMin,\r
+ IN UINTN BusMax,\r
IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
\r
@param[in] NoExtendedConfigSpace No Extended Config Space.\r
\r
+ @param[in] BusMin Minimum Bus number, inclusive.\r
+\r
+ @param[in] BusMax Maximum Bus number, inclusive.\r
+\r
@param[in] Io IO aperture.\r
\r
@param[in] Mem MMIO aperture.\r
IN UINT64 AllocationAttributes,\r
IN BOOLEAN DmaAbove4G,\r
IN BOOLEAN NoExtendedConfigSpace,\r
+ IN UINTN BusMin,\r
+ IN UINTN BusMax,\r
IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
\r
*Count = 0;\r
\r
+ if (BusMin > BusMax || BusMax > PCI_MAX_BUS) {\r
+ DEBUG ((DEBUG_ERROR, "%a: invalid bus range with BusMin %Lu and BusMax "\r
+ "%Lu\n", __FUNCTION__, (UINT64)BusMin, (UINT64)BusMax));\r
+ return NULL;\r
+ }\r
+\r
//\r
// QEMU provides the number of extra root buses, shortening the exhaustive\r
// search below. If there is no hint, the feature is missing.\r
QemuFwCfgSelectItem (FwCfgItem);\r
QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges);\r
\r
- if (ExtraRootBridges > PCI_MAX_BUS) {\r
+ //\r
+ // Validate the number of extra root bridges. As BusMax is inclusive, the\r
+ // max bus count is (BusMax - BusMin + 1). From that, the "main" root bus\r
+ // is always a given, so the max count for the "extra" root bridges is one\r
+ // less, i.e. (BusMax - BusMin). If the QEMU hint exceeds that, we have\r
+ // invalid behavior.\r
+ //\r
+ if (ExtraRootBridges > BusMax - BusMin) {\r
DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) "\r
"reported by QEMU\n", __FUNCTION__, ExtraRootBridges));\r
return NULL;\r
//\r
// The "main" root bus is always there.\r
//\r
- LastRootBridgeNumber = 0;\r
+ LastRootBridgeNumber = BusMin;\r
\r
//\r
// Scan all other root buses. If function 0 of any device on a bus returns a\r
// VendorId register value different from all-bits-one, then that bus is\r
// alive.\r
//\r
- for (RootBridgeNumber = 1;\r
- RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;\r
+ for (RootBridgeNumber = BusMin + 1;\r
+ RootBridgeNumber <= BusMax && Initialized < ExtraRootBridges;\r
++RootBridgeNumber) {\r
UINTN Device;\r
\r
DmaAbove4G,\r
NoExtendedConfigSpace,\r
(UINT8) LastRootBridgeNumber,\r
- PCI_MAX_BUS,\r
+ (UINT8) BusMax,\r
Io,\r
Mem,\r
MemAbove4G,\r