From caebf9103be2e6a5330c6395a1f9f213edb0c8df Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 23 Sep 2010 21:52:52 -0700 Subject: sparc: keep calling do_signal() as long as pending signals remain Analog of what commit 494486a1d2697f2153199b6501ab5b4d6e15a2bb had done to alpha (another architecture with similar bug). One note: in rtrap_32.S part clr %l6 has been a rudiment of left after commit 28e6103665301ce60634e8a77f0b657c6cc099de (sparc: Fix debugger syscall restart interactions) has killed %l6 use in there. Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/kernel/rtrap_32.S | 6 +++--- arch/sparc/kernel/rtrap_64.S | 36 +++--------------------------------- 2 files changed, 6 insertions(+), 36 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S index 4da2e1f6629..5f5f74c2c2c 100644 --- a/arch/sparc/kernel/rtrap_32.S +++ b/arch/sparc/kernel/rtrap_32.S @@ -78,9 +78,9 @@ signal_p: call do_notify_resume add %sp, STACKFRAME_SZ, %o0 ! pt_regs ptr - /* Fall through. */ - ld [%sp + STACKFRAME_SZ + PT_PSR], %t_psr - clr %l6 + b signal_p + ld [%curptr + TI_FLAGS], %g2 + ret_trap_continue: sethi %hi(PSR_SYSCALL), %g1 andn %t_psr, %g1, %t_psr diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 090b9e9ad5e..77f1b95e080 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S @@ -34,37 +34,9 @@ __handle_preemption: __handle_user_windows: call fault_in_user_windows wrpr %g0, RTRAP_PSTATE, %pstate - wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - /* Redo sched+sig checks */ - ldx [%g6 + TI_FLAGS], %l0 - andcc %l0, _TIF_NEED_RESCHED, %g0 - - be,pt %xcc, 1f - nop - call schedule - wrpr %g0, RTRAP_PSTATE, %pstate - wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - ldx [%g6 + TI_FLAGS], %l0 - -1: andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 - be,pt %xcc, __handle_user_windows_continue - nop - mov %l5, %o1 - add %sp, PTREGS_OFF, %o0 - mov %l0, %o2 - - call do_notify_resume - wrpr %g0, RTRAP_PSTATE, %pstate - wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - /* Signal delivery can modify pt_regs tstate, so we must - * reload it. - */ - ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 - sethi %hi(0xf << 20), %l4 - and %l1, %l4, %l4 - ba,pt %xcc, __handle_user_windows_continue + ba,pt %xcc, __handle_preemption_continue + wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate - andn %l1, %l4, %l1 __handle_userfpu: rd %fprs, %l5 andcc %l5, FPRS_FEF, %g0 @@ -87,7 +59,7 @@ __handle_signal: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 sethi %hi(0xf << 20), %l4 and %l1, %l4, %l4 - ba,pt %xcc, __handle_signal_continue + ba,pt %xcc, __handle_preemption_continue andn %l1, %l4, %l1 /* When returning from a NMI (%pil==15) interrupt we want to @@ -177,11 +149,9 @@ __handle_preemption_continue: bne,pn %xcc, __handle_preemption andcc %l0, _TIF_DO_NOTIFY_RESUME_MASK, %g0 bne,pn %xcc, __handle_signal -__handle_signal_continue: ldub [%g6 + TI_WSAVED], %o2 brnz,pn %o2, __handle_user_windows nop -__handle_user_windows_continue: sethi %hi(TSTATE_PEF), %o0 andcc %l1, %o0, %g0 -- cgit v1.2.3-70-g09d2 From 9088333e3d83a68aeac15f7810c3cbf332b80303 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 23 Sep 2010 22:06:47 -0700 Subject: sparc32: Fix unaligned stack handling on trap return. When the rett stack checking code sees the stack is unaligned (in both the sun4c and srmmu cases) it jumps to the window fault-in path. But that just tries to page the stack pages in, it doesn't do anything special if the stack is misaligned. Therefore we essentially just loop forever in the trap return path. Fix this by emitting a SIGILL in the stack fault-in code if the stack is mis-aligned. Reported-by: Al Viro Signed-off-by: David S. Miller --- arch/sparc/mm/fault_32.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'arch') diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index bd8601601af..5b836f5aea9 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c @@ -539,6 +539,12 @@ do_sigbus: __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); } +static void check_stack_aligned(unsigned long sp) +{ + if (sp & 0x7UL) + force_sig(SIGILL, current); +} + void window_overflow_fault(void) { unsigned long sp; @@ -547,6 +553,8 @@ void window_overflow_fault(void) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 1); force_user_fault(sp, 1); + + check_stack_aligned(sp); } void window_underflow_fault(unsigned long sp) @@ -554,6 +562,8 @@ void window_underflow_fault(unsigned long sp) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); + + check_stack_aligned(sp); } void window_ret_fault(struct pt_regs *regs) @@ -564,4 +574,6 @@ void window_ret_fault(struct pt_regs *regs) if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) force_user_fault(sp + 0x38, 0); force_user_fault(sp, 0); + + check_stack_aligned(sp); } -- cgit v1.2.3-70-g09d2 From 5125c6bd9e62f79b8b4fed4591c55aad3901e5b2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 25 Oct 2010 05:52:36 +0000 Subject: sparc: don't #include asm/system.h in asm/jump_label.h It seems that #include makes a circular dependency between kernel.h and bitmap.h which breaks allmodconfig build. Removing the line makes no change because jump_label.h doesn't need it actually AFAICS. Compile tested on sparc32 allmodconfig. Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- arch/sparc/include/asm/jump_label.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/include/asm/jump_label.h b/arch/sparc/include/asm/jump_label.h index 62e66d7b2fb..65c0d302979 100644 --- a/arch/sparc/include/asm/jump_label.h +++ b/arch/sparc/include/asm/jump_label.h @@ -4,7 +4,6 @@ #ifdef __KERNEL__ #include -#include #define JUMP_LABEL_NOP_SIZE 4 -- cgit v1.2.3-70-g09d2 From a3e5a375fe4f7cc599238cf607d63fc4ad018059 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 25 Oct 2010 05:52:37 +0000 Subject: sparc32: remove CONFIG_HAVE_PERF_EVENTS option Remove HAVE_PERF_EVENTS and PERF_USE_VMALLOC under config SPARC because they're under SPARC64 too. Supporting perf_event needs atomic64 operations but AFAIK sparc32 doesn't provide them, CMIIW. ;-) Also removes redundant HAVE_IRQ_WORK line. Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- arch/sparc/Kconfig | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 8e7bafc5dd0..058dbdb128b 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -28,8 +28,6 @@ config SPARC select RTC_CLASS select RTC_DRV_M48T59 select HAVE_IRQ_WORK - select HAVE_PERF_EVENTS - select PERF_USE_VMALLOC select HAVE_DMA_ATTRS select HAVE_DMA_API_DEBUG select HAVE_ARCH_JUMP_LABEL @@ -56,7 +54,6 @@ config SPARC64 select RTC_DRV_BQ4802 select RTC_DRV_SUN4V select RTC_DRV_STARFIRE - select HAVE_IRQ_WORK select HAVE_PERF_EVENTS select PERF_USE_VMALLOC -- cgit v1.2.3-70-g09d2 From 502279a7cd1e4b1d320ee2c9a25eca165232d213 Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Mon, 25 Oct 2010 21:23:46 +0000 Subject: sparc: Fixed random SPARC/LEON SMP CPU Stuck problem. Signed-off-by: Daniel Hellstrom Signed-off-by: David S. Miller --- arch/sparc/kernel/leon_smp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c index e1656fc41cc..7524689b03d 100644 --- a/arch/sparc/kernel/leon_smp.c +++ b/arch/sparc/kernel/leon_smp.c @@ -56,8 +56,8 @@ void __init leon_configure_cache_smp(void); static inline unsigned long do_swap(volatile unsigned long *ptr, unsigned long val) { - __asm__ __volatile__("swapa [%1] %2, %0\n\t" : "=&r"(val) - : "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) + __asm__ __volatile__("swapa [%2] %3, %0\n\t" : "=&r"(val) + : "0"(val), "r"(ptr), "i"(ASI_LEON_DCACHE_MISS) : "memory"); return val; } -- cgit v1.2.3-70-g09d2 From 516723215ca1f9bce154e3dcec71234ee3650343 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 25 Oct 2010 05:52:38 +0000 Subject: sparc32: fix build failure on CONFIG_SPARC_LEON CC arch/sparc/kernel/irq_32.o arch/sparc/kernel/irq_32.c: In function 'request_fast_irq': arch/sparc/kernel/irq_32.c:370:25: error: conflicting types for 'trapbase_cpu1' arch/sparc/include/asm/leon.h:366:22: note: previous declaration of 'trapbase_cpu1' was here arch/sparc/kernel/irq_32.c:370:40: error: conflicting types for 'trapbase_cpu2' arch/sparc/include/asm/leon.h:367:22: note: previous declaration of 'trapbase_cpu2' was here arch/sparc/kernel/irq_32.c:370:55: error: conflicting types for 'trapbase_cpu3' arch/sparc/include/asm/leon.h:368:22: note: previous declaration of 'trapbase_cpu3' was here make[3]: *** [arch/sparc/kernel/irq_32.o] Error 1 make[2]: *** [arch/sparc/kernel] Error 2 make[1]: *** [sub-make] Error 2 make: *** [all] Error 2 Signed-off-by: Namhyung Kim Signed-off-by: David S. Miller --- arch/sparc/kernel/irq_32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c index 0116d8d10de..5ad6e5c5dbb 100644 --- a/arch/sparc/kernel/irq_32.c +++ b/arch/sparc/kernel/irq_32.c @@ -365,7 +365,7 @@ static int request_fast_irq(unsigned int irq, unsigned long flags; unsigned int cpu_irq; int ret; -#ifdef CONFIG_SMP +#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON struct tt_entry *trap_table; extern struct tt_entry trapbase_cpu1, trapbase_cpu2, trapbase_cpu3; #endif @@ -425,7 +425,7 @@ static int request_fast_irq(unsigned int irq, table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; INSTANTIATE(sparc_ttable) -#ifdef CONFIG_SMP +#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON trap_table = &trapbase_cpu1; INSTANTIATE(trap_table) trap_table = &trapbase_cpu2; INSTANTIATE(trap_table) trap_table = &trapbase_cpu3; INSTANTIATE(trap_table) -- cgit v1.2.3-70-g09d2