[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>
This commit is contained in:
Родитель
37e3a6ac5a
Коммит
b8e7a54cd0
|
@ -640,15 +640,9 @@ io_preempt:
|
||||||
io_resume_loop:
|
io_resume_loop:
|
||||||
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
|
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
|
||||||
bno BASED(io_restore)
|
bno BASED(io_restore)
|
||||||
mvc __TI_precount(4,%r9),BASED(.Lc_pactive)
|
l %r1,BASED(.Lpreempt_schedule_irq)
|
||||||
TRACE_IRQS_ON
|
la %r14,BASED(io_resume_loop)
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
br %r1 # call schedule
|
||||||
l %r1,BASED(.Lschedule)
|
|
||||||
basr %r14,%r1 # call schedule
|
|
||||||
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
xc __TI_precount(4,%r9),__TI_precount(%r9)
|
|
||||||
b BASED(io_resume_loop)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1062,7 +1056,6 @@ cleanup_io_leave_insn:
|
||||||
.align 4
|
.align 4
|
||||||
.Lc_spsize: .long SP_SIZE
|
.Lc_spsize: .long SP_SIZE
|
||||||
.Lc_overhead: .long STACK_FRAME_OVERHEAD
|
.Lc_overhead: .long STACK_FRAME_OVERHEAD
|
||||||
.Lc_pactive: .long PREEMPT_ACTIVE
|
|
||||||
.Lnr_syscalls: .long NR_syscalls
|
.Lnr_syscalls: .long NR_syscalls
|
||||||
.L0x018: .short 0x018
|
.L0x018: .short 0x018
|
||||||
.L0x020: .short 0x020
|
.L0x020: .short 0x020
|
||||||
|
@ -1086,6 +1079,8 @@ cleanup_io_leave_insn:
|
||||||
.Lexecve_tail: .long execve_tail
|
.Lexecve_tail: .long execve_tail
|
||||||
.Ljump_table: .long pgm_check_table
|
.Ljump_table: .long pgm_check_table
|
||||||
.Lschedule: .long schedule
|
.Lschedule: .long schedule
|
||||||
|
.Lpreempt_schedule_irq:
|
||||||
|
.long preempt_schedule_irq
|
||||||
.Ltrace: .long syscall_trace
|
.Ltrace: .long syscall_trace
|
||||||
.Lschedtail: .long schedule_tail
|
.Lschedtail: .long schedule_tail
|
||||||
.Lsysc_table: .long sys_call_table
|
.Lsysc_table: .long sys_call_table
|
||||||
|
|
|
@ -623,15 +623,8 @@ io_preempt:
|
||||||
io_resume_loop:
|
io_resume_loop:
|
||||||
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
|
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
|
||||||
jno io_restore
|
jno io_restore
|
||||||
larl %r1,.Lc_pactive
|
larl %r14,io_resume_loop
|
||||||
mvc __TI_precount(4,%r9),0(%r1)
|
jg preempt_schedule_irq
|
||||||
TRACE_IRQS_ON
|
|
||||||
stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
|
|
||||||
brasl %r14,schedule # call schedule
|
|
||||||
stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
|
|
||||||
TRACE_IRQS_OFF
|
|
||||||
xc __TI_precount(4,%r9),__TI_precount(%r9)
|
|
||||||
j io_resume_loop
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1029,7 +1022,6 @@ cleanup_io_leave_insn:
|
||||||
*/
|
*/
|
||||||
.align 4
|
.align 4
|
||||||
.Lconst:
|
.Lconst:
|
||||||
.Lc_pactive: .long PREEMPT_ACTIVE
|
|
||||||
.Lnr_syscalls: .long NR_syscalls
|
.Lnr_syscalls: .long NR_syscalls
|
||||||
.L0x0130: .short 0x130
|
.L0x0130: .short 0x130
|
||||||
.L0x0140: .short 0x140
|
.L0x0140: .short 0x140
|
||||||
|
|
Загрузка…
Ссылка в новой задаче