Commit 95f4838e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-for-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc fixes from Helge Deller:
 "This time we made the kernel- and interruption stack allocation
  reentrant which fixed some strange kernel crashes (specifically
  protection ID traps).

  Furthemore this patchset fixes the interrupt stack in UP and SMP
  configurations by using native locking instructions.  And finally
  usage of floating point calculations on parisc were disabled in the
  MPILIB."

* 'parisc-for-3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: fix irq stack on UP and SMP
  parisc/superio: Use module_pci_driver to register driver
  parisc: make interrupt and interruption stack allocation reentrant
  parisc: show number of FPE and unaligned access handler calls in /proc/interrupts
  parisc: add additional parisc git tree to MAINTAINERS file
  parisc: use PAGE_SHIFT instead of hardcoded value 12 in pacache.S
  parisc: add rp5470 entry to machine database
  MPILIB: disable usage of floating point registers on parisc
parents 088d812f d96b51ec
...@@ -6084,6 +6084,7 @@ L: linux-parisc@vger.kernel.org ...@@ -6084,6 +6084,7 @@ L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/ W: http://www.parisc-linux.org/
Q: http://patchwork.kernel.org/project/linux-parisc/list/ Q: http://patchwork.kernel.org/project/linux-parisc/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git T: git git://git.kernel.org/pub/scm/linux/kernel/git/jejb/parisc-2.6.git
T: git git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git
S: Maintained S: Maintained
F: arch/parisc/ F: arch/parisc/
F: drivers/parisc/ F: drivers/parisc/
......
...@@ -438,7 +438,6 @@ ...@@ -438,7 +438,6 @@
SAVE_SP (%sr4, PT_SR4 (\regs)) SAVE_SP (%sr4, PT_SR4 (\regs))
SAVE_SP (%sr5, PT_SR5 (\regs)) SAVE_SP (%sr5, PT_SR5 (\regs))
SAVE_SP (%sr6, PT_SR6 (\regs)) SAVE_SP (%sr6, PT_SR6 (\regs))
SAVE_SP (%sr7, PT_SR7 (\regs))
SAVE_CR (%cr17, PT_IASQ0(\regs)) SAVE_CR (%cr17, PT_IASQ0(\regs))
mtctl %r0, %cr17 mtctl %r0, %cr17
......
...@@ -17,17 +17,14 @@ ...@@ -17,17 +17,14 @@
typedef struct { typedef struct {
unsigned int __softirq_pending; unsigned int __softirq_pending;
#ifdef CONFIG_DEBUG_STACKOVERFLOW
unsigned int kernel_stack_usage; unsigned int kernel_stack_usage;
#ifdef CONFIG_IRQSTACKS
unsigned int irq_stack_usage; unsigned int irq_stack_usage;
unsigned int irq_stack_counter;
#endif
#endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
unsigned int irq_resched_count; unsigned int irq_resched_count;
unsigned int irq_call_count; unsigned int irq_call_count;
#endif #endif
unsigned int irq_unaligned_count;
unsigned int irq_fpassist_count;
unsigned int irq_tlb_count; unsigned int irq_tlb_count;
} ____cacheline_aligned irq_cpustat_t; } ____cacheline_aligned irq_cpustat_t;
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/percpu.h> #include <asm/percpu.h>
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
/* /*
...@@ -58,26 +57,6 @@ ...@@ -58,26 +57,6 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
/*
* IRQ STACK - used for irq handler
*/
#ifdef __KERNEL__
#include <linux/spinlock_types.h>
#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */
union irq_stack_union {
unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
raw_spinlock_t lock;
};
DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
#endif /* __KERNEL__ */
/* /*
* Data detected about CPUs at boot time which is the same for all CPU's. * Data detected about CPUs at boot time which is the same for all CPU's.
* HP boxes are SMP - ie identical processors. * HP boxes are SMP - ie identical processors.
......
...@@ -65,15 +65,11 @@ ...@@ -65,15 +65,11 @@
rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */ rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */
mtsp %r0, %sr4 mtsp %r0, %sr4
mtsp %r0, %sr5 mtsp %r0, %sr5
mfsp %sr7, %r1 mtsp %r0, %sr6
or,= %r0,%r1,%r0 /* Only save sr7 in sr3 if sr7 != 0 */
mtsp %r1, %sr3
tovirt_r1 %r29 tovirt_r1 %r29
load32 KERNEL_PSW, %r1 load32 KERNEL_PSW, %r1
rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */ rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */
mtsp %r0, %sr6
mtsp %r0, %sr7
mtctl %r0, %cr17 /* Clear IIASQ tail */ mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */ mtctl %r0, %cr17 /* Clear IIASQ head */
mtctl %r1, %ipsw mtctl %r1, %ipsw
...@@ -119,17 +115,20 @@ ...@@ -119,17 +115,20 @@
/* we save the registers in the task struct */ /* we save the registers in the task struct */
copy %r30, %r17
mfctl %cr30, %r1 mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30
mtsp %r0,%sr7
mtsp %r16,%sr3
tophys %r1,%r9 tophys %r1,%r9
LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */ LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */
tophys %r1,%r9 tophys %r1,%r9
ldo TASK_REGS(%r9),%r9 ldo TASK_REGS(%r9),%r9
STREG %r30, PT_GR30(%r9) STREG %r17,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9) STREG %r29,PT_GR29(%r9)
STREG %r26,PT_GR26(%r9) STREG %r26,PT_GR26(%r9)
STREG %r16,PT_SR7(%r9)
copy %r9,%r29 copy %r9,%r29
mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30
.endm .endm
.macro get_stack_use_r30 .macro get_stack_use_r30
...@@ -137,10 +136,12 @@ ...@@ -137,10 +136,12 @@
/* we put a struct pt_regs on the stack and save the registers there */ /* we put a struct pt_regs on the stack and save the registers there */
tophys %r30,%r9 tophys %r30,%r9
STREG %r30,PT_GR30(%r9) copy %r30,%r1
ldo PT_SZ_ALGN(%r30),%r30 ldo PT_SZ_ALGN(%r30),%r30
STREG %r1,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9) STREG %r29,PT_GR29(%r9)
STREG %r26,PT_GR26(%r9) STREG %r26,PT_GR26(%r9)
STREG %r16,PT_SR7(%r9)
copy %r9,%r29 copy %r9,%r29
.endm .endm
......
...@@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_list[] = { ...@@ -222,6 +222,7 @@ static struct hp_hardware hp_hardware_list[] = {
{HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"}, {HPHW_NPROC,0x5DD,0x4,0x81,"Duet W2"},
{HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"}, {HPHW_NPROC,0x5DE,0x4,0x81,"Piccolo W+"},
{HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"}, {HPHW_NPROC,0x5DF,0x4,0x81,"Cantata W2"},
{HPHW_NPROC,0x5DF,0x0,0x00,"Marcato W+? (rp5470)"},
{HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"}, {HPHW_NPROC,0x5E0,0x4,0x91,"Cantata DC- W2"},
{HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"}, {HPHW_NPROC,0x5E1,0x4,0x91,"Crescendo DC- W2"},
{HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"}, {HPHW_NPROC,0x5E2,0x4,0x91,"Crescendo 650 W2"},
......
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/types.h> #include <linux/types.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/ldcw.h>
#undef PARISC_IRQ_CR16_COUNTS #undef PARISC_IRQ_CR16_COUNTS
...@@ -172,10 +172,6 @@ int arch_show_interrupts(struct seq_file *p, int prec) ...@@ -172,10 +172,6 @@ int arch_show_interrupts(struct seq_file *p, int prec)
for_each_online_cpu(j) for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage); seq_printf(p, "%10u ", irq_stats(j)->irq_stack_usage);
seq_puts(p, " Interrupt stack usage\n"); seq_puts(p, " Interrupt stack usage\n");
seq_printf(p, "%*s: ", prec, "ISC");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_stack_counter);
seq_puts(p, " Interrupt stack usage counter\n");
# endif # endif
#endif #endif
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
...@@ -188,6 +184,14 @@ int arch_show_interrupts(struct seq_file *p, int prec) ...@@ -188,6 +184,14 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_printf(p, "%10u ", irq_stats(j)->irq_call_count); seq_printf(p, "%10u ", irq_stats(j)->irq_call_count);
seq_puts(p, " Function call interrupts\n"); seq_puts(p, " Function call interrupts\n");
#endif #endif
seq_printf(p, "%*s: ", prec, "UAH");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_unaligned_count);
seq_puts(p, " Unaligned access handler traps\n");
seq_printf(p, "%*s: ", prec, "FPA");
for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_fpassist_count);
seq_puts(p, " Floating point assist traps\n");
seq_printf(p, "%*s: ", prec, "TLB"); seq_printf(p, "%*s: ", prec, "TLB");
for_each_online_cpu(j) for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count); seq_printf(p, "%10u ", irq_stats(j)->irq_tlb_count);
...@@ -376,6 +380,24 @@ static inline int eirr_to_irq(unsigned long eirr) ...@@ -376,6 +380,24 @@ static inline int eirr_to_irq(unsigned long eirr)
return (BITS_PER_LONG - bit) + TIMER_IRQ; return (BITS_PER_LONG - bit) + TIMER_IRQ;
} }
#ifdef CONFIG_IRQSTACKS
/*
* IRQ STACK - used for irq handler
*/
#define IRQ_STACK_SIZE (4096 << 2) /* 16k irq stack size */
union irq_stack_union {
unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
volatile unsigned int slock[4];
volatile unsigned int lock[1];
};
DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = {
.slock = { 1,1,1,1 },
};
#endif
int sysctl_panic_on_stackoverflow = 1; int sysctl_panic_on_stackoverflow = 1;
static inline void stack_overflow_check(struct pt_regs *regs) static inline void stack_overflow_check(struct pt_regs *regs)
...@@ -442,27 +464,26 @@ static inline void stack_overflow_check(struct pt_regs *regs) ...@@ -442,27 +464,26 @@ static inline void stack_overflow_check(struct pt_regs *regs)
} }
#ifdef CONFIG_IRQSTACKS #ifdef CONFIG_IRQSTACKS
DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { /* in entry.S: */
.lock = __RAW_SPIN_LOCK_UNLOCKED((irq_stack_union).lock) void call_on_stack(unsigned long p1, void *func, unsigned long new_stack);
};
static void execute_on_irq_stack(void *func, unsigned long param1) static void execute_on_irq_stack(void *func, unsigned long param1)
{ {
union irq_stack_union *union_ptr; union irq_stack_union *union_ptr;
unsigned long irq_stack; unsigned long irq_stack;
raw_spinlock_t *irq_stack_in_use; volatile unsigned int *irq_stack_in_use;
union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
irq_stack = (unsigned long) &union_ptr->stack; irq_stack = (unsigned long) &union_ptr->stack;
irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.lock), irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
64); /* align for stack frame usage */ 64); /* align for stack frame usage */
/* We may be called recursive. If we are already using the irq stack, /* We may be called recursive. If we are already using the irq stack,
* just continue to use it. Use spinlocks to serialize * just continue to use it. Use spinlocks to serialize
* the irq stack usage. * the irq stack usage.
*/ */
irq_stack_in_use = &union_ptr->lock; irq_stack_in_use = (volatile unsigned int *)__ldcw_align(union_ptr);
if (!raw_spin_trylock(irq_stack_in_use)) { if (!__ldcw(irq_stack_in_use)) {
void (*direct_call)(unsigned long p1) = func; void (*direct_call)(unsigned long p1) = func;
/* We are using the IRQ stack already. /* We are using the IRQ stack already.
...@@ -474,10 +495,8 @@ static void execute_on_irq_stack(void *func, unsigned long param1) ...@@ -474,10 +495,8 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
/* This is where we switch to the IRQ stack. */ /* This is where we switch to the IRQ stack. */
call_on_stack(param1, func, irq_stack); call_on_stack(param1, func, irq_stack);
__inc_irq_stat(irq_stack_counter);
/* free up irq stack usage. */ /* free up irq stack usage. */
do_raw_spin_unlock(irq_stack_in_use); *irq_stack_in_use = 1;
} }
asmlinkage void do_softirq(void) asmlinkage void do_softirq(void)
......
...@@ -612,7 +612,7 @@ ENTRY(copy_user_page_asm) ...@@ -612,7 +612,7 @@ ENTRY(copy_user_page_asm)
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */ extrw,u %r23, 24,25, %r23 /* convert phys addr to tlb insert format */
depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */ depw %r24, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */ depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
copy %r28, %r29 copy %r28, %r29
depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */ depwi 1, 9,1, %r29 /* Form aliased virtual address 'from' */
#endif #endif
...@@ -762,7 +762,7 @@ ENTRY(clear_user_page_asm) ...@@ -762,7 +762,7 @@ ENTRY(clear_user_page_asm)
#else #else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */ depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
#endif #endif
/* Purge any old translation */ /* Purge any old translation */
...@@ -846,7 +846,7 @@ ENTRY(flush_dcache_page_asm) ...@@ -846,7 +846,7 @@ ENTRY(flush_dcache_page_asm)
#else #else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */ depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
#endif #endif
/* Purge any old translation */ /* Purge any old translation */
...@@ -922,7 +922,7 @@ ENTRY(flush_icache_page_asm) ...@@ -922,7 +922,7 @@ ENTRY(flush_icache_page_asm)
#else #else
extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
depwi 0, 31,12, %r28 /* Clear any offset bits */ depwi 0, 31,PAGE_SHIFT, %r28 /* Clear any offset bits */
#endif #endif
/* Purge any old translation */ /* Purge any old translation */
......
...@@ -646,6 +646,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) ...@@ -646,6 +646,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
case 14: case 14:
/* Assist Exception Trap, i.e. floating point exception. */ /* Assist Exception Trap, i.e. floating point exception. */
die_if_kernel("Floating point exception", regs, 0); /* quiet */ die_if_kernel("Floating point exception", regs, 0); /* quiet */
__inc_irq_stat(irq_fpassist_count);
handle_fpe(regs); handle_fpe(regs);
return; return;
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/hardirq.h>
/* #define DEBUG_UNALIGNED 1 */ /* #define DEBUG_UNALIGNED 1 */
...@@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *regs) ...@@ -454,6 +455,8 @@ void handle_unaligned(struct pt_regs *regs)
struct siginfo si; struct siginfo si;
register int flop=0; /* true if this is a flop */ register int flop=0; /* true if this is a flop */
__inc_irq_stat(irq_unaligned_count);
/* log a message with pacing */ /* log a message with pacing */
if (user_mode(regs)) { if (user_mode(regs)) {
if (current->thread.flags & PARISC_UAC_SIGBUS) { if (current->thread.flags & PARISC_UAC_SIGBUS) {
......
...@@ -494,15 +494,4 @@ static struct pci_driver superio_driver = { ...@@ -494,15 +494,4 @@ static struct pci_driver superio_driver = {
.probe = superio_probe, .probe = superio_probe,
}; };
static int __init superio_modinit(void) module_pci_driver(superio_driver);
{
return pci_register_driver(&superio_driver);
}
static void __exit superio_exit(void)
{
pci_unregister_driver(&superio_driver);
}
module_init(superio_modinit);
module_exit(superio_exit);
...@@ -318,7 +318,8 @@ extern UDItype __udiv_qrnnd(); ...@@ -318,7 +318,8 @@ extern UDItype __udiv_qrnnd();
"rM" ((USItype)(bh)), \ "rM" ((USItype)(bh)), \
"rM" ((USItype)(al)), \ "rM" ((USItype)(al)), \
"rM" ((USItype)(bl))) "rM" ((USItype)(bl)))
#if defined(_PA_RISC1_1) #if 0 && defined(_PA_RISC1_1)
/* xmpyu uses floating point register which is not allowed in Linux kernel. */
#define umul_ppmm(wh, wl, u, v) \ #define umul_ppmm(wh, wl, u, v) \
do { \ do { \
union {UDItype __ll; \ union {UDItype __ll; \
...@@ -337,7 +338,7 @@ do { \ ...@@ -337,7 +338,7 @@ do { \
#define UMUL_TIME 40 #define UMUL_TIME 40
#define UDIV_TIME 80 #define UDIV_TIME 80
#endif #endif
#ifndef LONGLONG_STANDALONE #if 0 /* #ifndef LONGLONG_STANDALONE */
#define udiv_qrnnd(q, r, n1, n0, d) \ #define udiv_qrnnd(q, r, n1, n0, d) \
do { USItype __r; \ do { USItype __r; \
(q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \ (q) = __udiv_qrnnd(&__r, (n1), (n0), (d)); \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment