From 93a6423bd84d977bd768a001c6c3868e6a20b63a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Aug 2014 23:22:39 -0700 Subject: sparc64: Expand PCI bridge probing debug logging. Dump the various aspects of the PCI bridge probed at boot time, most importantly the bridge number ranges, and the ranges property. This helps diagnose PCI resource issues and other problems by giving ofpci_debug=1 on the boot command line. Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index 539babf00bb2..da24fb6deb03 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -432,6 +432,11 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, node->full_name); return; } + + if (ofpci_verbose) + printk(" Bridge bus range [%u --> %u]\n", + busrange[0], busrange[1]); + ranges = of_get_property(node, "ranges", &len); simba = 0; if (ranges == NULL) { @@ -451,6 +456,10 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, pci_bus_insert_busn_res(bus, busrange[0], busrange[1]); bus->bridge_ctl = 0; + if (ofpci_verbose) + printk(" Bridge ranges[%p] simba[%d]\n", + ranges, simba); + /* parse ranges property, or cook one up by hand for Simba */ /* PCI #address-cells == 3 and #size-cells == 2 always */ res = &dev->resource[PCI_BRIDGE_RESOURCES]; @@ -468,6 +477,14 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, } i = 1; for (; len >= 32; len -= 32, ranges += 8) { + u64 start; + + if (ofpci_verbose) + printk(" RAW Range[%08x:%08x:%08x:%08x:%08x:%08x:" + "%08x:%08x]\n", + ranges[0], ranges[1], ranges[2], ranges[3], + ranges[4], ranges[5], ranges[6], ranges[7]); + flags = pci_parse_of_flags(ranges[0]); size = GET_64BIT(ranges, 6); if (flags == 0 || size == 0) @@ -490,8 +507,13 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, } res->flags = flags; - region.start = GET_64BIT(ranges, 1); + region.start = start = GET_64BIT(ranges, 1); region.end = region.start + size - 1; + + if (ofpci_verbose) + printk(" Using flags[%08x] start[%016llx] size[%016llx]\n", + flags, start, size); + pcibios_bus_to_resource(dev->bus, res, ®ion); } after_ranges: -- cgit v1.2.3 From 4afba24e5fc2626a3c604ec990539572f6662ff9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Aug 2014 23:27:01 -0700 Subject: sparc64: Skip bogus PCI bridge ranges. It seems that when a PCI Express bridge is not in use and has no devices behind it, the ranges property is bogus. Specifically the size property is of the form [0xffffffff:...], and if you add this size to the resource start address the 64-bit calculation will overflow. Just check specifically for this size value signature and skip them. Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index da24fb6deb03..cc4c31e5185e 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -489,6 +489,17 @@ static void of_scan_pci_bridge(struct pci_pbm_info *pbm, size = GET_64BIT(ranges, 6); if (flags == 0 || size == 0) continue; + + /* On PCI-Express systems, PCI bridges that have no devices downstream + * have a bogus size value where the first 32-bit cell is 0xffffffff. + * This results in a bogus range where start + size overflows. + * + * Just skip these otherwise the kernel will complain when the resource + * tries to be claimed. + */ + if (size >> 32 == 0xffffffff) + continue; + if (flags & IORESOURCE_IO) { res = bus->resource[0]; if (res->flags) { -- cgit v1.2.3 From f1d25d37d316b8af202e51a4f82df01e12fe2661 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 12 Aug 2014 23:29:09 -0700 Subject: sparc64: Properly claim resources as each PCI bus is probed. Perform a pci_claim_resource() on all valid resources discovered during the OF device tree scan. Based almost entirely upon the PCI OF bus probing code which does the same thing there. Signed-off-by: David S. Miller --- arch/sparc/kernel/pci.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index cc4c31e5185e..b36365f49478 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -617,6 +617,36 @@ static void pci_bus_register_of_sysfs(struct pci_bus *bus) pci_bus_register_of_sysfs(child_bus); } +static void pci_claim_bus_resources(struct pci_bus *bus) +{ + struct pci_bus *child_bus; + struct pci_dev *dev; + + list_for_each_entry(dev, &bus->devices, bus_list) { + int i; + + for (i = 0; i < PCI_NUM_RESOURCES; i++) { + struct resource *r = &dev->resource[i]; + + if (r->parent || !r->start || !r->flags) + continue; + + if (ofpci_verbose) + printk("PCI: Claiming %s: " + "Resource %d: %016llx..%016llx [%x]\n", + pci_name(dev), i, + (unsigned long long)r->start, + (unsigned long long)r->end, + (unsigned int)r->flags); + + pci_claim_resource(dev, i); + } + } + + list_for_each_entry(child_bus, &bus->children, node) + pci_claim_bus_resources(child_bus); +} + struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, struct device *parent) { @@ -647,6 +677,8 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm, pci_bus_add_devices(bus); pci_bus_register_of_sysfs(bus); + pci_claim_bus_resources(bus); + return bus; } -- cgit v1.2.3 From 10cf15e1d1289aa0bf1d26e9f55176b4c7c5c512 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 13 Aug 2014 22:00:09 -0700 Subject: sparc: Hook up memfd_create system call. Signed-off-by: David S. Miller --- arch/sparc/include/uapi/asm/unistd.h | 3 ++- arch/sparc/kernel/systbls_32.S | 2 +- arch/sparc/kernel/systbls_64.S | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/sparc/include/uapi/asm/unistd.h b/arch/sparc/include/uapi/asm/unistd.h index 886cab456e1b..c842a89b1190 100644 --- a/arch/sparc/include/uapi/asm/unistd.h +++ b/arch/sparc/include/uapi/asm/unistd.h @@ -413,8 +413,9 @@ #define __NR_renameat2 345 #define __NR_seccomp 346 #define __NR_getrandom 347 +#define __NR_memfd_create 348 -#define NR_syscalls 348 +#define NR_syscalls 349 /* Bitmask values returned from kern_features system call. */ #define KERN_FEATURE_MIXED_MODE_STACK 0x00000001 diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S index 217893e18d78..6a873c344bc0 100644 --- a/arch/sparc/kernel/systbls_32.S +++ b/arch/sparc/kernel/systbls_32.S @@ -86,4 +86,4 @@ sys_call_table: /*330*/ .long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime /*335*/ .long sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev /*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr -/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom +/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S index d93b49d1b420..d9151b6490d8 100644 --- a/arch/sparc/kernel/systbls_64.S +++ b/arch/sparc/kernel/systbls_64.S @@ -87,7 +87,7 @@ sys_call_table32: /*330*/ .word compat_sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime .word sys_syncfs, compat_sys_sendmmsg, sys_setns, compat_sys_process_vm_readv, compat_sys_process_vm_writev /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr - .word sys32_renameat2, sys_seccomp, sys_getrandom + .word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create #endif /* CONFIG_COMPAT */ @@ -166,4 +166,4 @@ sys_call_table: /*330*/ .word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime .word sys_syncfs, sys_sendmmsg, sys_setns, sys_process_vm_readv, sys_process_vm_writev /*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr - .word sys_renameat2, sys_seccomp, sys_getrandom + .word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create -- cgit v1.2.3