diff options
Diffstat (limited to 'arch/ppc/kernel')
-rw-r--r-- | arch/ppc/kernel/pci.c | 41 | ||||
-rw-r--r-- | arch/ppc/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/ppc/kernel/traps.c | 66 | ||||
-rw-r--r-- | arch/ppc/kernel/vmlinux.lds.S | 1 |
4 files changed, 41 insertions, 69 deletions
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 63808e01cb0b..5e723c4c2571 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -879,7 +879,7 @@ pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, - unsigned long *offset, + resource_size_t *offset, enum pci_mmap_state mmap_state) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); @@ -891,7 +891,9 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* If memory, add on the PCI bridge address offset */ if (mmap_state == pci_mmap_mem) { +#if 0 /* See comment in pci_resource_to_user() for why this is disabled */ *offset += hose->pci_mem_offset; +#endif res_bit = IORESOURCE_MEM; } else { io_offset = hose->io_base_virt - ___IO_BASE; @@ -1030,7 +1032,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine) { - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + resource_size_t offset = vma->vm_pgoff << PAGE_SHIFT; struct resource *rp; int ret; @@ -1132,21 +1134,42 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar, resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); - unsigned long offset = 0; + resource_size_t offset = 0; if (hose == NULL) return; if (rsrc->flags & IORESOURCE_IO) - offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + offset = (unsigned long)hose->io_base_virt - _IO_BASE; + + /* We pass a fully fixed up address to userland for MMIO instead of + * a BAR value because X is lame and expects to be able to use that + * to pass to /dev/mem ! + * + * That means that we'll have potentially 64 bits values where some + * userland apps only expect 32 (like X itself since it thinks only + * Sparc has 64 bits MMIO) but if we don't do that, we break it on + * 32 bits CHRPs :-( + * + * Hopefully, the sysfs insterface is immune to that gunk. Once X + * has been fixed (and the fix spread enough), we can re-enable the + * 2 lines below and pass down a BAR value to userland. In that case + * we'll also have to re-enable the matching code in + * __pci_mmap_make_offset(). + * + * BenH. + */ +#if 0 + else if (rsrc->flags & IORESOURCE_MEM) + offset = hose->pci_mem_offset; +#endif - *start = rsrc->start + offset; - *end = rsrc->end + offset; + *start = rsrc->start - offset; + *end = rsrc->end - offset; } -void __init -pci_init_resource(struct resource *res, unsigned long start, unsigned long end, - int flags, char *name) +void __init pci_init_resource(struct resource *res, resource_size_t start, + resource_size_t end, int flags, char *name) { res->start = start; res->end = end; diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 27faeca2c7a2..3c506af19880 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -313,7 +313,7 @@ early_init(int r3, int r4, int r5) * Identify the CPU type and fix up code sections * that depend on which cpu we have. */ - spec = identify_cpu(offset); + spec = identify_cpu(offset, mfspr(SPRN_PVR)); do_feature_fixups(spec->cpu_features, PTRRELOC(&__start___ftr_fixup), PTRRELOC(&__stop___ftr_fixup)); diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 9661a91183b3..810f7aa72e92 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -28,6 +28,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/prctl.h> +#include <linux/bug.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -316,7 +317,7 @@ void machine_check_exception(struct pt_regs *regs) if (reason & MCSR_BUS_RBERR) printk("Bus - Read Data Bus Error\n"); if (reason & MCSR_BUS_WBERR) - printk("Bus - Read Data Bus Error\n"); + printk("Bus - Write Data Bus Error\n"); if (reason & MCSR_BUS_IPERR) printk("Bus - Instruction Parity Error\n"); if (reason & MCSR_BUS_RPERR) @@ -559,64 +560,9 @@ static void emulate_single_step(struct pt_regs *regs) } } -/* - * Look through the list of trap instructions that are used for BUG(), - * BUG_ON() and WARN_ON() and see if we hit one. At this point we know - * that the exception was caused by a trap instruction of some kind. - * Returns 1 if we should continue (i.e. it was a WARN_ON) or 0 - * otherwise. - */ -extern struct bug_entry __start___bug_table[], __stop___bug_table[]; - -#ifndef CONFIG_MODULES -#define module_find_bug(x) NULL -#endif - -struct bug_entry *find_bug(unsigned long bugaddr) +int is_valid_bugaddr(unsigned long addr) { - struct bug_entry *bug; - - for (bug = __start___bug_table; bug < __stop___bug_table; ++bug) - if (bugaddr == bug->bug_addr) - return bug; - return module_find_bug(bugaddr); -} - -int check_bug_trap(struct pt_regs *regs) -{ - struct bug_entry *bug; - unsigned long addr; - - if (regs->msr & MSR_PR) - return 0; /* not in kernel */ - addr = regs->nip; /* address of trap instruction */ - if (addr < PAGE_OFFSET) - return 0; - bug = find_bug(regs->nip); - if (bug == NULL) - return 0; - if (bug->line & BUG_WARNING_TRAP) { - /* this is a WARN_ON rather than BUG/BUG_ON */ -#ifdef CONFIG_XMON - xmon_printf(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); -#endif /* CONFIG_XMON */ - printk(KERN_ERR "Badness in %s at %s:%ld\n", - bug->function, bug->file, - bug->line & ~BUG_WARNING_TRAP); - dump_stack(); - return 1; - } -#ifdef CONFIG_XMON - xmon_printf(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - xmon(regs); -#endif /* CONFIG_XMON */ - printk(KERN_CRIT "kernel BUG in %s at %s:%ld!\n", - bug->function, bug->file, bug->line); - - return 0; + return addr >= PAGE_OFFSET; } void program_check_exception(struct pt_regs *regs) @@ -671,7 +617,9 @@ void program_check_exception(struct pt_regs *regs) /* trap exception */ if (debugger_bpt(regs)) return; - if (check_bug_trap(regs)) { + + if (!(regs->msr & MSR_PR) && /* not user-mode */ + report_bug(regs->nip) == BUG_TRAP_TYPE_WARN) { regs->nip += 4; return; } diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 16e8661e1fec..61921268a0d0 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S @@ -31,6 +31,7 @@ SECTIONS .plt : { *(.plt) } .text : { + _text = .; *(.text) SCHED_TEXT LOCK_TEXT |