From 90eab5e09de20e8d991bbb11f6edfb573f906352 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Mon, 27 Apr 2009 08:29:12 -0400 Subject: parisc: wire up preadv/pwritev syscalls Generic compat handlers look appropriate, so use those. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 03b9a01bc16..6a6296148e5 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -413,6 +413,8 @@ ENTRY_SAME(dup3) ENTRY_SAME(pipe2) ENTRY_SAME(inotify_init1) + ENTRY_COMP(preadv) + ENTRY_COMP(pwritev) /* Nothing yet */ -- cgit v1.2.3 From 071327ec9005e9a826d088d37021ed2c88e683f7 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Fri, 3 Apr 2009 01:49:22 +0000 Subject: parisc: remove CVS keywords Signed-off-by: Alexander Beregalov Acked-by: Matthew Wilcox Acked-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 3 +-- arch/parisc/kernel/pci.c | 3 +-- arch/parisc/kernel/processor.c | 3 +-- arch/parisc/kernel/setup.c | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 837530ea32e..f34082da009 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -1,5 +1,4 @@ -/* $Id: cache.c,v 1.4 2000/01/25 00:11:38 prumpf Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 6936386c986..f7064abc3bb 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -1,5 +1,4 @@ -/* $Id: pci.c,v 1.6 2000/01/29 00:12:05 grundler Exp $ - * +/* * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index e09d0f7fb6b..1ca69a808e3 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -1,5 +1,4 @@ -/* $Id: processor.c,v 1.1 2002/07/20 16:27:06 rhirst Exp $ - * +/* * Initial setup-routines for HP 9000 based hardware. * * Copyright (C) 1991, 1992, 1995 Linus Torvalds diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index 82131ca8e05..cb71f3dac99 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -1,5 +1,4 @@ -/* $Id: setup.c,v 1.8 2000/02/02 04:42:38 prumpf Exp $ - * +/* * Initial setup-routines for HP 9000 based hardware. * * Copyright (C) 1991, 1992, 1995 Linus Torvalds -- cgit v1.2.3 From 47b4150baa003fb83b93365f3eadd4c373e4fa6c Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sat, 6 Jun 2009 21:54:28 +0000 Subject: parisc: fix irq compile bugs in arch/parisc/kernel/irq.c Fix miscompilation in arch/parisc/kernel/irq.c: 123: warning: passing arg 1 of `cpumask_setall' from incompatible pointer type 141: warning: passing arg 1 of `cpumask_copy' from incompatible pointer type 300: warning: passing arg 1 of `cpumask_copy' from incompatible pointer type 357: warning: passing arg 2 of `cpumask_copy' from incompatible pointer type Signed-off-by: Helge Deller Signed-off-by: Kyle McMartin --- arch/parisc/kernel/irq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 8007f1e6572..639451c50e4 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -120,7 +120,7 @@ int cpu_check_affinity(unsigned int irq, const struct cpumask *dest) if (CHECK_IRQ_PER_CPU(irq)) { /* Bad linux design decision. The mask has already * been set; we must reset it */ - cpumask_setall(&irq_desc[irq].affinity); + cpumask_setall(irq_desc[irq].affinity); return -EINVAL; } @@ -138,7 +138,7 @@ static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest) if (cpu_dest < 0) return -1; - cpumask_copy(&irq_desc[irq].affinity, dest); + cpumask_copy(irq_desc[irq].affinity, dest); return 0; } @@ -299,7 +299,7 @@ int txn_alloc_irq(unsigned int bits_wide) unsigned long txn_affinity_addr(unsigned int irq, int cpu) { #ifdef CONFIG_SMP - cpumask_copy(&irq_desc[irq].affinity, cpumask_of(cpu)); + cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu)); #endif return per_cpu(cpu_data, cpu).txn_addr; @@ -356,7 +356,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) irq = eirr_to_irq(eirr_val); #ifdef CONFIG_SMP - cpumask_copy(&dest, &irq_desc[irq].affinity); + cpumask_copy(&dest, irq_desc[irq].affinity); if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) && !cpu_isset(smp_processor_id(), dest)) { int cpu = first_cpu(dest); -- cgit v1.2.3 From dfe07565021959f0f646e9e775810c1bfbe0f6d6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 10 Jun 2009 19:56:04 +0000 Subject: parisc: remove obsolete hw_interrupt_type The defines and typedefs (hw_interrupt_type, no_irq_type, irq_desc_t) have been kept around for migration reasons. After more than two years it's time to remove them finally. This patch cleans up one of the remaining users. When all such patches hit mainline we can remove the defines and typedefs finally. Impact: cleanup Convert the last remaining users to struct irq_chip and remove the define. Signed-off-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Kyle McMartin --- arch/parisc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c index 639451c50e4..330f536a932 100644 --- a/arch/parisc/kernel/irq.c +++ b/arch/parisc/kernel/irq.c @@ -144,7 +144,7 @@ static int cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest) } #endif -static struct hw_interrupt_type cpu_interrupt_type = { +static struct irq_chip cpu_interrupt_type = { .typename = "CPU", .startup = cpu_startup_irq, .shutdown = cpu_disable_irq, -- cgit v1.2.3 From ebc30a0f67a4d6a9470556f4311478b3b04c2b1f Mon Sep 17 00:00:00 2001 From: Coly Li Date: Thu, 30 Apr 2009 22:43:46 +0000 Subject: parisc: add parameter to read_cr16() This patch modifies parameter of au1x_counter1_read() from 'void' to 'struct clocksource *cs', which fixes compile warning for incompatible parameter type. Signed-off-by: Coly Li Signed-off-by: Helge Deller Cc: Ingo Molnar Signed-off-by: Kyle McMartin --- arch/parisc/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index d4dd05674c6..d97d07f47a5 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -173,7 +173,7 @@ EXPORT_SYMBOL(profile_pc); /* clock source code */ -static cycle_t read_cr16(void) +static cycle_t read_cr16(struct clocksource *cs) { return get_cycles(); } -- cgit v1.2.3 From 84be31be3727d11b2a91781306b642e801c5a379 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Mon, 1 Jun 2009 00:20:23 +0000 Subject: parisc: fix "delay!" timer handling Rewrote timer_interrupt() to properly handle the "delayed!" case. If we used floating point math to compute the number of ticks that had elapsed since the last timer interrupt, it could take up to 12K cycles (emperical!) to handle the interrupt. Existing code assumed it would never take more than 8k cycles. We end up programming Interval Timer to a value less than "current" cycle counter. Thus have to wait until Interval Timer "wrapped" and would then get the "delayed!" printk that I moved below. Since we don't really know what the upper limit is, I prefer to read CR16 again after we've programmed it to make sure we won't have to wait for CR16 to wrap. Further, the printk was between reading CR16 (cycle couner) and writing CR16 (the interval timer). This would cause us to continue to set the interval timer to a value that was "behind" the cycle counter. Rinse and repeat. So no printk's between reading CR16 and setting next interval timer. Tested on A500 (550 Mhz PA8600). Signed-off-by: Grant Grundler Tested-by: Kyle McMartin Signed-off-by: Kyle McMartin ---- Kyle, Helge, and other parisc's, Please test on 32-bit before committing. I think I have it right but recognize I might not. TODO: I wanted to use "do_div()" in order to get both remainder and value back with one division op. That should help with the latency alot but can be applied seperately from this patch. thanks, grant --- arch/parisc/kernel/time.c | 88 ++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 35 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index d97d07f47a5..a79c6f9e7e2 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -56,9 +56,9 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */ */ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) { - unsigned long now; + unsigned long now, now2; unsigned long next_tick; - unsigned long cycles_elapsed, ticks_elapsed; + unsigned long cycles_elapsed, ticks_elapsed = 1; unsigned long cycles_remainder; unsigned int cpu = smp_processor_id(); struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); @@ -71,44 +71,24 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) /* Initialize next_tick to the expected tick time. */ next_tick = cpuinfo->it_value; - /* Get current interval timer. - * CR16 reads as 64 bits in CPU wide mode. - * CR16 reads as 32 bits in CPU narrow mode. - */ + /* Get current cycle counter (Control Register 16). */ now = mfctl(16); cycles_elapsed = now - next_tick; - if ((cycles_elapsed >> 5) < cpt) { + if ((cycles_elapsed >> 6) < cpt) { /* use "cheap" math (add/subtract) instead * of the more expensive div/mul method */ cycles_remainder = cycles_elapsed; - ticks_elapsed = 1; while (cycles_remainder > cpt) { cycles_remainder -= cpt; ticks_elapsed++; } } else { + /* TODO: Reduce this to one fdiv op */ cycles_remainder = cycles_elapsed % cpt; - ticks_elapsed = 1 + cycles_elapsed / cpt; - } - - /* Can we differentiate between "early CR16" (aka Scenario 1) and - * "long delay" (aka Scenario 3)? I don't think so. - * - * We expected timer_interrupt to be delivered at least a few hundred - * cycles after the IT fires. But it's arbitrary how much time passes - * before we call it "late". I've picked one second. - */ - if (unlikely(ticks_elapsed > HZ)) { - /* Scenario 3: very long delay? bad in any case */ - printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!" - " cycles %lX rem %lX " - " next/now %lX/%lX\n", - cpu, - cycles_elapsed, cycles_remainder, - next_tick, now ); + ticks_elapsed += cycles_elapsed / cpt; } /* convert from "division remainder" to "remainder of clock tick" */ @@ -122,18 +102,56 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id) cpuinfo->it_value = next_tick; - /* Skip one clocktick on purpose if we are likely to miss next_tick. - * We want to avoid the new next_tick being less than CR16. - * If that happened, itimer wouldn't fire until CR16 wrapped. - * We'll catch the tick we missed on the tick after that. + /* Program the IT when to deliver the next interrupt. + * Only bottom 32-bits of next_tick are writable in CR16! */ - if (!(cycles_remainder >> 13)) - next_tick += cpt; - - /* Program the IT when to deliver the next interrupt. */ - /* Only bottom 32-bits of next_tick are written to cr16. */ mtctl(next_tick, 16); + /* Skip one clocktick on purpose if we missed next_tick. + * The new CR16 must be "later" than current CR16 otherwise + * itimer would not fire until CR16 wrapped - e.g 4 seconds + * later on a 1Ghz processor. We'll account for the missed + * tick on the next timer interrupt. + * + * "next_tick - now" will always give the difference regardless + * if one or the other wrapped. If "now" is "bigger" we'll end up + * with a very large unsigned number. + */ + now2 = mfctl(16); + if (next_tick - now2 > cpt) + mtctl(next_tick+cpt, 16); + +#if 1 +/* + * GGG: DEBUG code for how many cycles programming CR16 used. + */ + if (unlikely(now2 - now > 0x3000)) /* 12K cycles */ + printk (KERN_CRIT "timer_interrupt(CPU %d): SLOW! 0x%lx cycles!" + " cyc %lX rem %lX " + " next/now %lX/%lX\n", + cpu, now2 - now, cycles_elapsed, cycles_remainder, + next_tick, now ); +#endif + + /* Can we differentiate between "early CR16" (aka Scenario 1) and + * "long delay" (aka Scenario 3)? I don't think so. + * + * Timer_interrupt will be delivered at least a few hundred cycles + * after the IT fires. But it's arbitrary how much time passes + * before we call it "late". I've picked one second. + * + * It's important NO printk's are between reading CR16 and + * setting up the next value. May introduce huge variance. + */ + if (unlikely(ticks_elapsed > HZ)) { + /* Scenario 3: very long delay? bad in any case */ + printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!" + " cycles %lX rem %lX " + " next/now %lX/%lX\n", + cpu, + cycles_elapsed, cycles_remainder, + next_tick, now ); + } /* Done mucking with unreliable delivery of interrupts. * Go do system house keeping. -- cgit v1.2.3 From e82a3b75127188f20c7780bec580e148beb29da7 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 16 Jun 2009 20:51:48 +0000 Subject: parisc: ensure broadcast tlb purge runs single threaded The TLB flushing functions on hppa, which causes PxTLB broadcasts on the system bus, needs to be protected by irq-safe spinlocks to avoid irq handlers to deadlock the kernel. The deadlocks only happened during I/O intensive loads and triggered pretty seldom, which is why this bug went so long unnoticed. Signed-off-by: Helge Deller [edited to use spin_lock_irqsave on UP as well since we'd been locking there all this time anyway, --kyle] Signed-off-by: Kyle McMartin --- arch/parisc/kernel/cache.c | 23 +++++++++++++++-------- arch/parisc/kernel/pci-dma.c | 12 ++++++++---- 2 files changed, 23 insertions(+), 12 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index f34082da009..b6ed34de14e 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -397,12 +397,13 @@ EXPORT_SYMBOL(flush_kernel_icache_range_asm); void clear_user_page_asm(void *page, unsigned long vaddr) { + unsigned long flags; /* This function is implemented in assembly in pacache.S */ extern void __clear_user_page_asm(void *page, unsigned long vaddr); - purge_tlb_start(); + purge_tlb_start(flags); __clear_user_page_asm(page, vaddr); - purge_tlb_end(); + purge_tlb_end(flags); } #define FLUSH_THRESHOLD 0x80000 /* 0.5MB */ @@ -443,20 +444,24 @@ extern void clear_user_page_asm(void *page, unsigned long vaddr); void clear_user_page(void *page, unsigned long vaddr, struct page *pg) { + unsigned long flags; + purge_kernel_dcache_page((unsigned long)page); - purge_tlb_start(); + purge_tlb_start(flags); pdtlb_kernel(page); - purge_tlb_end(); + purge_tlb_end(flags); clear_user_page_asm(page, vaddr); } EXPORT_SYMBOL(clear_user_page); void flush_kernel_dcache_page_addr(void *addr) { + unsigned long flags; + flush_kernel_dcache_page_asm(addr); - purge_tlb_start(); + purge_tlb_start(flags); pdtlb_kernel(addr); - purge_tlb_end(); + purge_tlb_end(flags); } EXPORT_SYMBOL(flush_kernel_dcache_page_addr); @@ -489,8 +494,10 @@ void __flush_tlb_range(unsigned long sid, unsigned long start, if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ flush_tlb_all(); else { + unsigned long flags; + mtsp(sid, 1); - purge_tlb_start(); + purge_tlb_start(flags); if (split_tlb) { while (npages--) { pdtlb(start); @@ -503,7 +510,7 @@ void __flush_tlb_range(unsigned long sid, unsigned long start, start += PAGE_SIZE; } } - purge_tlb_end(); + purge_tlb_end(flags); } } diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c index 7d927eac932..c07f618ff7d 100644 --- a/arch/parisc/kernel/pci-dma.c +++ b/arch/parisc/kernel/pci-dma.c @@ -90,12 +90,14 @@ static inline int map_pte_uncached(pte_t * pte, if (end > PMD_SIZE) end = PMD_SIZE; do { + unsigned long flags; + if (!pte_none(*pte)) printk(KERN_ERR "map_pte_uncached: page already exists\n"); set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC)); - purge_tlb_start(); + purge_tlb_start(flags); pdtlb_kernel(orig_vaddr); - purge_tlb_end(); + purge_tlb_end(flags); vaddr += PAGE_SIZE; orig_vaddr += PAGE_SIZE; (*paddr_ptr) += PAGE_SIZE; @@ -168,11 +170,13 @@ static inline void unmap_uncached_pte(pmd_t * pmd, unsigned long vaddr, if (end > PMD_SIZE) end = PMD_SIZE; do { + unsigned long flags; pte_t page = *pte; + pte_clear(&init_mm, vaddr, pte); - purge_tlb_start(); + purge_tlb_start(flags); pdtlb_kernel(orig_vaddr); - purge_tlb_end(); + purge_tlb_end(flags); vaddr += PAGE_SIZE; orig_vaddr += PAGE_SIZE; pte++; -- cgit v1.2.3 From 4435607e986c792a8753f8850b570fdd80b21b10 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 23 Jun 2009 11:40:37 -0400 Subject: parisc: wire up rt_tgsigqueueinfo Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 6a6296148e5..83f8959ff65 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -413,8 +413,9 @@ ENTRY_SAME(dup3) ENTRY_SAME(pipe2) ENTRY_SAME(inotify_init1) - ENTRY_COMP(preadv) + ENTRY_COMP(preadv) /* 315 */ ENTRY_COMP(pwritev) + ENTRY_COMP(rt_tgsigqueueinfo) /* Nothing yet */ -- cgit v1.2.3 From c3301ab4fb64cf84321d35a8e94f68c94c816dc1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 23 Jun 2009 11:47:07 -0400 Subject: parisc: remove dead code from sys_parisc32.c Unless I'm totally missing something get_fd_set32/set_fd_set32 are completely unused. Signed-off-by: Christoph Hellwig Acked-by: Grant Grundler Signed-off-by: Kyle McMartin --- arch/parisc/kernel/sys_parisc32.c | 62 --------------------------------------- 1 file changed, 62 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index 1adb40c8166..92a0acaa0d1 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -174,68 +174,6 @@ asmlinkage long sys32_sched_rr_get_interval(pid_t pid, return ret; } -/*** copied from mips64 ***/ -/* - * Ooo, nasty. We need here to frob 32-bit unsigned longs to - * 64-bit unsigned longs. - */ - -static inline int -get_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset) -{ - n = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32)); - if (ufdset) { - unsigned long odd; - - if (!access_ok(VERIFY_WRITE, ufdset, n*sizeof(u32))) - return -EFAULT; - - odd = n & 1UL; - n &= ~1UL; - while (n) { - unsigned long h, l; - __get_user(l, ufdset); - __get_user(h, ufdset+1); - ufdset += 2; - *fdset++ = h << 32 | l; - n -= 2; - } - if (odd) - __get_user(*fdset, ufdset); - } else { - /* Tricky, must clear full unsigned long in the - * kernel fdset at the end, this makes sure that - * actually happens. - */ - memset(fdset, 0, ((n + 1) & ~1)*sizeof(u32)); - } - return 0; -} - -static inline void -set_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset) -{ - unsigned long odd; - n = (n + 8*sizeof(u32) - 1) / (8*sizeof(u32)); - - if (!ufdset) - return; - - odd = n & 1UL; - n &= ~1UL; - while (n) { - unsigned long h, l; - l = *fdset++; - h = l >> 32; - __put_user(l, ufdset); - __put_user(h, ufdset+1); - ufdset += 2; - n -= 2; - } - if (odd) - __put_user(*fdset, ufdset); -} - struct msgbuf32 { int mtype; char mtext[1]; -- cgit v1.2.3 From 64a0cdb026666cd9911fa045b863fb1f0f255dd8 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 23 Jun 2009 13:10:03 -0400 Subject: parisc: processor.c, fix bloated stack frame The pa_pdc_cell struct can be kmalloc'd, so do that instead. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/processor.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index 1ca69a808e3..c8fb61ed32f 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -120,22 +120,28 @@ static int __cpuinit processor_probe(struct parisc_device *dev) if (is_pdc_pat()) { ulong status; unsigned long bytecnt; - pdc_pat_cell_mod_maddr_block_t pa_pdc_cell; + pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; #undef USE_PAT_CPUID #ifdef USE_PAT_CPUID struct pdc_pat_cpu_num cpu_info; #endif + pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); + if (!pa_pdc_cell) + panic("couldn't allocate memory for PDC_PAT_CELL!"); + status = pdc_pat_cell_module(&bytecnt, dev->pcell_loc, - dev->mod_index, PA_VIEW, &pa_pdc_cell); + dev->mod_index, PA_VIEW, pa_pdc_cell); BUG_ON(PDC_OK != status); /* verify it's the same as what do_pat_inventory() found */ - BUG_ON(dev->mod_info != pa_pdc_cell.mod_info); - BUG_ON(dev->pmod_loc != pa_pdc_cell.mod_location); + BUG_ON(dev->mod_info != pa_pdc_cell->mod_info); + BUG_ON(dev->pmod_loc != pa_pdc_cell->mod_location); + + txn_addr = pa_pdc_cell->mod[0]; /* id_eid for IO sapic */ - txn_addr = pa_pdc_cell.mod[0]; /* id_eid for IO sapic */ + kfree(pa_pdc_cell); #ifdef USE_PAT_CPUID /* We need contiguous numbers for cpuid. Firmware's notion -- cgit v1.2.3 From 0d56d1aa0e756f077b700420c54e1a52140e73b4 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 23 Jun 2009 13:11:22 -0400 Subject: parisc: inventory.c, fix bloated stack frame The pa_pdc_cell struct can be kmalloc'd, so do that instead. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/inventory.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index bd1f7f1ff74..d228d823787 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -170,23 +170,27 @@ static void __init pagezero_memconfig(void) static int __init pat_query_module(ulong pcell_loc, ulong mod_index) { - pdc_pat_cell_mod_maddr_block_t pa_pdc_cell; + pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; unsigned long bytecnt; unsigned long temp; /* 64-bit scratch value */ long status; /* PDC return value status */ struct parisc_device *dev; + pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); + if (!pa_pdc_cell) + panic("couldn't allocate memory for PDC_PAT_CELL!"); + /* return cell module (PA or Processor view) */ status = pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index, - PA_VIEW, &pa_pdc_cell); + PA_VIEW, pa_pdc_cell); if (status != PDC_OK) { /* no more cell modules or error */ return status; } - temp = pa_pdc_cell.cba; - dev = alloc_pa_dev(PAT_GET_CBA(temp), &pa_pdc_cell.mod_path); + temp = pa_pdc_cell->cba; + dev = alloc_pa_dev(PAT_GET_CBA(temp), &(pa_pdc_cell->mod_path)); if (!dev) { return PDC_OK; } @@ -203,8 +207,8 @@ pat_query_module(ulong pcell_loc, ulong mod_index) /* save generic info returned from the call */ /* REVISIT: who is the consumer of this? not sure yet... */ - dev->mod_info = pa_pdc_cell.mod_info; /* pass to PAT_GET_ENTITY() */ - dev->pmod_loc = pa_pdc_cell.mod_location; + dev->mod_info = pa_pdc_cell->mod_info; /* pass to PAT_GET_ENTITY() */ + dev->pmod_loc = pa_pdc_cell->mod_location; register_parisc_device(dev); /* advertise device */ @@ -216,14 +220,14 @@ pat_query_module(ulong pcell_loc, ulong mod_index) case PAT_ENTITY_PROC: printk(KERN_DEBUG "PAT_ENTITY_PROC: id_eid 0x%lx\n", - pa_pdc_cell.mod[0]); + pa_pdc_cell->mod[0]); break; case PAT_ENTITY_MEM: printk(KERN_DEBUG "PAT_ENTITY_MEM: amount 0x%lx min_gni_base 0x%lx min_gni_len 0x%lx\n", - pa_pdc_cell.mod[0], pa_pdc_cell.mod[1], - pa_pdc_cell.mod[2]); + pa_pdc_cell->mod[0], pa_pdc_cell->mod[1], + pa_pdc_cell->mod[2]); break; case PAT_ENTITY_CA: printk(KERN_DEBUG "PAT_ENTITY_CA: %ld\n", pcell_loc); @@ -243,23 +247,26 @@ pat_query_module(ulong pcell_loc, ulong mod_index) print_ranges: pdc_pat_cell_module(&bytecnt, pcell_loc, mod_index, IO_VIEW, &io_pdc_cell); - printk(KERN_DEBUG "ranges %ld\n", pa_pdc_cell.mod[1]); - for (i = 0; i < pa_pdc_cell.mod[1]; i++) { + printk(KERN_DEBUG "ranges %ld\n", pa_pdc_cell->mod[1]); + for (i = 0; i < pa_pdc_cell->mod[1]; i++) { printk(KERN_DEBUG " PA_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", - i, pa_pdc_cell.mod[2 + i * 3], /* type */ - pa_pdc_cell.mod[3 + i * 3], /* start */ - pa_pdc_cell.mod[4 + i * 3]); /* finish (ie end) */ + i, pa_pdc_cell->mod[2 + i * 3], /* type */ + pa_pdc_cell->mod[3 + i * 3], /* start */ + pa_pdc_cell->mod[4 + i * 3]); /* finish (ie end) */ printk(KERN_DEBUG " IO_VIEW %ld: 0x%016lx 0x%016lx 0x%016lx\n", - i, io_pdc_cell.mod[2 + i * 3], /* type */ - io_pdc_cell.mod[3 + i * 3], /* start */ - io_pdc_cell.mod[4 + i * 3]); /* finish (ie end) */ + i, io_pdc_cell->mod[2 + i * 3], /* type */ + io_pdc_cell->mod[3 + i * 3], /* start */ + io_pdc_cell->mod[4 + i * 3]); /* finish (ie end) */ } printk(KERN_DEBUG "\n"); break; } #endif /* DEBUG_PAT */ + + kfree(pa_pdc_cell); + return PDC_OK; } -- cgit v1.2.3 From 538e23615fe78b6da151ef136e3f7c6ad1fda2c1 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 23 Jun 2009 20:22:06 -0400 Subject: parisc: wire sys_perf_counter_open to sys_ni_syscall Reserve a syscall slot for sys_perf_counter_open. Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 83f8959ff65..0c83673a03a 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -416,6 +416,7 @@ ENTRY_COMP(preadv) /* 315 */ ENTRY_COMP(pwritev) ENTRY_COMP(rt_tgsigqueueinfo) + ENTRY_SAME(ni_syscall) /* Nothing yet */ -- cgit v1.2.3 From 2d4618dce6a318ff4ec78dfe492cc3793015d540 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 23 Jun 2009 21:38:49 -0400 Subject: parisc: perf: wire up sys_perf_counter_open Signed-off-by: Kyle McMartin --- arch/parisc/kernel/syscall_table.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 0c83673a03a..cf145eb026b 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -416,7 +416,7 @@ ENTRY_COMP(preadv) /* 315 */ ENTRY_COMP(pwritev) ENTRY_COMP(rt_tgsigqueueinfo) - ENTRY_SAME(ni_syscall) + ENTRY_SAME(perf_counter_open) /* Nothing yet */ -- cgit v1.2.3 From ad361c9884e809340f6daca80d56a9e9c871690a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 6 Jul 2009 13:05:40 -0700 Subject: Remove multiple KERN_ prefixes from printk formats Commit 5fd29d6ccbc98884569d6f3105aeca70858b3e0f ("printk: clean up handling of log-levels and newlines") changed printk semantics. printk lines with multiple KERN_ prefixes are no longer emitted as before the patch. is now included in the output on each additional use. Remove all uses of multiple KERN_s in formats. Signed-off-by: Joe Perches Signed-off-by: Linus Torvalds --- arch/parisc/kernel/process.c | 2 +- arch/parisc/kernel/traps.c | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 61c07078c07..1f3aa8db020 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -156,7 +156,7 @@ void machine_power_off(void) * software. The user has to press the button himself. */ printk(KERN_EMERG "System shut down completed.\n" - KERN_EMERG "Please power this system off now."); + "Please power this system off now."); } void (*pm_power_off)(void) = machine_power_off; diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index c32f5d6d778..528f0ff9b27 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -250,15 +250,14 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) oops_enter(); /* Amuse the user in a SPARC fashion */ - if (err) printk( -KERN_CRIT " _______________________________ \n" -KERN_CRIT " < Your System ate a SPARC! Gah! >\n" -KERN_CRIT " ------------------------------- \n" -KERN_CRIT " \\ ^__^\n" -KERN_CRIT " \\ (xx)\\_______\n" -KERN_CRIT " (__)\\ )\\/\\\n" -KERN_CRIT " U ||----w |\n" -KERN_CRIT " || ||\n"); + if (err) printk(KERN_CRIT + " _______________________________ \n" + " < Your System ate a SPARC! Gah! >\n" + " ------------------------------- \n" + " \\ ^__^\n" + " (__)\\ )\\/\\\n" + " U ||----w |\n" + " || ||\n"); /* unlock the pdc lock if necessary */ pdc_emergency_unlock(); @@ -797,7 +796,8 @@ void notrace handle_interruption(int code, struct pt_regs *regs) else printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ", code); - printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm); + printk(KERN_CONT "pid=%d command='%s'\n", + task_pid_nr(current), current->comm); show_regs(regs); #endif si.si_signo = SIGSEGV; -- cgit v1.2.3 From b4f2e2ad5348063ef94aa623f6f09b52ecaf0990 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sun, 2 Aug 2009 12:34:08 +0200 Subject: parisc: Fix GOT overflow during module load on 64bit kernel Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/module.c | 50 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 5 deletions(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index ef5caf2e6ed..61ee0eec4e6 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -86,8 +86,12 @@ * the bottom of the table, which has a maximum signed displacement of * 0x3fff; however, since we're only going forward, this becomes * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have - * at most 1023 entries */ -#define MAX_GOTS 1023 + * at most 1023 entries. + * To overcome this 14bit displacement with some kernel modules, we'll + * use instead the unusal 16bit displacement method (see reassemble_16a) + * which gives us a maximum positive displacement of 0x7fff, and as such + * allows us to allocate up to 4095 GOT entries. */ +#define MAX_GOTS 4095 /* three functions to determine where in the module core * or init pieces the location is */ @@ -145,12 +149,40 @@ struct stub_entry { /* The reassemble_* functions prepare an immediate value for insertion into an opcode. pa-risc uses all sorts of weird bitfields in the instruction to hold the value. */ +static inline int sign_unext(int x, int len) +{ + int len_ones; + + len_ones = (1 << len) - 1; + return x & len_ones; +} + +static inline int low_sign_unext(int x, int len) +{ + int sign, temp; + + sign = (x >> (len-1)) & 1; + temp = sign_unext(x, len-1); + return (temp << 1) | sign; +} + static inline int reassemble_14(int as14) { return (((as14 & 0x1fff) << 1) | ((as14 & 0x2000) >> 13)); } +static inline int reassemble_16a(int as16) +{ + int s, t; + + /* Unusual 16-bit encoding, for wide mode only. */ + t = (as16 << 1) & 0xffff; + s = (as16 & 0x8000); + return (t ^ s ^ (s >> 1)) | (s >> 15); +} + + static inline int reassemble_17(int as17) { return (((as17 & 0x10000) >> 16) | @@ -407,6 +439,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, enum elf_stub_type stub_type, Elf_Addr loc0, unsigned int targetsec) { struct stub_entry *stub; + int __maybe_unused d; /* initialize stub_offset to point in front of the section */ if (!me->arch.section[targetsec].stub_offset) { @@ -460,12 +493,19 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, */ switch (stub_type) { case ELF_STUB_GOT: - stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ + d = get_got(me, value, addend); + if (d <= 15) { + /* Format 5 */ + stub->insns[0] = 0x0f6010db; /* ldd 0(%dp),%dp */ + stub->insns[0] |= low_sign_unext(d, 5) << 16; + } else { + /* Format 3 */ + stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ + stub->insns[0] |= reassemble_16a(d); + } stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ stub->insns[2] = 0xe820d000; /* bve (%r1) */ stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ - - stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); break; case ELF_STUB_MILLI: stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ -- cgit v1.2.3 From 2678251b207394aa8b9d92c653c05a8b3449f1f5 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Mon, 13 Jul 2009 01:44:37 +0000 Subject: parisc: Set correct bit in protection flags Signed-off-by: John David Anglin Signed-off-by: Helge Deller --- arch/parisc/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/parisc/kernel') diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index ae3e70cd1e1..e552e547cb9 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -553,7 +553,7 @@ * on most of those machines only handles cache transactions. */ extrd,u,*= \pte,_PAGE_NO_CACHE_BIT+32,1,%r0 - depi 1,12,1,\prot + depdi 1,12,1,\prot /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ convert_for_tlb_insert20 \pte -- cgit v1.2.3