Commit 3be5fa236649 ("Revert "iommu/amd: Prevent binding other PCI
drivers to IOMMU PCI devices"") had an unintended side effect in that
when looking for any AGP bridge, driver_attach() will try to bind to
IOMMU devices without preemptively checking for PCI_CAP_ID_AGP
capability. This happens during agp_amd64_init().

As a result, driver_attach() calls driver_probe_device(), which then
calls really_probe(), raising this critical condition:

 pci 0000:00:00.2: Resources present before probing

With the device being:

 00:00.2 IOMMU: Advanced Micro Devices, Inc. [AMD] Raven/Raven2 IOMMU
        Subsystem: Advanced Micro Devices, Inc. [AMD] Raven/Raven2 IOMMU
        Flags: bus master, fast devsel, latency 0, IRQ 25
        Capabilities: [40] Secure device <?>
        Capabilities: [64] MSI: Enable+ Count=1/4 Maskable- 64bit+
        Capabilities: [74] HyperTransport: MSI Mapping Enable+ Fixed+

As pci_register_driver() calls the device's probing function, the latter
(agp_amd64_probe) tries to find the device's PCI_CAP_ID_AGP capability,
and returns -ENODEV if said capability is not found.

Do not attempt driver_attach() if agp_amd64_pci_driver.probe is non-zero
to avoid probing already present resources.

Link: https://lore.kernel.org/all/afjolz88kih5w...@wunner.de

Signed-off-by: Ahmed Salem <x0rw...@gmail.com>
---
I'm not quite sure whether I should have maintained the linked
conversation's Ccs, so please let me know if I should Cc anyone else.

Lukas, kindly let me know whether you want me to add a Suggested-by
trailer as well.


diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index bf490967241a..e6a0d09e115a 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -768,10 +768,15 @@ int __init agp_amd64_init(void)
 
                /* Look for any AGP bridge */
                agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table;
-               err = driver_attach(&agp_amd64_pci_driver.driver);
-               if (err == 0 && agp_bridges_found == 0) {
+               if ((int *)agp_amd64_pci_driver.probe != 0) {
                        pci_unregister_driver(&agp_amd64_pci_driver);
                        err = -ENODEV;
+               } else {
+                       err = driver_attach(&agp_amd64_pci_driver.driver);
+                       if (err == 0 && agp_bridges_found == 0) {
+                               pci_unregister_driver(&agp_amd64_pci_driver);
+                               err = -ENODEV;
+                       }
                }
        }
        return err;

base-commit: 11313e2f78128c948e9b4eb58b3dacfc30964700
-- 
2.47.2

Reply via email to