diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2007-11-20 05:13:35 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2007-11-20 05:13:46 -0500 |
commit | b8e7a54cd06b0b0174029ef3a7f5a1415a2c28f2 (patch) | |
tree | e42beedde089c3aabe9df1537ad687f2756a69ac /arch/s390/kernel/entry.S | |
parent | 37e3a6ac5a30468021a2f366e497d455bbcb5d21 (diff) |
[S390] Fix kernel preemption.
When returning from IRQ handling and TIF_NEED_RESCHED is set we must
call preempt_schedule_irq() instead of schedule().
Otherwise the BKL might be unlocked in schedule() and therfore
everything that relies on the BKL is broken.
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 15 |
1 files changed, 5 insertions, 10 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 764d56177cb5..b2b2edc40eb1 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -640,15 +640,9 @@ io_preempt: | |||
640 | io_resume_loop: | 640 | io_resume_loop: |
641 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED | 641 | tm __TI_flags+3(%r9),_TIF_NEED_RESCHED |
642 | bno BASED(io_restore) | 642 | bno BASED(io_restore) |
643 | mvc __TI_precount(4,%r9),BASED(.Lc_pactive) | 643 | l %r1,BASED(.Lpreempt_schedule_irq) |
644 | TRACE_IRQS_ON | 644 | la %r14,BASED(io_resume_loop) |
645 | stosm __SF_EMPTY(%r15),0x03 # reenable interrupts | 645 | br %r1 # call schedule |
646 | l %r1,BASED(.Lschedule) | ||
647 | basr %r14,%r1 # call schedule | ||
648 | stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts | ||
649 | TRACE_IRQS_OFF | ||
650 | xc __TI_precount(4,%r9),__TI_precount(%r9) | ||
651 | b BASED(io_resume_loop) | ||
652 | #endif | 646 | #endif |
653 | 647 | ||
654 | # | 648 | # |
@@ -1062,7 +1056,6 @@ cleanup_io_leave_insn: | |||
1062 | .align 4 | 1056 | .align 4 |
1063 | .Lc_spsize: .long SP_SIZE | 1057 | .Lc_spsize: .long SP_SIZE |
1064 | .Lc_overhead: .long STACK_FRAME_OVERHEAD | 1058 | .Lc_overhead: .long STACK_FRAME_OVERHEAD |
1065 | .Lc_pactive: .long PREEMPT_ACTIVE | ||
1066 | .Lnr_syscalls: .long NR_syscalls | 1059 | .Lnr_syscalls: .long NR_syscalls |
1067 | .L0x018: .short 0x018 | 1060 | .L0x018: .short 0x018 |
1068 | .L0x020: .short 0x020 | 1061 | .L0x020: .short 0x020 |
@@ -1086,6 +1079,8 @@ cleanup_io_leave_insn: | |||
1086 | .Lexecve_tail: .long execve_tail | 1079 | .Lexecve_tail: .long execve_tail |
1087 | .Ljump_table: .long pgm_check_table | 1080 | .Ljump_table: .long pgm_check_table |
1088 | .Lschedule: .long schedule | 1081 | .Lschedule: .long schedule |
1082 | .Lpreempt_schedule_irq: | ||
1083 | .long preempt_schedule_irq | ||
1089 | .Ltrace: .long syscall_trace | 1084 | .Ltrace: .long syscall_trace |
1090 | .Lschedtail: .long schedule_tail | 1085 | .Lschedtail: .long schedule_tail |
1091 | .Lsysc_table: .long sys_call_table | 1086 | .Lsysc_table: .long sys_call_table |