aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn David Anglin <dave.anglin@bell.net>2013-05-06 20:07:25 -0400
committerHelge Deller <deller@gmx.de>2013-05-07 14:33:03 -0400
commitc207a76bf155cb5cf24cf849c08f6555e9180594 (patch)
treef9f05b4d721dd215e28318337617beada3c238dd
parentf21dda025ab00da197ac30b6c6690c380d838683 (diff)
parisc: only re-enable interrupts if we need to schedule or deliver signals when returning to userspace
Helge and I have found that we have a kernel stack overflow problem which causes a variety of random failures. Currently, we re-enable interrupts when returning from an external interrupt incase we need to schedule or delivery signals. As a result, a potentially unlimited number of interrupts can occur while we are running on the kernel stack. It is very limited in space (currently, 16k). This change defers enabling interrupts until we have actually decided to schedule or delivery signals. This only occurs when we about to return to userspace. This limits the number of interrupts on the kernel stack to one. In other cases, interrupts remain disabled until the final return from interrupt (rfi). Signed-off-by: John David Anglin <dave.anglin@bell.net> Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--arch/parisc/kernel/entry.S14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 36f4f1dcb778..3f3326d876f7 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -833,11 +833,6 @@ ENTRY(syscall_exit_rfi)
833 STREG %r19,PT_SR7(%r16) 833 STREG %r19,PT_SR7(%r16)
834 834
835intr_return: 835intr_return:
836 /* NOTE: Need to enable interrupts incase we schedule. */
837 ssm PSW_SM_I, %r0
838
839intr_check_resched:
840
841 /* check for reschedule */ 836 /* check for reschedule */
842 mfctl %cr30,%r1 837 mfctl %cr30,%r1
843 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ 838 LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
@@ -864,6 +859,11 @@ intr_check_sig:
864 LDREG PT_IASQ1(%r16), %r20 859 LDREG PT_IASQ1(%r16), %r20
865 cmpib,COND(=),n 0,%r20,intr_restore /* backward */ 860 cmpib,COND(=),n 0,%r20,intr_restore /* backward */
866 861
862 /* NOTE: We need to enable interrupts if we have to deliver
863 * signals. We used to do this earlier but it caused kernel
864 * stack overflows. */
865 ssm PSW_SM_I, %r0
866
867 copy %r0, %r25 /* long in_syscall = 0 */ 867 copy %r0, %r25 /* long in_syscall = 0 */
868#ifdef CONFIG_64BIT 868#ifdef CONFIG_64BIT
869 ldo -16(%r30),%r29 /* Reference param save area */ 869 ldo -16(%r30),%r29 /* Reference param save area */
@@ -915,6 +915,10 @@ intr_do_resched:
915 cmpib,COND(=) 0, %r20, intr_do_preempt 915 cmpib,COND(=) 0, %r20, intr_do_preempt
916 nop 916 nop
917 917
918 /* NOTE: We need to enable interrupts if we schedule. We used
919 * to do this earlier but it caused kernel stack overflows. */
920 ssm PSW_SM_I, %r0
921
918#ifdef CONFIG_64BIT 922#ifdef CONFIG_64BIT
919 ldo -16(%r30),%r29 /* Reference param save area */ 923 ldo -16(%r30),%r29 /* Reference param save area */
920#endif 924#endif