]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Fix bug on SRIOV ReservedBusNum when ARI enable.
authorFoster Nong <foster.nong@intel.com>
Wed, 12 Oct 2022 02:36:56 +0000 (10:36 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 14 Oct 2022 07:07:01 +0000 (07:07 +0000)
If a device which support both features SR-IOV/ARI  has multi
functions, which maybe support 8-255. After enable ARI forwarding in
the root port and ARI Capable Hierarchy in the SR-IOV PF0.
The device will support and expose multi functions(0-255) with ARI ID routing.
In next device loop in below for() code, actually it still be in the
same SR-IOV device, and just some PF which is over 8 or higher
one(n*8), PciAllocateBusNumber() will allocate bus
number(ReservedBusNum - TempReservedBusNum)) for this PF. if reset
TempReservedBusNum as 0 in this case,it will allocate wrong bus number
for this PF because TempReservedBusNum should be total previous PF's
reserved bus numbers.

code:
  for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {
    TempReservedBusNum = 0;
    for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {
    //
    // Check to see whether a pci device is present
    //
    Status = PciDevicePresent (
                 PciRootBridgeIo,
                 &Pci,
                 StartBusNumber,
                 Device,
                 Func
                 );
    ...
    Status = PciAllocateBusNumber (PciDevice, *SubBusNumber,
    (UINT8)(PciDevice->ReservedBusNum - TempReservedBusNum), SubBusNumber);

The solution is add a new flag IsAriEnabled to help handle this case.
if ARI is enabled, then TempReservedBusNum will not be reset again
during all functions(1-255) scan with checking flag IsAriEnabled.

Signed-off-by: Foster Nong <foster.nong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c

index 4b58c3ea9b7ffd00dc7c80050fa7971dad9a6eb2..ca5c06204deca8f5289b4dfaa5fd6265d22fb75d 100644 (file)
@@ -262,6 +262,7 @@ struct _PCI_IO_DEVICE {
   EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR            *BusNumberRanges;\r
 \r
   BOOLEAN                                      IsPciExp;\r
+  BOOLEAN                                      IsAriEnabled;\r
   //\r
   // For SR-IOV\r
   //\r
index bc20da1f386e156952eaa6ca026deca88040f9b8..8eca85969580ca25e31c30d223a2dfc566139b69 100644 (file)
@@ -2286,6 +2286,7 @@ CreatePciIoDevice (
                          &Data32\r
                          );\r
       if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {\r
+        PciIoDevice->IsAriEnabled = TRUE;\r
         //\r
         // ARI forward support in bridge, so enable it.\r
         //\r
index d5e3ef4d3f5f80d079419141734beb36637a6995..84fc0161a19c889cb7ec2b9a4eef10b195fede4a 100644 (file)
@@ -1106,6 +1106,7 @@ PciScanBus (
   EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *PciRootBridgeIo;\r
   BOOLEAN                            BusPadding;\r
   UINT32                             TempReservedBusNum;\r
+  BOOLEAN                            IsAriEnabled;\r
 \r
   PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
   SecondBus       = 0;\r
@@ -1116,9 +1117,13 @@ PciScanBus (
   BusPadding      = FALSE;\r
   PciDevice       = NULL;\r
   PciAddress      = 0;\r
+  IsAriEnabled    = FALSE;\r
 \r
   for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
-    TempReservedBusNum = 0;\r
+    if (!IsAriEnabled) {\r
+      TempReservedBusNum = 0;\r
+    }\r
+\r
     for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
       //\r
       // Check to see whether a pci device is present\r
@@ -1158,6 +1163,27 @@ PciScanBus (
         continue;\r
       }\r
 \r
+      //\r
+      // Per Pcie spec ARI Extended Capability\r
+      // This capability must be implemented by each function in an ARI device.\r
+      // It is not applicable to a Root Port, a Switch Downstream Port, an RCiEP, or a Root Complex Event Collector\r
+      //\r
+      if (((Device == 0) && (Func == 0)) && (PciDevice->IsAriEnabled)) {\r
+        IsAriEnabled = TRUE;\r
+      }\r
+\r
+      if (PciDevice->IsAriEnabled != IsAriEnabled) {\r
+        DEBUG ((\r
+          DEBUG_ERROR,\r
+          "ERROR: %02x:%02x:%02x device ARI Feature(%x) is not consistent with others Function\n",\r
+          StartBusNumber,\r
+          Device,\r
+          Func,\r
+          PciDevice->IsAriEnabled\r
+          ));\r
+        return EFI_DEVICE_ERROR;\r
+      }\r
+\r
       PciAddress = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0);\r
 \r
       if (!IS_PCI_BRIDGE (&Pci)) {\r