The soft filter system introduced by commit 11c141672045f ("drm/amdgpu:
Fix VFCT bus number matching with soft filter") has a deficiency that
it won't work when there are multiple GPUs of the exact same model.

As it was introduced specifically to help the case of pci=realloc, gate
it to only run when that's in use.

Fixes: 11c141672045f ("drm/amdgpu: Fix VFCT bus number matching with soft 
filter")
Reported-by: Reza Nikzad Chaleshori <[email protected]>
Closes: 
https://lore.kernel.org/amd-gfx/[email protected]/
Signed-off-by: Mario Limonciello <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c | 15 ++++++++-------
 drivers/pci/setup-bus.c                  |  5 +++++
 include/linux/pci.h                      |  1 +
 3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
index 08ed1eb695586..75af9a59671ae 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c
@@ -384,12 +384,10 @@ static bool amdgpu_read_disabled_bios(struct 
amdgpu_device *adev)
  * @vhdr: VFCT image header to check
  *
  * VFCT entries contain the PCI bus number as recorded during BIOS POST.
- * On systems where the kernel renumbers PCI buses (e.g. pci=realloc or
- * resource conflicts), the runtime bus number may differ from the POST
- * value.  Match by device identity (vendor + device + function) and use
- * the bus number as a preference: exact bus match is preferred, but when
- * the bus numbers disagree we accept the entry if the device identity
- * matches.
+ * On systems where the user requested PCI resource reallocation, the
+ * runtime bus number may differ from the POST value. Match by device
+ * identity (vendor + device + function), but only treat the bus number as
+ * a preference when pci=realloc was explicitly requested.
  *
  * Returns: 0 on match, -ENODEV on no match
  */
@@ -409,7 +407,10 @@ static int amdgpu_acpi_vfct_match(struct amdgpu_device 
*adev,
        if (vhdr->PCIBus == adev->pdev->bus->number)
                return 0;
 
-       /* Bus mismatch but device identity matches (PCI renumbering case) */
+       /* Allow bus renumbering only when the user requested pci=realloc. */
+       if (!pci_realloc_enabled_by_user())
+               return -ENODEV;
+
        dev_notice(adev->dev,
                   "VFCT bus number mismatch: table %u != runtime %u, matching 
by device identity (vendor 0x%04x device 0x%04x)\n",
                   vhdr->PCIBus, adev->pdev->bus->number,
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index ed16ef7c26fa7..d9450585082c0 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -1799,6 +1799,11 @@ static bool pci_realloc_enabled(enum enable_type enable)
        return enable >= user_enabled;
 }
 
+bool pci_realloc_enabled_by_user(void)
+{
+       return pci_realloc_enable == user_enabled;
+}
+
 #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO)
 static int iov_resources_unassigned(struct pci_dev *dev, void *data)
 {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index d31a8d107b1ef..844734da9250f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -610,6 +610,7 @@ static inline struct pci_dev *pci_physfn(struct pci_dev 
*dev)
 }
 
 struct pci_dev *pci_alloc_dev(struct pci_bus *bus);
+bool pci_realloc_enabled_by_user(void);
 
 #define        to_pci_dev(n) container_of(n, struct pci_dev, dev)
 #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, 
d)) != NULL)
-- 
2.43.0

Reply via email to