* [RFC PATCH 0/3] Make 64-bit prefetchable MMIO work @ 2013-11-19 6:36 Guo Chao 2013-11-19 6:36 ` [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address Guo Chao ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Guo Chao @ 2013-11-19 6:36 UTC (permalink / raw) To: linux-pci; +Cc: bhelgaas, yinghai Resource assignment code does not work properly after we expose 64-bit prefetchable MMIO window in PowerNV platform. # ROM BAR get 4G-above address. This is because default value of PCIBIOS_MAX_MEM_32 is -1 which makes it useless in 64-bit platform. After fixing this ... # ROM BAR can't get any address. This is because PCIBIOS_MAX_MEM_32 is actually a PCI address but functions as a CPU address. After fixing this ... # 64-bit prefetchable address is never used. This is because root bridge's IORESOURCE_MEM_64 is reset due to ROM BARs, which makes it not quilify to get 4G-above prefetchable address from host bridge. The 64-bit 4G-above prefetchable window is not used at all in the end. Nothing is really broken currently. This is just a RFC series, preparing for later PowerNV 64-bit MMIO work. Guo Chao (3): PCI: do not compare CPU address with PCI address PCI: set proper default value of PCIBIOS_MAX_MEM_32 PCI: do not reset bridge's IORESOURCE_MEM_64 flag for ROM BAR arch/x86/include/asm/pci.h | 1 - drivers/pci/bus.c | 65 ++++++++++++++++++++++++++++++++++++++++++++-- drivers/pci/setup-bus.c | 3 ++- include/linux/pci.h | 2 +- 4 files changed, 66 insertions(+), 5 deletions(-) -- 1.8.3.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address 2013-11-19 6:36 [RFC PATCH 0/3] Make 64-bit prefetchable MMIO work Guo Chao @ 2013-11-19 6:36 ` Guo Chao 2013-11-19 19:31 ` Yinghai Lu 2013-11-19 6:36 ` [RFC PATCH 2/3] PCI: set proper default value of PCIBIOS_MAX_MEM_32 Guo Chao 2013-11-19 6:36 ` [RFC PATCH 3/3] PCI: do not reset bridge's IORESOURCE_MEM_64 flag for ROM BAR Guo Chao 2 siblings, 1 reply; 7+ messages in thread From: Guo Chao @ 2013-11-19 6:36 UTC (permalink / raw) To: linux-pci; +Cc: bhelgaas, yinghai In resource assignment code, limits are exerted to restrict allocated resource range. However these limits are PCI address but compared to CPU address in the end. Translated them before comparing. We can't just use pcibios_bus_to_resource because the limits may not included in the host bridge window. Introduce a help function to do this translation, if address missed, return an approximate one. Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com> --- drivers/pci/bus.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index fc1b740..532c0a4 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -99,6 +99,64 @@ void pci_bus_remove_resources(struct pci_bus *bus) } /** + * pci_bus_to_resource + * + * Much like pcibios_bus_to_resource() except it takes a single address + * and returns an approximate one if target address is not included + * in the bridge window. The approximate address is smaller than required + * one is 'bound' is 1, larger than required one if 'bound' is 0. + */ +static resource_size_t pci_bus_to_resource(struct pci_bus *bus, int flags, + int mask, resource_size_t addr, int bound) +{ + struct pci_host_bridge *bridge; + struct pci_host_bridge_window *window, *match = NULL; + resource_size_t max = 0, min = -1; + resource_size_t offset = -1, start, end; + + while (bus->parent) + bus = bus->parent; + + bridge = to_pci_host_bridge(bus->bridge); + + list_for_each_entry(window, &bridge->windows, list) { + if ((flags ^ window->res->flags) & mask) + continue; + + start = window->res->start - window->offset; + end = window->res->end - window->offset; + + if (addr >= start && addr <= end) { + offset = window->offset; + break; + } + + if (bound && addr > end && end > max) { + max = end; + match = window; + } else if (!bound && addr < start && start < min) { + min = start; + match = window; + } + } + + if (offset == -1) { + /* + * Not even found the matched type. This may happen, + * for example, if try to translate IO address in a HB + * without IO window. Just return the original address, + * it will fail later anyway. + */ + if (match == NULL) + return addr; + + return (bound ? max : min) + match->offset; + } + + return addr + offset; +} + +/** * pci_bus_alloc_resource - allocate a resource from a parent bus * @bus: PCI bus * @res: resource to allocate @@ -129,9 +187,12 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, type_mask |= IORESOURCE_IO | IORESOURCE_MEM; - /* don't allocate too high if the pref mem doesn't support 64bit*/ + /* don't allocate too high if the pref mem doesn't support 64bit */ if (!(res->flags & IORESOURCE_MEM_64)) - max = PCIBIOS_MAX_MEM_32; + max = pci_bus_to_resource(bus, res->flags, type_mask, + PCIBIOS_MAX_MEM_32, 1); + + min = pci_bus_to_resource(bus, res->flags, type_mask, min, 0); pci_bus_for_each_resource(bus, r, i) { if (!r) -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address 2013-11-19 6:36 ` [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address Guo Chao @ 2013-11-19 19:31 ` Yinghai Lu 2013-11-19 19:35 ` Yinghai Lu 2013-11-19 23:48 ` Bjorn Helgaas 0 siblings, 2 replies; 7+ messages in thread From: Yinghai Lu @ 2013-11-19 19:31 UTC (permalink / raw) To: Guo Chao; +Cc: linux-pci@vger.kernel.org, Bjorn Helgaas [-- Attachment #1: Type: text/plain, Size: 3193 bytes --] On Mon, Nov 18, 2013 at 10:36 PM, Guo Chao <yan@linux.vnet.ibm.com> wrote: > In resource assignment code, limits are exerted to restrict allocated > resource range. However these limits are PCI address but compared to > CPU address in the end. Translated them before comparing. > > We can't just use pcibios_bus_to_resource because the limits may not > included in the host bridge window. Introduce a help function to > do this translation, if address missed, return an approximate one. > > Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com> > --- > drivers/pci/bus.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 63 insertions(+), 2 deletions(-) > > diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c > index fc1b740..532c0a4 100644 > --- a/drivers/pci/bus.c > +++ b/drivers/pci/bus.c > @@ -99,6 +99,64 @@ void pci_bus_remove_resources(struct pci_bus *bus) > } > > /** > + * pci_bus_to_resource > + * > + * Much like pcibios_bus_to_resource() except it takes a single address > + * and returns an approximate one if target address is not included > + * in the bridge window. The approximate address is smaller than required > + * one is 'bound' is 1, larger than required one if 'bound' is 0. > + */ > +static resource_size_t pci_bus_to_resource(struct pci_bus *bus, int flags, > + int mask, resource_size_t addr, int bound) > +{ > + struct pci_host_bridge *bridge; > + struct pci_host_bridge_window *window, *match = NULL; > + resource_size_t max = 0, min = -1; > + resource_size_t offset = -1, start, end; > + > + while (bus->parent) > + bus = bus->parent; > + > + bridge = to_pci_host_bridge(bus->bridge); > + > + list_for_each_entry(window, &bridge->windows, list) { > + if ((flags ^ window->res->flags) & mask) > + continue; > + > + start = window->res->start - window->offset; > + end = window->res->end - window->offset; > + > + if (addr >= start && addr <= end) { > + offset = window->offset; > + break; > + } > + > + if (bound && addr > end && end > max) { > + max = end; > + match = window; > + } else if (!bound && addr < start && start < min) { > + min = start; > + match = window; > + } > + } > + > + if (offset == -1) { > + /* > + * Not even found the matched type. This may happen, > + * for example, if try to translate IO address in a HB > + * without IO window. Just return the original address, > + * it will fail later anyway. > + */ > + if (match == NULL) > + return addr; > + > + return (bound ? max : min) + match->offset; > + } > + > + return addr + offset; > +} that is confusing. Can we use http://lkml.indiana.edu/hypermail/linux/kernel/1206.0/00437/pcibus_addr_converting_bus.patch instead? or as attached: [-- Attachment #2: pcibus_addr_converting_bus.patch --] [-- Type: text/x-patch, Size: 3793 bytes --] Subject: [PATCH] PCI: pcibus address to resource converting take bus directly For allocating resource under bus path, we do have dev pass along, and we could just use bus instead. Signed-off-by: Yinghai Lu <yinghai@kernel.org> --- drivers/pci/host-bridge.c | 34 +++++++++++++++++++++------------- include/linux/pci.h | 3 +++ 2 files changed, 24 insertions(+), 13 deletions(-) Index: linux-2.6/drivers/pci/host-bridge.c =================================================================== --- linux-2.6.orig/drivers/pci/host-bridge.c +++ linux-2.6/drivers/pci/host-bridge.c @@ -9,22 +9,19 @@ #include "pci.h" -static struct pci_bus *find_pci_root_bus(struct pci_dev *dev) +static struct pci_bus *find_pci_root_bus(struct pci_bus *bus) { - struct pci_bus *bus; - - bus = dev->bus; while (bus->parent) bus = bus->parent; return bus; } -static struct pci_host_bridge *find_pci_host_bridge(struct pci_dev *dev) +static struct pci_host_bridge *find_pci_host_bridge(struct pci_bus *bus) { - struct pci_bus *bus = find_pci_root_bus(dev); + struct pci_bus *root_bus = find_pci_root_bus(bus); - return to_pci_host_bridge(bus->bridge); + return to_pci_host_bridge(root_bus->bridge); } void pci_set_host_bridge_release(struct pci_host_bridge *bridge, @@ -40,10 +37,11 @@ static bool resource_contains(struct res return res1->start <= res2->start && res1->end >= res2->end; } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, - struct resource *res) +void __pcibios_resource_to_bus(struct pci_bus *bus, + struct pci_bus_region *region, + struct resource *res) { - struct pci_host_bridge *bridge = find_pci_host_bridge(dev); + struct pci_host_bridge *bridge = find_pci_host_bridge(bus); struct pci_host_bridge_window *window; resource_size_t offset = 0; @@ -60,6 +58,11 @@ void pcibios_resource_to_bus(struct pci_ region->start = res->start - offset; region->end = res->end - offset; } +void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, + struct resource *res) +{ + __pcibios_resource_to_bus(dev->bus, region, res); +} EXPORT_SYMBOL(pcibios_resource_to_bus); static bool region_contains(struct pci_bus_region *region1, @@ -68,10 +71,10 @@ static bool region_contains(struct pci_b return region1->start <= region2->start && region1->end >= region2->end; } -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, - struct pci_bus_region *region) +static void __pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, + struct pci_bus_region *region) { - struct pci_host_bridge *bridge = find_pci_host_bridge(dev); + struct pci_host_bridge *bridge = find_pci_host_bridge(bus); struct pci_host_bridge_window *window; resource_size_t offset = 0; @@ -93,4 +96,9 @@ void pcibios_bus_to_resource(struct pci_ res->start = region->start + offset; res->end = region->end + offset; } +void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, + struct pci_bus_region *region) +{ + __pcibios_bus_to_resource(dev->bus, res, region); +} EXPORT_SYMBOL(pcibios_bus_to_resource); Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -792,6 +792,9 @@ void pci_fixup_cardbus(struct pci_bus *) /* Generic PCI functions used internally */ +void __pcibios_resource_to_bus(struct pci_bus *bus, + struct pci_bus_region *region, + struct resource *res); void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, [-- Attachment #3: pcibus_addr_converting_bus_2.patch --] [-- Type: text/x-patch, Size: 1561 bytes --] Subject: [PATCH] PCI: Add pcibios_bus_addr_to_res() it takes addr and return converted address only. Signed-off-by: Yinghai Lu <yinghai@kernel.org> --- drivers/pci/host-bridge.c | 14 ++++++++++++++ include/linux/pci.h | 2 ++ 2 files changed, 16 insertions(+) Index: linux-2.6/drivers/pci/host-bridge.c =================================================================== --- linux-2.6.orig/drivers/pci/host-bridge.c +++ linux-2.6/drivers/pci/host-bridge.c @@ -102,3 +102,17 @@ void pcibios_bus_to_resource(struct pci_ __pcibios_bus_to_resource(dev->bus, res, region); } EXPORT_SYMBOL(pcibios_bus_to_resource); + +resource_size_t pcibios_bus_addr_to_res(struct pci_bus *bus, int flags, + resource_size_t addr) +{ + struct pci_bus_region region; + struct resource r; + + r.flags = flags; + region.start = addr; + region.end = addr; + __pcibios_bus_to_resource(bus, &r, ®ion); + + return r.end; +} Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -799,6 +799,8 @@ void pcibios_resource_to_bus(struct pci_ struct resource *res); void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region); +resource_size_t pcibios_bus_addr_to_res(struct pci_bus *bus, int flags, + resource_size_t addr); void pcibios_scan_specific_bus(int busn); struct pci_bus *pci_find_bus(int domain, int busnr); void pci_bus_add_devices(const struct pci_bus *bus); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address 2013-11-19 19:31 ` Yinghai Lu @ 2013-11-19 19:35 ` Yinghai Lu 2013-11-19 23:48 ` Bjorn Helgaas 1 sibling, 0 replies; 7+ messages in thread From: Yinghai Lu @ 2013-11-19 19:35 UTC (permalink / raw) To: Guo Chao; +Cc: linux-pci@vger.kernel.org, Bjorn Helgaas [-- Attachment #1: Type: text/plain, Size: 285 bytes --] On Tue, Nov 19, 2013 at 11:31 AM, Yinghai Lu <yinghai@kernel.org> wrote: > On Mon, Nov 18, 2013 at 10:36 PM, Guo Chao <yan@linux.vnet.ibm.com> > Can we use http://lkml.indiana.edu/hypermail/linux/kernel/1206.0/00437/pcibus_addr_converting_bus.patch > instead? > > or as attached: and [-- Attachment #2: allocate_high_at_first_v6_1.patch --] [-- Type: text/x-patch, Size: 4272 bytes --] Subject: [PATCH] PCI: Try to allocate mem64 above 4G at first Will fall back to below 4g if it can not find any above 4g. x86 32bit without X86_PAE support will have bottom set to 0, because resource_size_t is 32bit. Also for 32bit with resource_size_t 64bit kernel on machine with pae support we are safe because iomem_resource is limited to 32bit according to x86_phys_bits. -v2: update bottom assigning to make it clear for non-pae support machine. -v3: Bjorn's change: use MAX_RESOURCE instead of -1 use start/end instead of bottom/max for all arch instead of just x86_64 -v4: updated after PCI_MAX_RESOURCE_32 change. -v5: restore io handling to use PCI_MAX_RESOURCE_32 as limit. -v6: checking pcibios_resource_to_bus return for every bus res, to decide it if we need to try high at first. It supports all arches instead of just x86_64. Signed-off-by: Yinghai Lu <yinghai@kernel.org> --- arch/x86/include/asm/pci.h | 1 - drivers/pci/bus.c | 42 ++++++++++++++++++++++++++++++++++-------- drivers/pci/pci.h | 2 ++ include/linux/pci.h | 4 ---- 4 files changed, 36 insertions(+), 13 deletions(-) Index: linux-2.6/arch/x86/include/asm/pci.h =================================================================== --- linux-2.6.orig/arch/x86/include/asm/pci.h +++ linux-2.6/arch/x86/include/asm/pci.h @@ -155,7 +155,6 @@ void default_restore_msi_irqs(struct pci /* generic pci stuff */ #include <asm-generic/pci.h> -#define PCIBIOS_MAX_MEM_32 0xffffffff #ifdef CONFIG_NUMA /* Returns the node based on pci bus */ Index: linux-2.6/drivers/pci/bus.c =================================================================== --- linux-2.6.orig/drivers/pci/bus.c +++ linux-2.6/drivers/pci/bus.c @@ -125,15 +125,13 @@ pci_bus_alloc_resource(struct pci_bus *b { int i, ret = -ENOMEM; struct resource *r; - resource_size_t max = -1; type_mask |= IORESOURCE_IO | IORESOURCE_MEM; - /* don't allocate too high if the pref mem doesn't support 64bit*/ - if (!(res->flags & IORESOURCE_MEM_64)) - max = PCIBIOS_MAX_MEM_32; - pci_bus_for_each_resource(bus, r, i) { + resource_size_t start, end, middle; + struct pci_bus_region region; + if (!r) continue; @@ -147,14 +145,42 @@ pci_bus_alloc_resource(struct pci_bus *b !(res->flags & IORESOURCE_PREFETCH)) continue; + start = 0; + end = MAX_RESOURCE; + /* + * don't allocate too high if the pref mem doesn't + * support 64bit, also if this is a 64-bit mem + * resource, try above 4GB first + */ + __pcibios_resource_to_bus(bus, ®ion, r); + if (region.start <= PCI_MAX_ADDR_32 && + region.end > PCI_MAX_ADDR_32) { + middle = pcibios_bus_addr_to_res(bus, res->flags, + PCI_MAX_ADDR_32); + if (res->flags & IORESOURCE_MEM_64) + start = middle + 1; + else + end = middle; + } else if (region.start > PCI_MAX_ADDR_32 && + !(res->flags & IORESOURCE_MEM_64)) + continue; + +again: /* Ok, try it out.. */ ret = allocate_resource(r, res, size, - r->start ? : min, - max, align, + max(start, r->start ? : min), + end, align, alignf, alignf_data); if (ret == 0) - break; + return 0; + + if (start != 0) { + start = 0; + goto again; + } } + + return ret; } Index: linux-2.6/drivers/pci/pci.h =================================================================== --- linux-2.6.orig/drivers/pci/pci.h +++ linux-2.6/drivers/pci/pci.h @@ -195,6 +195,8 @@ enum pci_bar_type { pci_bar_mem64, /* A 64-bit memory BAR */ }; +#define PCI_MAX_ADDR_32 ((resource_size_t)0xffffffff) + bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, int crs_timeout); int pci_setup_device(struct pci_dev *dev); Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -1539,10 +1539,6 @@ static inline struct pci_host_bridge *pc #include <asm/pci.h> -#ifndef PCIBIOS_MAX_MEM_32 -#define PCIBIOS_MAX_MEM_32 (-1) -#endif - /* these helpers provide future and backwards compatibility * for accessing popular PCI BAR info */ static inline resource_size_t pci_resource_start(const struct pci_dev *dev, ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address 2013-11-19 19:31 ` Yinghai Lu 2013-11-19 19:35 ` Yinghai Lu @ 2013-11-19 23:48 ` Bjorn Helgaas 1 sibling, 0 replies; 7+ messages in thread From: Bjorn Helgaas @ 2013-11-19 23:48 UTC (permalink / raw) To: Yinghai Lu; +Cc: Guo Chao, linux-pci@vger.kernel.org On Tue, Nov 19, 2013 at 12:31 PM, Yinghai Lu <yinghai@kernel.org> wrote: > On Mon, Nov 18, 2013 at 10:36 PM, Guo Chao <yan@linux.vnet.ibm.com> wrote: >> In resource assignment code, limits are exerted to restrict allocated >> resource range. However these limits are PCI address but compared to >> CPU address in the end. Translated them before comparing. >> >> We can't just use pcibios_bus_to_resource because the limits may not >> included in the host bridge window. Introduce a help function to >> do this translation, if address missed, return an approximate one. >> >> Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com> >> --- >> drivers/pci/bus.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 63 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c >> index fc1b740..532c0a4 100644 >> --- a/drivers/pci/bus.c >> +++ b/drivers/pci/bus.c >> @@ -99,6 +99,64 @@ void pci_bus_remove_resources(struct pci_bus *bus) >> } >> >> /** >> + * pci_bus_to_resource >> + * >> + * Much like pcibios_bus_to_resource() except it takes a single address >> + * and returns an approximate one if target address is not included >> + * in the bridge window. The approximate address is smaller than required >> + * one is 'bound' is 1, larger than required one if 'bound' is 0. >> + */ >> +static resource_size_t pci_bus_to_resource(struct pci_bus *bus, int flags, >> + int mask, resource_size_t addr, int bound) >> +{ >> + struct pci_host_bridge *bridge; >> + struct pci_host_bridge_window *window, *match = NULL; >> + resource_size_t max = 0, min = -1; >> + resource_size_t offset = -1, start, end; >> + >> + while (bus->parent) >> + bus = bus->parent; >> + >> + bridge = to_pci_host_bridge(bus->bridge); >> + >> + list_for_each_entry(window, &bridge->windows, list) { >> + if ((flags ^ window->res->flags) & mask) >> + continue; >> + >> + start = window->res->start - window->offset; >> + end = window->res->end - window->offset; >> + >> + if (addr >= start && addr <= end) { >> + offset = window->offset; >> + break; >> + } >> + >> + if (bound && addr > end && end > max) { >> + max = end; >> + match = window; >> + } else if (!bound && addr < start && start < min) { >> + min = start; >> + match = window; >> + } >> + } >> + >> + if (offset == -1) { >> + /* >> + * Not even found the matched type. This may happen, >> + * for example, if try to translate IO address in a HB >> + * without IO window. Just return the original address, >> + * it will fail later anyway. >> + */ >> + if (match == NULL) >> + return addr; >> + >> + return (bound ? max : min) + match->offset; >> + } >> + >> + return addr + offset; >> +} > > that is confusing. I agree, this is way too confusing. I certainly agree that the current code is wrong -- PCIBIOS_MAX_MEM_32 is a limit on the *bus* address, but we're using it to limit CPU addresses. And it's not arch-dependent at all; it's strictly a function of PCI, so I think you should fix that, too. Your [2/3] patch is a start, but I don't think there's any reason to allow an arch to override it, and it's only used in one place, so it doesn't need to be in include/linux/pci.h where it's effectively exported to the world. It's completely bogus to try to compute "max" outside the loop because there's no requirement that the translation offset be the same for all the resources. But *inside* the loop, you have a valid struct resource, and you can easily compute the corresponding bus addresses and determine whether they fit in 32 bits. Bjorn ^ permalink raw reply [flat|nested] 7+ messages in thread
* [RFC PATCH 2/3] PCI: set proper default value of PCIBIOS_MAX_MEM_32 2013-11-19 6:36 [RFC PATCH 0/3] Make 64-bit prefetchable MMIO work Guo Chao 2013-11-19 6:36 ` [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address Guo Chao @ 2013-11-19 6:36 ` Guo Chao 2013-11-19 6:36 ` [RFC PATCH 3/3] PCI: do not reset bridge's IORESOURCE_MEM_64 flag for ROM BAR Guo Chao 2 siblings, 0 replies; 7+ messages in thread From: Guo Chao @ 2013-11-19 6:36 UTC (permalink / raw) To: linux-pci; +Cc: bhelgaas, yinghai PCIBIOS_MAX_MEM_32 is used to prevent 32-bit BAR from getting 4G-above address. Its default value -1 extends to 0xffffffffffffffff in 64-bit platform which make it useless at all. While arch can overwrite it, 0xffffffff should be good enough for those who does not have special requirement. Set PCIBIOS_MAX_MEM_32 to 0xffffffff and kill this definition in x86. Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com> --- arch/x86/include/asm/pci.h | 1 - include/linux/pci.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 7d74432..73ff4bc 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -125,7 +125,6 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, /* generic pci stuff */ #include <asm-generic/pci.h> -#define PCIBIOS_MAX_MEM_32 0xffffffff #ifdef CONFIG_NUMA /* Returns the node based on pci bus */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 835ec7b..f43405d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1487,7 +1487,7 @@ static inline struct pci_dev *pci_dev_get(struct pci_dev *dev) #include <asm/pci.h> #ifndef PCIBIOS_MAX_MEM_32 -#define PCIBIOS_MAX_MEM_32 (-1) +#define PCIBIOS_MAX_MEM_32 (0xffffffff) #endif /* these helpers provide future and backwards compatibility -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [RFC PATCH 3/3] PCI: do not reset bridge's IORESOURCE_MEM_64 flag for ROM BAR 2013-11-19 6:36 [RFC PATCH 0/3] Make 64-bit prefetchable MMIO work Guo Chao 2013-11-19 6:36 ` [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address Guo Chao 2013-11-19 6:36 ` [RFC PATCH 2/3] PCI: set proper default value of PCIBIOS_MAX_MEM_32 Guo Chao @ 2013-11-19 6:36 ` Guo Chao 2 siblings, 0 replies; 7+ messages in thread From: Guo Chao @ 2013-11-19 6:36 UTC (permalink / raw) To: linux-pci; +Cc: bhelgaas, yinghai If 32-bit prefetchable BARs detected, the prefetchable resource's IORESOURCE_MEM_64 flag of its upstream bridge will be reset. This in turn causes all upstream bridges up to the root bridge have their IORESOURCE_MEM_64 reset. If prefetchable windows in a system located above 4G, then they are never used for the sake of 32-bit prefetchable BAR. Desert 64-bit prefetchable windows for ROM BAR seems unreasonable. Just don't reset bridge's IORESOURCE_MEM_64 flag in case of ROM BARs. They will fail to get address from 4G-above prefetchable window and fall back to non-prefetchable window within 4G. Signed-off-by: Guo Chao <yan@linux.vnet.ibm.com> --- drivers/pci/setup-bus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 4ce83b2..e9006b9 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -974,7 +974,8 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, aligns[order] += align; if (order > max_order) max_order = order; - mem64_mask &= r->flags & IORESOURCE_MEM_64; + if (i != PCI_ROM_RESOURCE) + mem64_mask &= r->flags & IORESOURCE_MEM_64; if (realloc_head) children_add_size += get_res_add_size(realloc_head, r); -- 1.8.3.2 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2013-11-19 23:48 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-11-19 6:36 [RFC PATCH 0/3] Make 64-bit prefetchable MMIO work Guo Chao 2013-11-19 6:36 ` [RFC PATCH 1/3] PCI: do not compare CPU address with PCI address Guo Chao 2013-11-19 19:31 ` Yinghai Lu 2013-11-19 19:35 ` Yinghai Lu 2013-11-19 23:48 ` Bjorn Helgaas 2013-11-19 6:36 ` [RFC PATCH 2/3] PCI: set proper default value of PCIBIOS_MAX_MEM_32 Guo Chao 2013-11-19 6:36 ` [RFC PATCH 3/3] PCI: do not reset bridge's IORESOURCE_MEM_64 flag for ROM BAR Guo Chao
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).