From: Yinghai Lu <yinghai@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Tony Luck <tony.luck@intel.com>,
David Miller <davem@davemloft.net>, x86 <x86@kernel.org>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arch@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH -v12 14/15] PCI: More strict checking of valid range for bridge
Date: Tue, 26 Jun 2012 11:54:08 -0700 [thread overview]
Message-ID: <1340736849-14875-15-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1340736849-14875-1-git-send-email-yinghai@kernel.org>
Found one sick system with two sibling bridge have overlaping range from BIOS.
00:02.1 bus range is 0x30-0x30
00:02.2 bus range is 0x30-0x3f, and it have two children under it.
RHEL 6.2 kernel, will just 00:02.1 have child bus 0x30, and bridge 00:02.2 will
not have.
before this patch, this patchset will have 00:02.1 to have bus 0x30,
and 00:02.2 will have reallocate range bus 01.
but 00:02.1 will have scaned at first, so later it will have two fake devices.
To fix the problem, We need to check with unscaned sibling bridge about range
overlapping.
If there is overlapping found, will mark both sides to be broken.
So we could prevent one side take too big range.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/probe.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 44 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 93b61b8..118fe5b 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -743,6 +743,48 @@ static int __devinit pci_bridge_probe_busn_res(struct pci_bus *bus,
return ret;
}
+static int __devinit pci_bridge_check_busn_broken_with_unscaned(
+ struct pci_bus *bus,
+ struct pci_dev *dev,
+ int secondary, int subordinate)
+{
+ u32 buses2;
+ int broken = 0;
+ struct pci_dev *dev2;
+ int secondary2, subordinate2;
+ int common_start, common_end;
+
+ /* need to check with not scaned sibling bridges */
+ list_for_each_entry(dev2, &bus->devices, bus_list) {
+ if (dev2->hdr_type != PCI_HEADER_TYPE_BRIDGE &&
+ dev2->hdr_type != PCI_HEADER_TYPE_CARDBUS)
+ continue;
+ if (dev2->subordinate)
+ continue;
+ if (dev2 == dev)
+ continue;
+
+ pci_read_config_dword(dev2, PCI_PRIMARY_BUS, &buses2);
+ secondary2 = (buses2 >> 8) & 0xFF;
+ subordinate2 = (buses2 >> 16) & 0xFF;
+
+ /* overlapping between them ? */
+ common_start = max(secondary, secondary2);
+ common_end = min(subordinate, subordinate2);
+ if (common_start <= common_end) {
+ /*
+ * Temporarily disable forwarding of the
+ * configuration cycles on this sibling bridge
+ */
+ pci_write_config_dword(dev2, PCI_PRIMARY_BUS,
+ buses2 & ~0xffffff);
+ broken = 1;
+ }
+ }
+
+ return broken;
+}
+
static int __devinit pci_bridge_check_busn_broken(struct pci_bus *bus,
struct pci_dev *dev,
int secondary, int subordinate)
@@ -763,7 +805,8 @@ static int __devinit pci_bridge_check_busn_broken(struct pci_bus *bus,
release_resource(&busn_res);
- return 0;
+ return pci_bridge_check_busn_broken_with_unscaned(bus, dev,
+ secondary, subordinate);
}
static unsigned int __devinit __pci_scan_child_bus(struct pci_bus *bus,
--
1.7.7
next prev parent reply other threads:[~2012-06-26 18:56 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-26 18:53 [PATCH -v12 00/15] PCI: allocate pci bus num range for unassigned bridge busn Yinghai Lu
2012-06-26 18:53 ` [PATCH -v12 01/15] resources: Split out __allocate_resource() Yinghai Lu
2012-06-26 18:53 ` Yinghai Lu
2012-06-26 19:01 ` Linus Torvalds
2012-06-26 19:01 ` Linus Torvalds
2012-06-26 20:33 ` Yinghai Lu
2012-06-26 20:33 ` Yinghai Lu
2012-06-26 20:43 ` Linus Torvalds
2012-06-26 20:43 ` Linus Torvalds
2012-06-26 18:53 ` [PATCH -v12 02/15] resources: Add probe_resource() Yinghai Lu
2012-06-26 18:53 ` Yinghai Lu
2012-06-26 22:07 ` Yinghai Lu
2012-08-28 16:09 ` Yinghai Lu
2012-08-28 16:09 ` Yinghai Lu
2012-08-28 17:05 ` Linus Torvalds
2012-08-29 0:10 ` Linus Torvalds
2012-08-29 0:10 ` Linus Torvalds
2012-08-29 10:14 ` Ram Pai
2012-08-29 16:02 ` Yinghai Lu
2012-08-29 16:02 ` Yinghai Lu
2012-08-29 15:57 ` Yinghai Lu
2012-08-29 15:57 ` Yinghai Lu
2012-08-29 17:36 ` Yinghai Lu
2012-08-29 17:36 ` Yinghai Lu
2012-08-31 0:40 ` Bjorn Helgaas
2012-08-31 0:40 ` Bjorn Helgaas
2012-06-26 18:53 ` [PATCH -v12 03/15] resources: Replace registered resource in tree Yinghai Lu
2012-06-26 18:53 ` Yinghai Lu
2012-06-26 18:53 ` [PATCH -v12 04/15] PCI: Add pci_bus_extend/shrink_top() Yinghai Lu
2012-06-26 18:53 ` Yinghai Lu
2012-06-26 18:53 ` [PATCH -v12 05/15] PCI: Probe safe range that we can use for unassigned bridge Yinghai Lu
2012-06-26 18:53 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 06/15] PCI: Add pci_bus_replace_busn_res() Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 07/15] PCI: Allocate bus range instead of use max blindly Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 08/15] PCI: Strict checking of valid range for bridge Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 09/15] PCI: Kill pci_fixup_parent_subordinate_busnr() Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 10/15] PCI: Seperate child bus scanning to two passes overall Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 11/15] pcmcia: Remove workaround for fixing pci parent bus subordinate Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 12/15] PCI: Double checking setting for bus register and bus struct Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` [PATCH -v12 13/15] PCI, pciehp: Remove not needed bus number range checking Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu [this message]
2012-06-26 18:54 ` [PATCH -v12 15/15] PCI: Don't shrink too much for hotplug bridge Yinghai Lu
2012-06-26 18:54 ` Yinghai Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1340736849-14875-15-git-send-email-yinghai@kernel.org \
--to=yinghai@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=benh@kernel.crashing.org \
--cc=bhelgaas@google.com \
--cc=davem@davemloft.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux@dominikbrodowski.net \
--cc=tony.luck@intel.com \
--cc=torvalds@linux-foundation.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).