x86_64: Calgary - Fix mis-handled PCI topology

Current code assumed that devices were directly connected to a Calgary
bridge, as it tried to get the iommu table directly from the parent bus
controller.

When we have another bridge between the Calgary/CalIOC2 bridge and the
device we should look upwards until we get to the top (Calgary/CalIOC2
bridge), where the iommu table resides.

Signed-off-by: Murillo Fernandes Bernardes <mfb@br.ibm.com>
Signed-off-by: Muli Ben-Yehuda <muli@il.ibm.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by Murillo Fernandes Bernardes and committed by Linus Torvalds f055a061 3320ad99

+6 -7
+6 -7
arch/x86_64/kernel/pci-calgary.c
··· 367 368 pdev = to_pci_dev(dev); 369 370 - /* is the device behind a bridge? */ 371 - if (unlikely(pdev->bus->parent)) 372 - pbus = pdev->bus->parent; 373 - else 374 - pbus = pdev->bus; 375 376 tbl = pci_iommu(pbus); 377 378 - BUG_ON(pdev->bus->parent && 379 - (tbl->it_busno != pdev->bus->parent->number)); 380 381 return tbl; 382 }
··· 367 368 pdev = to_pci_dev(dev); 369 370 + pbus = pdev->bus; 371 + 372 + /* is the device behind a bridge? Look for the root bus */ 373 + while (pbus->parent) 374 + pbus = pbus->parent; 375 376 tbl = pci_iommu(pbus); 377 378 + BUG_ON(tbl && (tbl->it_busno != pbus->number)); 379 380 return tbl; 381 }