From: Murillo Fernandes Bernardes Date: Fri, 10 Aug 2007 20:31:00 +0000 (+0200) Subject: x86_64: Calgary - Fix mis-handled PCI topology X-Git-Tag: firefly_0821_release~26805 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f055a0619aae795832ef6a783021184925758b67;p=firefly-linux-kernel-4.4.55.git 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 Signed-off-by: Muli Ben-Yehuda Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index ba16c968ca3f..71da01e73f03 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -367,16 +367,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev) pdev = to_pci_dev(dev); - /* is the device behind a bridge? */ - if (unlikely(pdev->bus->parent)) - pbus = pdev->bus->parent; - else - pbus = pdev->bus; + pbus = pdev->bus; + + /* is the device behind a bridge? Look for the root bus */ + while (pbus->parent) + pbus = pbus->parent; tbl = pci_iommu(pbus); - BUG_ON(pdev->bus->parent && - (tbl->it_busno != pdev->bus->parent->number)); + BUG_ON(tbl && (tbl->it_busno != pbus->number)); return tbl; }