* [PATCH 00/10] PCI: clip firmware assigned resources
@ 2015-01-12 19:23 Yinghai Lu
2015-01-12 19:23 ` [PATCH 01/10] PCI: clip firmware assigned resource under parent bridge's Yinghai Lu
` (9 more replies)
0 siblings, 10 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, linux-kernel, Yinghai Lu
During the fix https://bugzilla.kernel.org/show_bug.cgi?id=85491,
Bjorn suggest that we should clip the resources instead of just
reject them.
We should only need first two for x86. others for related arches
to keep them consistent.
Thanks
Yinghai
Yinghai Lu (10):
PCI: clip firmware assigned resource under parent bridge's
PCI, x86: clip firmware assigned resource under parent bridge's
PCI, alpha: clip firmware assigned resource under parent bridge's
PCI, frv: clip firmware assigned resource under parent bridge's
PCI, ia64: clip firmware assigned resource under parent bridge's
PCI, microblaze: clip firmware assigned resource under parent bridge's
PCI, mn10300: clip firmware assigned resource under parent bridge's
PCI, parisc: clip firmware assigned resource under parent bridge's
PCI, powerpc: clip firmware assigned resource under parent bridge's
PCI, sparc: clip firmware assigned resource under parent bridge's
arch/alpha/kernel/pci.c | 24 ++++++++++-
arch/frv/mb93090-mb00/pci-frv.c | 33 ++++++++++++---
arch/ia64/pci/pci.c | 71 +++++++++++++++++++------------
arch/microblaze/pci/pci-common.c | 42 ++++++++++++++++++-
arch/mn10300/unit-asb2305/pci-asb2305.c | 61 ++++++++++++++++++---------
arch/mn10300/unit-asb2305/pci.c | 69 ++++++++++++++++++------------
arch/powerpc/kernel/pci-common.c | 43 ++++++++++++++++++-
arch/sparc/kernel/pci.c | 20 ++++++++-
arch/x86/pci/i386.c | 74 +++++++++++++++++++++++----------
drivers/parisc/lba_pci.c | 26 +++++++++++-
drivers/pci/bus.c | 37 +++++++++++++++++
include/linux/pci.h | 1 +
12 files changed, 394 insertions(+), 107 deletions(-)
--
1.8.4.5
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 01/10] PCI: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 02/10] PCI, x86: " Yinghai Lu
` (8 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, linux-kernel, Yinghai Lu
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
This one is core part, arch changes will be in following patches.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/bus.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 1 +
2 files changed, 38 insertions(+)
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 73aef51..d29b252 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -228,6 +228,43 @@ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
}
EXPORT_SYMBOL(pci_bus_alloc_resource);
+bool pci_bus_clip_resource(struct pci_dev *dev, struct resource *res)
+{
+ struct pci_bus *bus = dev->bus;
+ resource_size_t start, end;
+ struct resource orig_res = *res;
+ struct resource *r;
+ int i;
+
+ pci_bus_for_each_resource(bus, r, i) {
+ if (!r)
+ continue;
+
+ if (resource_type(res) != resource_type(r))
+ continue;
+
+ start = max(r->start, res->start);
+ end = min(r->end, res->end);
+
+ /* no overlap ? */
+ if (start > end)
+ continue;
+
+ if (res->start == start && res->end == end)
+ return false;
+
+ /* changed */
+ res->start = start;
+ res->end = end;
+ dev_printk(KERN_DEBUG, &dev->dev, "%pR ==> %pR\n",
+ &orig_res, res);
+
+ return true;
+ }
+
+ return false;
+}
+
void __weak pcibios_resource_survey_bus(struct pci_bus *bus) { }
/**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 360a966..e140627 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1094,6 +1094,7 @@ void pci_free_resource_list(struct list_head *resources);
void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags);
struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n);
void pci_bus_remove_resources(struct pci_bus *bus);
+bool pci_bus_clip_resource(struct pci_dev *dev, struct resource *res);
#define pci_bus_for_each_resource(bus, res, i) \
for (i = 0; \
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 02/10] PCI, x86: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
2015-01-12 19:23 ` [PATCH 01/10] PCI: clip firmware assigned resource under parent bridge's Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-14 16:52 ` Bjorn Helgaas
2015-01-12 19:23 ` [PATCH 03/10] PCI, alpha: " Yinghai Lu
` (7 subsequent siblings)
9 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, x86
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Tested-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
---
arch/x86/pci/i386.c | 74 +++++++++++++++++++++++++++++++++++++----------------
1 file changed, 52 insertions(+), 22 deletions(-)
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 9b18ef3..d43e1af 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -205,10 +205,11 @@ EXPORT_SYMBOL(pcibios_align_resource);
* as well.
*/
-static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
+static bool pcibios_allocate_bridge_resources(struct pci_dev *dev)
{
int idx;
struct resource *r;
+ bool changed = false;
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
@@ -216,17 +217,33 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
continue;
if (r->parent) /* Already allocated */
continue;
- if (!r->start || pci_claim_resource(dev, idx) < 0) {
- /*
- * Something is wrong with the region.
- * Invalidate the resource to prevent
- * child resource allocations in this
- * range.
- */
- r->start = r->end = 0;
- r->flags = 0;
+
+ if (!r->start)
+ goto clear;
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again after clip for pci bridge*/
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
}
+
+clear:
+ /*
+ * Something is wrong with the region.
+ * Invalidate the resource to prevent
+ * child resource allocations in this
+ * range.
+ */
+ r->start = r->end = 0;
+ r->flags = 0;
}
+
+ return changed;
}
static void pcibios_allocate_bus_resources(struct pci_bus *bus)
@@ -234,8 +251,12 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
struct pci_bus *child;
/* Depth-First Search on bus tree */
- if (bus->self)
- pcibios_allocate_bridge_resources(bus->self);
+ if (bus->self) {
+ bool changed = pcibios_allocate_bridge_resources(bus->self);
+
+ if (changed)
+ pci_setup_bridge(bus);
+ }
list_for_each_entry(child, &bus->children, node)
pcibios_allocate_bus_resources(child);
}
@@ -274,18 +295,27 @@ static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass)
dev_dbg(&dev->dev,
"BAR %d: reserving %pr (d=%d, p=%d)\n",
idx, r, disabled, pass);
- if (pci_claim_resource(dev, idx) < 0) {
- if (r->flags & IORESOURCE_PCI_FIXED) {
- dev_info(&dev->dev, "BAR %d %pR is immovable\n",
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ if (r->flags & IORESOURCE_PCI_FIXED) {
+ dev_info(&dev->dev, "BAR %d %pR is immovable\n",
idx, r);
- } else {
- /* We'll assign a new address later */
- pcibios_save_fw_addr(dev,
- idx, r->start);
- r->end -= r->start;
- r->start = 0;
- }
+ continue;
+ }
+
+ /* try again with clip */
+ if (pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
}
+
+ /* We'll assign a new address later */
+ pcibios_save_fw_addr(dev, idx, r->start);
+ r->end -= r->start;
+ r->start = 0;
}
}
if (!pass) {
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 03/10] PCI, alpha: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
2015-01-12 19:23 ` [PATCH 01/10] PCI: clip firmware assigned resource under parent bridge's Yinghai Lu
2015-01-12 19:23 ` [PATCH 02/10] PCI, x86: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 04/10] PCI, frv: " Yinghai Lu
` (6 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, Richard Henderson,
Ivan Kokshaysky, Matt Turner, linux-alpha
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: linux-alpha@vger.kernel.org
---
arch/alpha/kernel/pci.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 076c35c..b54b40f 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -277,6 +277,7 @@ pcibios_claim_one_bus(struct pci_bus *b)
struct pci_bus *child_bus;
list_for_each_entry(dev, &b->devices, bus_list) {
+ bool changed = false;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -285,9 +286,28 @@ pcibios_claim_one_bus(struct pci_bus *b)
if (r->parent || !r->start || !r->flags)
continue;
if (pci_has_flag(PCI_PROBE_ONLY) ||
- (r->flags & IORESOURCE_PCI_FIXED))
- pci_claim_resource(dev, i);
+ (r->flags & IORESOURCE_PCI_FIXED)) {
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+
+ if (dev->subordinate &&
+ i >= PCI_BRIDGE_RESOURCES &&
+ i < PCI_NUM_RESOURCES &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, i);
+ } else if (i < PCI_BRIDGE_RESOURCES &&
+ i != PCI_ROM_RESOURCE &&
+ pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, i);
+ pci_claim_resource(dev, i);
+ }
+ }
}
+
+ if (changed)
+ pci_setup_bridge(dev->subordinate);
}
list_for_each_entry(child_bus, &b->children, node)
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 04/10] PCI, frv: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (2 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 03/10] PCI, alpha: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 05/10] PCI, ia64: " Yinghai Lu
` (5 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, David Howells,
Paul Gortmaker
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
---
arch/frv/mb93090-mb00/pci-frv.c | 33 ++++++++++++++++++++++++++++-----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/arch/frv/mb93090-mb00/pci-frv.c b/arch/frv/mb93090-mb00/pci-frv.c
index 67b1d16..f4e36f6 100644
--- a/arch/frv/mb93090-mb00/pci-frv.c
+++ b/arch/frv/mb93090-mb00/pci-frv.c
@@ -90,12 +90,26 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
bus = list_entry(ln, struct pci_bus, node);
if ((dev = bus->self)) {
+ bool changed = false;
+
for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
r = &dev->resource[idx];
if (!r->start)
continue;
- pci_claim_resource(dev, idx);
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again after clip for pci bridge*/
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, idx);
+ }
}
+
+ if (changed)
+ pci_setup_bridge(bus);
}
pcibios_allocate_bus_resources(&bus->children);
}
@@ -123,11 +137,20 @@ static void __init pcibios_allocate_resources(int pass)
if (pass == disabled) {
DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
r->start, r->end, r->flags, disabled, pass);
- if (pci_claim_resource(dev, idx) < 0) {
- /* We'll assign a new address later */
- r->end -= r->start;
- r->start = 0;
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again with clip */
+ if (pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
}
+
+ /* We'll assign a new address later */
+ r->end -= r->start;
+ r->start = 0;
}
}
if (!pass) {
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 05/10] PCI, ia64: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (3 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 04/10] PCI, frv: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 06/10] PCI, microblaze: " Yinghai Lu
` (4 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, Tony Luck, Fenghua Yu,
Rafael J. Wysocki, linux-ia64
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/pci/pci.c | 71 +++++++++++++++++++++++++++++++++--------------------
1 file changed, 44 insertions(+), 27 deletions(-)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 291a582..a3f9e27 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -487,45 +487,57 @@ int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
return 0;
}
-static int is_valid_resource(struct pci_dev *dev, int idx)
+void pcibios_fixup_device_resources(struct pci_dev *dev)
{
- unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
- struct resource *devr = &dev->resource[idx], *busr;
+ int idx;
if (!dev->bus)
- return 0;
+ return;
- pci_bus_for_each_resource(dev->bus, busr, i) {
- if (!busr || ((busr->flags ^ devr->flags) & type_mask))
+ for (idx = 0; idx < PCI_BRIDGE_RESOURCES; idx++) {
+ struct resource *r = &dev->resource[idx];
+
+ if (!r->flags || r->parent || !r->start)
continue;
- if ((devr->start) && (devr->start >= busr->start) &&
- (devr->end <= busr->end))
- return 1;
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again with clip */
+ if (pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ pci_claim_resource(dev, idx);
+ }
}
- return 0;
}
+EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources);
-static void pcibios_fixup_resources(struct pci_dev *dev, int start, int limit)
+static bool pcibios_fixup_bridge_resources(struct pci_dev *dev)
{
- int i;
+ int idx;
+ bool changed = false;
+
+ if (!dev->bus)
+ return changed;
+
+ for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+ struct resource *r = &dev->resource[idx];
- for (i = start; i < limit; i++) {
- if (!dev->resource[i].flags)
+ if (!r->flags || r->parent || !r->start)
continue;
- if ((is_valid_resource(dev, i)))
- pci_claim_resource(dev, i);
- }
-}
-void pcibios_fixup_device_resources(struct pci_dev *dev)
-{
- pcibios_fixup_resources(dev, 0, PCI_BRIDGE_RESOURCES);
-}
-EXPORT_SYMBOL_GPL(pcibios_fixup_device_resources);
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
-static void pcibios_fixup_bridge_resources(struct pci_dev *dev)
-{
- pcibios_fixup_resources(dev, PCI_BRIDGE_RESOURCES, PCI_NUM_RESOURCES);
+ /* try again after clip for pci bridge*/
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, idx);
+ }
+ }
+
+ return changed;
}
/*
@@ -536,9 +548,14 @@ void pcibios_fixup_bus(struct pci_bus *b)
struct pci_dev *dev;
if (b->self) {
+ bool changed;
+
pci_read_bridge_bases(b);
- pcibios_fixup_bridge_resources(b->self);
+ changed = pcibios_fixup_bridge_resources(b->self);
+ if (changed)
+ pci_setup_bridge(b);
}
+
list_for_each_entry(dev, &b->devices, bus_list)
pcibios_fixup_device_resources(dev);
platform_pci_fixup_bus(b);
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 06/10] PCI, microblaze: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (4 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 05/10] PCI, ia64: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 07/10] PCI, mn10300: " Yinghai Lu
` (3 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, Michal Simek,
Benjamin Herrenschmidt, Sebastian Ott
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Michal Simek <monstr@monstr.eu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
---
arch/microblaze/pci/pci-common.c | 42 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index b30e41c..4ec2dd4 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -988,6 +988,7 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
struct pci_bus *b;
int i;
struct resource *res, *pr;
+ bool changed = false;
pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
pci_domain_nr(bus), bus->number);
@@ -1026,6 +1027,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
pr, (pr && pr->name) ? pr->name : "nil");
if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+ struct pci_dev *dev = bus->self;
+
if (request_resource(pr, res) == 0)
continue;
/*
@@ -1035,6 +1038,16 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
*/
if (reparent_resources(pr, res) == 0)
continue;
+
+ if (dev && i >= PCI_BRIDGE_RESOURCES &&
+ i < PCI_NUM_RESOURCES &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, res)) {
+ changed = true;
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+ }
+
}
pr_warn("PCI: Cannot allocate resource region ");
pr_cont("%d of PCI bridge %d, will remap\n", i, bus->number);
@@ -1042,6 +1055,9 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
res->flags = 0;
}
+ if (changed)
+ pci_setup_bridge(bus);
+
list_for_each_entry(b, &bus->children, node)
pcibios_allocate_bus_resources(b);
}
@@ -1059,6 +1075,12 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
pr = pci_find_parent_resource(dev, r);
if (!pr || (pr->flags & IORESOURCE_UNSET) ||
request_resource(pr, r) < 0) {
+ /* try again with clip */
+ if (idx != PCI_ROM_RESOURCE && pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ if (pci_claim_resource(dev, idx) >= 0)
+ return;
+ }
pr_warn("PCI: Cannot allocate resource region %d ", idx);
pr_cont("of device %s, will remap\n", pci_name(dev));
if (pr)
@@ -1213,6 +1235,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
struct pci_bus *child_bus;
list_for_each_entry(dev, &bus->devices, bus_list) {
+ bool changed = false;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -1227,8 +1250,25 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
(unsigned long long)r->end,
(unsigned int)r->flags);
- pci_claim_resource(dev, i);
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+
+ if (dev->subordinate &&
+ i >= PCI_BRIDGE_RESOURCES &&
+ i < PCI_NUM_RESOURCES &&
+ (dev->class >> 8) != PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, i);
+ } else if (i < PCI_BRIDGE_RESOURCES &&
+ i != PCI_ROM_RESOURCE &&
+ pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, i);
+ pci_claim_resource(dev, i);
+ }
}
+ if (changed)
+ pci_setup_bridge(dev->subordinate);
}
list_for_each_entry(child_bus, &bus->children, node)
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 07/10] PCI, mn10300: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (5 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 06/10] PCI, microblaze: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 08/10] PCI, parisc: " Yinghai Lu
` (2 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, David Howells,
Koichi Yasutake, linux-am33-list
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: David Howells <dhowells@redhat.com>
Cc: Koichi Yasutake <yasutake.koichi@jp.panasonic.com>
Cc: linux-am33-list@redhat.com
---
arch/mn10300/unit-asb2305/pci-asb2305.c | 61 +++++++++++++++++++----------
arch/mn10300/unit-asb2305/pci.c | 69 ++++++++++++++++++++-------------
2 files changed, 84 insertions(+), 46 deletions(-)
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.c b/arch/mn10300/unit-asb2305/pci-asb2305.c
index febb9cd..32ea240 100644
--- a/arch/mn10300/unit-asb2305/pci-asb2305.c
+++ b/arch/mn10300/unit-asb2305/pci-asb2305.c
@@ -99,26 +99,40 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
list_for_each_entry(bus, bus_list, node) {
dev = bus->self;
if (dev) {
+ bool changed = false;
+
for (idx = PCI_BRIDGE_RESOURCES;
idx < PCI_NUM_RESOURCES;
idx++) {
r = &dev->resource[idx];
if (!r->flags)
continue;
- if (!r->start ||
- pci_claim_resource(dev, idx) < 0) {
- printk(KERN_ERR "PCI:"
- " Cannot allocate resource"
- " region %d of bridge %s\n",
- idx, pci_name(dev));
- /* Something is wrong with the region.
- * Invalidate the resource to prevent
- * child resource allocations in this
- * range. */
- r->start = r->end = 0;
- r->flags = 0;
+ if (!r->start)
+ goto clear;
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again after clip for pci bridge*/
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
}
+
+clear:
+ pr_err("PCI: Cannot allocate resource region %d of bridge %s\n",
+ idx, pci_name(dev));
+ /* Something is wrong with the region.
+ * Invalidate the resource to prevent
+ * child resource allocations in this
+ * range. */
+ r->start = r->end = 0;
+ r->flags = 0;
}
+ if (changed)
+ pci_setup_bridge(bus);
}
pcibios_allocate_bus_resources(&bus->children);
}
@@ -148,15 +162,22 @@ static void __init pcibios_allocate_resources(int pass)
" (f=%lx, d=%d, p=%d)\n",
pci_name(dev), r->start, r->end, r->flags,
disabled, pass);
- if (pci_claim_resource(dev, idx) < 0) {
- printk(KERN_ERR "PCI:"
- " Cannot allocate resource"
- " region %d of device %s\n",
- idx, pci_name(dev));
- /* We'll assign a new address later */
- r->end -= r->start;
- r->start = 0;
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again with clip */
+ if (pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
}
+
+ pr_err("PCI: Cannot allocate resource region %d of device %s\n",
+ idx, pci_name(dev));
+ /* We'll assign a new address later */
+ r->end -= r->start;
+ r->start = 0;
}
}
if (!pass) {
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c
index 6b4339f..83caf70 100644
--- a/arch/mn10300/unit-asb2305/pci.c
+++ b/arch/mn10300/unit-asb2305/pci.c
@@ -281,43 +281,56 @@ static int __init pci_check_direct(void)
return -ENODEV;
}
-static int is_valid_resource(struct pci_dev *dev, int idx)
+static void pcibios_fixup_device_resources(struct pci_dev *dev)
{
- unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM;
- struct resource *devr = &dev->resource[idx], *busr;
-
- if (dev->bus) {
- pci_bus_for_each_resource(dev->bus, busr, i) {
- if (!busr || (busr->flags ^ devr->flags) & type_mask)
- continue;
-
- if (devr->start &&
- devr->start >= busr->start &&
- devr->end <= busr->end)
- return 1;
+ int idx;
+
+ if (!dev->bus)
+ return;
+
+ for (idx = 0; idx < PCI_BRIDGE_RESOURCES; idx++) {
+ struct resource *r = &dev->resource[idx];
+
+ if (!r->flags || r->parent || !r->start)
+ continue;
+
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again with clip */
+ if (pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ pci_claim_resource(dev, idx);
}
}
-
- return 0;
}
-static void pcibios_fixup_device_resources(struct pci_dev *dev)
+static bool pcibios_fixup_bridge_resources(struct pci_dev *dev)
{
- int limit, i;
+ int idx;
+ bool changed = false;
- if (dev->bus->number != 0)
- return;
+ if (!dev->bus)
+ return changed;
- limit = (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) ?
- PCI_BRIDGE_RESOURCES : PCI_NUM_RESOURCES;
+ for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+ struct resource *r = &dev->resource[idx];
- for (i = 0; i < limit; i++) {
- if (!dev->resource[i].flags)
+ if (!r->flags || r->parent || !r->start)
continue;
- if (is_valid_resource(dev, i))
- pci_claim_resource(dev, i);
+ if (pci_claim_resource(dev, idx) >= 0)
+ continue;
+
+ /* try again after clip for pci bridge*/
+ if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, idx);
+ }
}
+
+ return changed;
}
/*
@@ -329,8 +342,12 @@ void pcibios_fixup_bus(struct pci_bus *bus)
struct pci_dev *dev;
if (bus->self) {
+ bool changed;
+
pci_read_bridge_bases(bus);
- pcibios_fixup_device_resources(bus->self);
+ changed = pcibios_fixup_bridge_resources(bus->self);
+ if (changed)
+ pci_setup_bridge(bus);
}
list_for_each_entry(dev, &bus->devices, bus_list)
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 08/10] PCI, parisc: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (6 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 07/10] PCI, mn10300: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-13 21:01 ` Helge Deller
2015-01-12 19:23 ` [PATCH 09/10] PCI, powerpc: " Yinghai Lu
2015-01-12 19:23 ` [PATCH 10/10] PCI, sparc: " Yinghai Lu
9 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, James E.J. Bottomley,
Helge Deller, linux-parisc
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-parisc@vger.kernel.org
---
drivers/parisc/lba_pci.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 37e71ff..e6ab352 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -692,11 +692,25 @@ lba_fixup_bus(struct pci_bus *bus)
*/
if (bus->parent) {
int i;
+ bool changed = false;
+
+ dev = bus->self;
/* PCI-PCI Bridge */
pci_read_bridge_bases(bus);
for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
- pci_claim_resource(bus->self, i);
+ struct resource *res = &dev->resource[i];
+
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+
+ if (pci_bus_clip_resource(dev, res)) {
+ changed = true;
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+ }
}
+ if (changed)
+ pci_setup_bridge(bus);
} else {
/* Host-PCI Bridge */
int err;
@@ -776,7 +790,15 @@ lba_fixup_bus(struct pci_bus *bus)
** that share expansion ROMs (think quad tulip), but
** isn't harmful.
*/
- pci_claim_resource(dev, i);
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+
+ /* try again with clip */
+ if (i != PCI_ROM_RESOURCE &&
+ pci_bus_clip_resource(dev, res)) {
+ pci_update_resource(dev, i);
+ pci_claim_resource(dev, i);
+ }
}
#ifdef FBB_SUPPORT
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 09/10] PCI, powerpc: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (7 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 08/10] PCI, parisc: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-13 9:07 ` Wei Yang
2015-01-12 19:23 ` [PATCH 10/10] PCI, sparc: " Yinghai Lu
9 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman, Gavin Shan, Anton Blanchard,
Sebastian Ott, Wei Yang, Andrew Murray, linuxppc-dev
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Gavin Shan <gwshan@linux.vnet.ibm.com>
Cc: Anton Blanchard <anton@samba.org>
Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
Cc: Wei Yang <weiyang@linux.vnet.ibm.com>
Cc: Andrew Murray <amurray@embedded-bits.co.uk>
Cc: linuxppc-dev@lists.ozlabs.org
---
arch/powerpc/kernel/pci-common.c | 43 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 37d512d..6909546 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1148,6 +1148,7 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
struct pci_bus *b;
int i;
struct resource *res, *pr;
+ bool changed = false;
pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
pci_domain_nr(bus), bus->number);
@@ -1184,6 +1185,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
pr, (pr && pr->name) ? pr->name : "nil");
if (pr && !(pr->flags & IORESOURCE_UNSET)) {
+ struct pci_dev *dev = bus->self;
+
if (request_resource(pr, res) == 0)
continue;
/*
@@ -1193,6 +1196,16 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
*/
if (reparent_resources(pr, res) == 0)
continue;
+
+ if (dev && i >= PCI_BRIDGE_RESOURCES &&
+ i < PCI_NUM_RESOURCES &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, res)) {
+ changed = true;
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+ }
+
}
pr_warning("PCI: Cannot allocate resource region "
"%d of PCI bridge %d, will remap\n", i, bus->number);
@@ -1208,6 +1221,9 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
res->flags = 0;
}
+ if (changed)
+ pci_setup_bridge(bus);
+
list_for_each_entry(b, &bus->children, node)
pcibios_allocate_bus_resources(b);
}
@@ -1225,6 +1241,13 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
pr = pci_find_parent_resource(dev, r);
if (!pr || (pr->flags & IORESOURCE_UNSET) ||
request_resource(pr, r) < 0) {
+ /* try again with clip */
+ if (idx != PCI_ROM_RESOURCE && pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, idx);
+ if (pci_claim_resource(dev, idx) >= 0)
+ return;
+ }
+
printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
" of device %s, will remap\n", idx, pci_name(dev));
if (pr)
@@ -1386,6 +1409,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
struct pci_bus *child_bus;
list_for_each_entry(dev, &bus->devices, bus_list) {
+ bool changed = false;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -1401,8 +1425,25 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
(unsigned long long)r->end,
(unsigned int)r->flags);
- pci_claim_resource(dev, i);
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+
+ if (dev->subordinate &&
+ i >= PCI_BRIDGE_RESOURCES &&
+ i < PCI_NUM_RESOURCES &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, i);
+ } else if (i < PCI_BRIDGE_RESOURCES &&
+ i != PCI_ROM_RESOURCE &&
+ pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, i);
+ pci_claim_resource(dev, i);
+ }
}
+ if (changed)
+ pci_setup_bridge(dev->subordinate);
}
list_for_each_entry(child_bus, &bus->children, node)
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH 10/10] PCI, sparc: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
` (8 preceding siblings ...)
2015-01-12 19:23 ` [PATCH 09/10] PCI, powerpc: " Yinghai Lu
@ 2015-01-12 19:23 ` Yinghai Lu
2015-01-12 22:31 ` Kjetil Oftedal
9 siblings, 1 reply; 17+ messages in thread
From: Yinghai Lu @ 2015-01-12 19:23 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, linux-kernel, Yinghai Lu, David S. Miller,
Paul Gortmaker, Yijing Wang, Sam Ravnborg, sparclinux
Some bios put range that is not fully coverred by root bus resources.
Try to clip them and update them in pci bridge bars.
We'd like to fix other arches instead of just x86.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
Reported-by: Marek Kordik <kordikmarek@gmail.com>
Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: Yijing Wang <wangyijing@huawei.com>
Cc: Sam Ravnborg <sam@ravnborg.org>
Cc: sparclinux@vger.kernel.org
---
arch/sparc/kernel/pci.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b36365f..0e391e5 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -623,6 +623,7 @@ static void pci_claim_bus_resources(struct pci_bus *bus)
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
+ bool changed = false;
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -639,8 +640,25 @@ static void pci_claim_bus_resources(struct pci_bus *bus)
(unsigned long long)r->end,
(unsigned int)r->flags);
- pci_claim_resource(dev, i);
+ if (pci_claim_resource(dev, i) >= 0)
+ continue;
+
+ if (dev->subordinate &&
+ i >= PCI_BRIDGE_RESOURCES &&
+ i < PCI_NUM_RESOURCES &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+ pci_bus_clip_resource(dev, r)) {
+ changed = true;
+ pci_claim_resource(dev, i);
+ } else if (i < PCI_BRIDGE_RESOURCES &&
+ i != PCI_ROM_RESOURCE &&
+ pci_bus_clip_resource(dev, r)) {
+ pci_update_resource(dev, i);
+ pci_claim_resource(dev, i);
+ }
}
+ if (changed)
+ pci_setup_bridge(dev->subordinate);
}
list_for_each_entry(child_bus, &bus->children, node)
--
1.8.4.5
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH 10/10] PCI, sparc: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 ` [PATCH 10/10] PCI, sparc: " Yinghai Lu
@ 2015-01-12 22:31 ` Kjetil Oftedal
2015-01-15 22:15 ` Bjorn Helgaas
0 siblings, 1 reply; 17+ messages in thread
From: Kjetil Oftedal @ 2015-01-12 22:31 UTC (permalink / raw)
To: Yinghai Lu
Cc: Bjorn Helgaas, linux-pci, linux-kernel, David S. Miller,
Paul Gortmaker, Yijing Wang, Sam Ravnborg, sparclinux
Hi,
Am I missing something or is this just code to get the the resource
subsystem to accept the bus resources, not caring if the resources are
actually usable? PCI BARs usually have a given size for a reason?
-
Kjetil Oftedal
On 12/01/2015, Yinghai Lu <yinghai@kernel.org> wrote:
> Some bios put range that is not fully coverred by root bus resources.
> Try to clip them and update them in pci bridge bars.
>
> We'd like to fix other arches instead of just x86.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
> Reported-by: Marek Kordik <kordikmarek@gmail.com>
> Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to
> 64-bit resources")
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
> Cc: Yijing Wang <wangyijing@huawei.com>
> Cc: Sam Ravnborg <sam@ravnborg.org>
> Cc: sparclinux@vger.kernel.org
> ---
> arch/sparc/kernel/pci.c | 20 +++++++++++++++++++-
> 1 file changed, 19 insertions(+), 1 deletion(-)
>
> diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
> index b36365f..0e391e5 100644
> --- a/arch/sparc/kernel/pci.c
> +++ b/arch/sparc/kernel/pci.c
> @@ -623,6 +623,7 @@ static void pci_claim_bus_resources(struct pci_bus
> *bus)
> struct pci_dev *dev;
>
> list_for_each_entry(dev, &bus->devices, bus_list) {
> + bool changed = false;
> int i;
>
> for (i = 0; i < PCI_NUM_RESOURCES; i++) {
> @@ -639,8 +640,25 @@ static void pci_claim_bus_resources(struct pci_bus
> *bus)
> (unsigned long long)r->end,
> (unsigned int)r->flags);
>
> - pci_claim_resource(dev, i);
> + if (pci_claim_resource(dev, i) >= 0)
> + continue;
> +
> + if (dev->subordinate &&
> + i >= PCI_BRIDGE_RESOURCES &&
> + i < PCI_NUM_RESOURCES &&
> + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
> + pci_bus_clip_resource(dev, r)) {
> + changed = true;
> + pci_claim_resource(dev, i);
> + } else if (i < PCI_BRIDGE_RESOURCES &&
> + i != PCI_ROM_RESOURCE &&
> + pci_bus_clip_resource(dev, r)) {
> + pci_update_resource(dev, i);
> + pci_claim_resource(dev, i);
> + }
> }
> + if (changed)
> + pci_setup_bridge(dev->subordinate);
> }
>
> list_for_each_entry(child_bus, &bus->children, node)
> --
> 1.8.4.5
>
> --
> To unsubscribe from this list: send the line "unsubscribe sparclinux" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 09/10] PCI, powerpc: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 ` [PATCH 09/10] PCI, powerpc: " Yinghai Lu
@ 2015-01-13 9:07 ` Wei Yang
0 siblings, 0 replies; 17+ messages in thread
From: Wei Yang @ 2015-01-13 9:07 UTC (permalink / raw)
To: Yinghai Lu
Cc: Bjorn Helgaas, linux-pci, linux-kernel, Benjamin Herrenschmidt,
Paul Mackerras, Michael Ellerman, Gavin Shan, Anton Blanchard,
Sebastian Ott, Wei Yang, Andrew Murray, linuxppc-dev
Did a quick test, looks good on my machine.
Thanks :-)
On Mon, Jan 12, 2015 at 11:23:19AM -0800, Yinghai Lu wrote:
>Some bios put range that is not fully coverred by root bus resources.
>Try to clip them and update them in pci bridge bars.
>
>We'd like to fix other arches instead of just x86.
>
>Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
>Reported-by: Marek Kordik <kordikmarek@gmail.com>
>Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
>Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>Cc: Paul Mackerras <paulus@samba.org>
>Cc: Michael Ellerman <mpe@ellerman.id.au>
>Cc: Gavin Shan <gwshan@linux.vnet.ibm.com>
>Cc: Anton Blanchard <anton@samba.org>
>Cc: Sebastian Ott <sebott@linux.vnet.ibm.com>
>Cc: Wei Yang <weiyang@linux.vnet.ibm.com>
>Cc: Andrew Murray <amurray@embedded-bits.co.uk>
>Cc: linuxppc-dev@lists.ozlabs.org
>---
> arch/powerpc/kernel/pci-common.c | 43 +++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
>diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
>index 37d512d..6909546 100644
>--- a/arch/powerpc/kernel/pci-common.c
>+++ b/arch/powerpc/kernel/pci-common.c
>@@ -1148,6 +1148,7 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> struct pci_bus *b;
> int i;
> struct resource *res, *pr;
>+ bool changed = false;
>
> pr_debug("PCI: Allocating bus resources for %04x:%02x...\n",
> pci_domain_nr(bus), bus->number);
>@@ -1184,6 +1185,8 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> pr, (pr && pr->name) ? pr->name : "nil");
>
> if (pr && !(pr->flags & IORESOURCE_UNSET)) {
>+ struct pci_dev *dev = bus->self;
>+
> if (request_resource(pr, res) == 0)
> continue;
> /*
>@@ -1193,6 +1196,16 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> */
> if (reparent_resources(pr, res) == 0)
> continue;
>+
>+ if (dev && i >= PCI_BRIDGE_RESOURCES &&
>+ i < PCI_NUM_RESOURCES &&
>+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
>+ pci_bus_clip_resource(dev, res)) {
>+ changed = true;
>+ if (pci_claim_resource(dev, i) >= 0)
>+ continue;
>+ }
>+
> }
> pr_warning("PCI: Cannot allocate resource region "
> "%d of PCI bridge %d, will remap\n", i, bus->number);
>@@ -1208,6 +1221,9 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> res->flags = 0;
> }
>
>+ if (changed)
>+ pci_setup_bridge(bus);
>+
> list_for_each_entry(b, &bus->children, node)
> pcibios_allocate_bus_resources(b);
> }
>@@ -1225,6 +1241,13 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
> pr = pci_find_parent_resource(dev, r);
> if (!pr || (pr->flags & IORESOURCE_UNSET) ||
> request_resource(pr, r) < 0) {
>+ /* try again with clip */
>+ if (idx != PCI_ROM_RESOURCE && pci_bus_clip_resource(dev, r)) {
>+ pci_update_resource(dev, idx);
>+ if (pci_claim_resource(dev, idx) >= 0)
>+ return;
>+ }
>+
> printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
> " of device %s, will remap\n", idx, pci_name(dev));
> if (pr)
>@@ -1386,6 +1409,7 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
> struct pci_bus *child_bus;
>
> list_for_each_entry(dev, &bus->devices, bus_list) {
>+ bool changed = false;
> int i;
>
> for (i = 0; i < PCI_NUM_RESOURCES; i++) {
>@@ -1401,8 +1425,25 @@ void pcibios_claim_one_bus(struct pci_bus *bus)
> (unsigned long long)r->end,
> (unsigned int)r->flags);
>
>- pci_claim_resource(dev, i);
>+ if (pci_claim_resource(dev, i) >= 0)
>+ continue;
>+
>+ if (dev->subordinate &&
>+ i >= PCI_BRIDGE_RESOURCES &&
>+ i < PCI_NUM_RESOURCES &&
>+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
>+ pci_bus_clip_resource(dev, r)) {
>+ changed = true;
>+ pci_claim_resource(dev, i);
>+ } else if (i < PCI_BRIDGE_RESOURCES &&
>+ i != PCI_ROM_RESOURCE &&
>+ pci_bus_clip_resource(dev, r)) {
>+ pci_update_resource(dev, i);
>+ pci_claim_resource(dev, i);
>+ }
> }
>+ if (changed)
>+ pci_setup_bridge(dev->subordinate);
> }
>
> list_for_each_entry(child_bus, &bus->children, node)
>--
>1.8.4.5
--
Richard Yang
Help you, Help me
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 08/10] PCI, parisc: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 ` [PATCH 08/10] PCI, parisc: " Yinghai Lu
@ 2015-01-13 21:01 ` Helge Deller
0 siblings, 0 replies; 17+ messages in thread
From: Helge Deller @ 2015-01-13 21:01 UTC (permalink / raw)
To: Yinghai Lu, Bjorn Helgaas
Cc: linux-pci, linux-kernel, James E.J. Bottomley, linux-parisc
On 12.01.2015 20:23, Yinghai Lu wrote:
> Some bios put range that is not fully coverred by root bus resources.
> Try to clip them and update them in pci bridge bars.
>
> We'd like to fix other arches instead of just x86.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
> Reported-by: Marek Kordik <kordikmarek@gmail.com>
> Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: "James E.J. Bottomley" <jejb@parisc-linux.org>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-parisc@vger.kernel.org
I tested it on the parisc arch - everything OK.
Acked-by: Helge Deller <deller@gmx.de>
Thanks!
Helge
> ---
> drivers/parisc/lba_pci.c | 26 ++++++++++++++++++++++++--
> 1 file changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
> index 37e71ff..e6ab352 100644
> --- a/drivers/parisc/lba_pci.c
> +++ b/drivers/parisc/lba_pci.c
> @@ -692,11 +692,25 @@ lba_fixup_bus(struct pci_bus *bus)
> */
> if (bus->parent) {
> int i;
> + bool changed = false;
> +
> + dev = bus->self;
> /* PCI-PCI Bridge */
> pci_read_bridge_bases(bus);
> for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
> - pci_claim_resource(bus->self, i);
> + struct resource *res = &dev->resource[i];
> +
> + if (pci_claim_resource(dev, i) >= 0)
> + continue;
> +
> + if (pci_bus_clip_resource(dev, res)) {
> + changed = true;
> + if (pci_claim_resource(dev, i) >= 0)
> + continue;
> + }
> }
> + if (changed)
> + pci_setup_bridge(bus);
> } else {
> /* Host-PCI Bridge */
> int err;
> @@ -776,7 +790,15 @@ lba_fixup_bus(struct pci_bus *bus)
> ** that share expansion ROMs (think quad tulip), but
> ** isn't harmful.
> */
> - pci_claim_resource(dev, i);
> + if (pci_claim_resource(dev, i) >= 0)
> + continue;
> +
> + /* try again with clip */
> + if (i != PCI_ROM_RESOURCE &&
> + pci_bus_clip_resource(dev, res)) {
> + pci_update_resource(dev, i);
> + pci_claim_resource(dev, i);
> + }
> }
>
> #ifdef FBB_SUPPORT
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 02/10] PCI, x86: clip firmware assigned resource under parent bridge's
2015-01-12 19:23 ` [PATCH 02/10] PCI, x86: " Yinghai Lu
@ 2015-01-14 16:52 ` Bjorn Helgaas
2015-01-14 19:17 ` Yinghai Lu
0 siblings, 1 reply; 17+ messages in thread
From: Bjorn Helgaas @ 2015-01-14 16:52 UTC (permalink / raw)
To: Yinghai Lu
Cc: linux-pci, linux-kernel, Thomas Gleixner, Ingo Molnar,
H. Peter Anvin, x86
On Mon, Jan 12, 2015 at 11:23:12AM -0800, Yinghai Lu wrote:
> Some bios put range that is not fully coverred by root bus resources.
> Try to clip them and update them in pci bridge bars.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
> Reported-by: Marek Kordik <kordikmarek@gmail.com>
> Tested-by: Marek Kordik <kordikmarek@gmail.com>
> Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to 64-bit resources")
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: x86@kernel.org
> ---
> arch/x86/pci/i386.c | 74 +++++++++++++++++++++++++++++++++++++----------------
> 1 file changed, 52 insertions(+), 22 deletions(-)
>
> diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
> index 9b18ef3..d43e1af 100644
> --- a/arch/x86/pci/i386.c
> +++ b/arch/x86/pci/i386.c
> @@ -205,10 +205,11 @@ EXPORT_SYMBOL(pcibios_align_resource);
> * as well.
> */
>
> -static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
> +static bool pcibios_allocate_bridge_resources(struct pci_dev *dev)
> {
> int idx;
> struct resource *r;
> + bool changed = false;
>
> for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
> r = &dev->resource[idx];
> @@ -216,17 +217,33 @@ static void pcibios_allocate_bridge_resources(struct pci_dev *dev)
> continue;
> if (r->parent) /* Already allocated */
> continue;
> - if (!r->start || pci_claim_resource(dev, idx) < 0) {
> - /*
> - * Something is wrong with the region.
> - * Invalidate the resource to prevent
> - * child resource allocations in this
> - * range.
> - */
> - r->start = r->end = 0;
> - r->flags = 0;
> +
> + if (!r->start)
> + goto clear;
> +
> + if (pci_claim_resource(dev, idx) >= 0)
> + continue;
> +
> + /* try again after clip for pci bridge*/
> + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
> + pci_bus_clip_resource(dev, r)) {
> + changed = true;
> + if (pci_claim_resource(dev, idx) >= 0)
> + continue;
> }
> +
> +clear:
> + /*
> + * Something is wrong with the region.
> + * Invalidate the resource to prevent
> + * child resource allocations in this
> + * range.
> + */
> + r->start = r->end = 0;
> + r->flags = 0;
> }
> +
> + return changed;
There's a lot of duplicated code in these patches. Is it possible to
factor this out a bit, e.g., something like this?
int pci_claim_bridge_resource(struct pci_dev *dev, int i)
{
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
return 0;
if (pci_claim_resource(dev, i) == 0)
return 0; /* claimed the window */
if (!pci_bus_clip_resource(dev, i))
return -EINVAL; /* clipping didn't change anything */
if (dev->subordinate)
pci_setup_bridge(dev->subordinate);
if (pci_claim_resource(dev, i) == 0)
return 0; /* claimed a smaller window */
return -EINVAL;
}
> }
>
> static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> @@ -234,8 +251,12 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
> struct pci_bus *child;
>
> /* Depth-First Search on bus tree */
> - if (bus->self)
> - pcibios_allocate_bridge_resources(bus->self);
> + if (bus->self) {
> + bool changed = pcibios_allocate_bridge_resources(bus->self);
> +
> + if (changed)
> + pci_setup_bridge(bus);
> + }
> list_for_each_entry(child, &bus->children, node)
> pcibios_allocate_bus_resources(child);
> }
> @@ -274,18 +295,27 @@ static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass)
> dev_dbg(&dev->dev,
> "BAR %d: reserving %pr (d=%d, p=%d)\n",
> idx, r, disabled, pass);
> - if (pci_claim_resource(dev, idx) < 0) {
> - if (r->flags & IORESOURCE_PCI_FIXED) {
> - dev_info(&dev->dev, "BAR %d %pR is immovable\n",
> +
> + if (pci_claim_resource(dev, idx) >= 0)
> + continue;
> +
> + if (r->flags & IORESOURCE_PCI_FIXED) {
> + dev_info(&dev->dev, "BAR %d %pR is immovable\n",
> idx, r);
> - } else {
> - /* We'll assign a new address later */
> - pcibios_save_fw_addr(dev,
> - idx, r->start);
> - r->end -= r->start;
> - r->start = 0;
> - }
> + continue;
> + }
> +
> + /* try again with clip */
> + if (pci_bus_clip_resource(dev, r)) {
> + pci_update_resource(dev, idx);
> + if (pci_claim_resource(dev, idx) >= 0)
> + continue;
This hunk doesn't make sense to me. This only deals with standard BARs and
IOV BARS. It doesn't deal with bridge windows at all. The sizes of these
BARs and IOV BARs are fixed and there's no point in trying to clip them
because we can't tell the hardware that the BAR is now smaller.
It's different for bridge windows because we can adjust their size.
Bjorn
> }
> +
> + /* We'll assign a new address later */
> + pcibios_save_fw_addr(dev, idx, r->start);
> + r->end -= r->start;
> + r->start = 0;
> }
> }
> if (!pass) {
> --
> 1.8.4.5
>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 02/10] PCI, x86: clip firmware assigned resource under parent bridge's
2015-01-14 16:52 ` Bjorn Helgaas
@ 2015-01-14 19:17 ` Yinghai Lu
0 siblings, 0 replies; 17+ messages in thread
From: Yinghai Lu @ 2015-01-14 19:17 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci@vger.kernel.org, Linux Kernel Mailing List,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin,
the arch/x86 maintainers
On Wed, Jan 14, 2015 at 8:52 AM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Mon, Jan 12, 2015 at 11:23:12AM -0800, Yinghai Lu wrote:
> There's a lot of duplicated code in these patches. Is it possible to
> factor this out a bit, e.g., something like this?
>
> int pci_claim_bridge_resource(struct pci_dev *dev, int i)
> {
> if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
> return 0;
>
> if (pci_claim_resource(dev, i) == 0)
> return 0; /* claimed the window */
>
> if (!pci_bus_clip_resource(dev, i))
> return -EINVAL; /* clipping didn't change anything */
>
> if (dev->subordinate)
> pci_setup_bridge(dev->subordinate);
> if (pci_claim_resource(dev, i) == 0)
> return 0; /* claimed a smaller window */
>
> return -EINVAL;
> }
ok. will have one in setup_bus.c
>
>> }
>>
>> static void pcibios_allocate_bus_resources(struct pci_bus *bus)
>> @@ -234,8 +251,12 @@ static void pcibios_allocate_bus_resources(struct pci_bus *bus)
>> struct pci_bus *child;
>>
>> /* Depth-First Search on bus tree */
>> - if (bus->self)
>> - pcibios_allocate_bridge_resources(bus->self);
>> + if (bus->self) {
>> + bool changed = pcibios_allocate_bridge_resources(bus->self);
>> +
>> + if (changed)
>> + pci_setup_bridge(bus);
>> + }
>> list_for_each_entry(child, &bus->children, node)
>> pcibios_allocate_bus_resources(child);
>> }
>> @@ -274,18 +295,27 @@ static void pcibios_allocate_dev_resources(struct pci_dev *dev, int pass)
>> dev_dbg(&dev->dev,
>> "BAR %d: reserving %pr (d=%d, p=%d)\n",
>> idx, r, disabled, pass);
>> - if (pci_claim_resource(dev, idx) < 0) {
>> - if (r->flags & IORESOURCE_PCI_FIXED) {
>> - dev_info(&dev->dev, "BAR %d %pR is immovable\n",
>> +
>> + if (pci_claim_resource(dev, idx) >= 0)
>> + continue;
>> +
>> + if (r->flags & IORESOURCE_PCI_FIXED) {
>> + dev_info(&dev->dev, "BAR %d %pR is immovable\n",
>> idx, r);
>> - } else {
>> - /* We'll assign a new address later */
>> - pcibios_save_fw_addr(dev,
>> - idx, r->start);
>> - r->end -= r->start;
>> - r->start = 0;
>> - }
>> + continue;
>> + }
>> +
>> + /* try again with clip */
>> + if (pci_bus_clip_resource(dev, r)) {
>> + pci_update_resource(dev, idx);
>> + if (pci_claim_resource(dev, idx) >= 0)
>> + continue;
>
> This hunk doesn't make sense to me. This only deals with standard BARs and
> IOV BARS. It doesn't deal with bridge windows at all. The sizes of these
> BARs and IOV BARs are fixed and there's no point in trying to clip them
> because we can't tell the hardware that the BAR is now smaller.
>
> It's different for bridge windows because we can adjust their size.
ok, will drop that.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 10/10] PCI, sparc: clip firmware assigned resource under parent bridge's
2015-01-12 22:31 ` Kjetil Oftedal
@ 2015-01-15 22:15 ` Bjorn Helgaas
0 siblings, 0 replies; 17+ messages in thread
From: Bjorn Helgaas @ 2015-01-15 22:15 UTC (permalink / raw)
To: Kjetil Oftedal
Cc: Yinghai Lu, linux-pci, linux-kernel, David S. Miller,
Paul Gortmaker, Yijing Wang, Sam Ravnborg, sparclinux
On Mon, Jan 12, 2015 at 11:31:09PM +0100, Kjetil Oftedal wrote:
> Hi,
>
> Am I missing something or is this just code to get the the resource
> subsystem to accept the bus resources, not caring if the resources are
> actually usable? PCI BARs usually have a given size for a reason?
Hi Kjetil,
This isn't for regular PCI BARs (Yinghai did apply it to some regular BARs
in the v1 patches, but I think that was a mistake). This is for scenarios
like this:
pci_bus 0000:00: root bus resource [mem 0xc0000000-0xffffffff]
pci 0000:00:01.0: bridge window [mem 0xbdf00000-0xddefffff 64bit pref]
pci 0000:01:00.0: reg 0x10: [mem 0xc0000000-0xcfffffff pref]
The 00:01.0 window is illegal: it starts before the host bridge window, so
we have to assume the [0xbdf00000-0xbfffffff] region is inaccessible. We
can make it legal by clipping it to [mem 0xc0000000-0xddefffff 64bit pref].
Linux should never assign an illegal bridge window like this, but some
firmware does, and the idea is to make a minimal change (clip the window)
before resorting to the big hammer of reassigning resources from scratch.
Bjorn
> On 12/01/2015, Yinghai Lu <yinghai@kernel.org> wrote:
> > Some bios put range that is not fully coverred by root bus resources.
> > Try to clip them and update them in pci bridge bars.
> >
> > We'd like to fix other arches instead of just x86.
> >
> > Link: https://bugzilla.kernel.org/show_bug.cgi?id=85491
> > Reported-by: Marek Kordik <kordikmarek@gmail.com>
> > Fixes: 5b28541552ef ("PCI: Restrict 64-bit prefetchable bridge windows to
> > 64-bit resources")
> > Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> > Cc: "David S. Miller" <davem@davemloft.net>
> > Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
> > Cc: Yijing Wang <wangyijing@huawei.com>
> > Cc: Sam Ravnborg <sam@ravnborg.org>
> > Cc: sparclinux@vger.kernel.org
> > ---
> > arch/sparc/kernel/pci.c | 20 +++++++++++++++++++-
> > 1 file changed, 19 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
> > index b36365f..0e391e5 100644
> > --- a/arch/sparc/kernel/pci.c
> > +++ b/arch/sparc/kernel/pci.c
> > @@ -623,6 +623,7 @@ static void pci_claim_bus_resources(struct pci_bus
> > *bus)
> > struct pci_dev *dev;
> >
> > list_for_each_entry(dev, &bus->devices, bus_list) {
> > + bool changed = false;
> > int i;
> >
> > for (i = 0; i < PCI_NUM_RESOURCES; i++) {
> > @@ -639,8 +640,25 @@ static void pci_claim_bus_resources(struct pci_bus
> > *bus)
> > (unsigned long long)r->end,
> > (unsigned int)r->flags);
> >
> > - pci_claim_resource(dev, i);
> > + if (pci_claim_resource(dev, i) >= 0)
> > + continue;
> > +
> > + if (dev->subordinate &&
> > + i >= PCI_BRIDGE_RESOURCES &&
> > + i < PCI_NUM_RESOURCES &&
> > + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
> > + pci_bus_clip_resource(dev, r)) {
> > + changed = true;
> > + pci_claim_resource(dev, i);
> > + } else if (i < PCI_BRIDGE_RESOURCES &&
> > + i != PCI_ROM_RESOURCE &&
> > + pci_bus_clip_resource(dev, r)) {
> > + pci_update_resource(dev, i);
> > + pci_claim_resource(dev, i);
> > + }
> > }
> > + if (changed)
> > + pci_setup_bridge(dev->subordinate);
> > }
> >
> > list_for_each_entry(child_bus, &bus->children, node)
> > --
> > 1.8.4.5
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe sparclinux" in
> > the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
> >
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2015-01-15 22:15 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-12 19:23 [PATCH 00/10] PCI: clip firmware assigned resources Yinghai Lu
2015-01-12 19:23 ` [PATCH 01/10] PCI: clip firmware assigned resource under parent bridge's Yinghai Lu
2015-01-12 19:23 ` [PATCH 02/10] PCI, x86: " Yinghai Lu
2015-01-14 16:52 ` Bjorn Helgaas
2015-01-14 19:17 ` Yinghai Lu
2015-01-12 19:23 ` [PATCH 03/10] PCI, alpha: " Yinghai Lu
2015-01-12 19:23 ` [PATCH 04/10] PCI, frv: " Yinghai Lu
2015-01-12 19:23 ` [PATCH 05/10] PCI, ia64: " Yinghai Lu
2015-01-12 19:23 ` [PATCH 06/10] PCI, microblaze: " Yinghai Lu
2015-01-12 19:23 ` [PATCH 07/10] PCI, mn10300: " Yinghai Lu
2015-01-12 19:23 ` [PATCH 08/10] PCI, parisc: " Yinghai Lu
2015-01-13 21:01 ` Helge Deller
2015-01-12 19:23 ` [PATCH 09/10] PCI, powerpc: " Yinghai Lu
2015-01-13 9:07 ` Wei Yang
2015-01-12 19:23 ` [PATCH 10/10] PCI, sparc: " Yinghai Lu
2015-01-12 22:31 ` Kjetil Oftedal
2015-01-15 22:15 ` Bjorn Helgaas
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).