From 176b1803ce4690d0dd94e16f118dbd14af045034 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 9 Apr 2010 13:43:00 +0200 Subject: [PATCH] [S390] fix io_return critical section cleanup If a machine check interrupts the io interrupt handler on one of the instructions between io_return and io_leave the critical section cleanup code will move the return psw to io_work_loop. By doing that the switch from the asynchronous interrupt stack to the process stack is skipped. If e.g. TIF_NEED_RESCHED is set things break because the scheduler is called with the asynchronous interrupts stack. Moving the psw back to io_return instead fixes the problem. Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/entry.S | 8 +++++++- arch/s390/kernel/entry64.S | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 4348f9bc5393..6af7045280a8 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -964,7 +964,7 @@ cleanup_critical: clc 4(4,%r12),BASED(cleanup_table_io_work_loop) bl BASED(0f) clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) - bl BASED(cleanup_io_return) + bl BASED(cleanup_io_work_loop) 0: br %r14 @@ -1038,6 +1038,12 @@ cleanup_sysc_leave_insn: .long sysc_done - 8 + 0x80000000 cleanup_io_return: + mvc __LC_RETURN_PSW(4),0(%r12) + mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return) + la %r12,__LC_RETURN_PSW + br %r14 + +cleanup_io_work_loop: mvc __LC_RETURN_PSW(4),0(%r12) mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) la %r12,__LC_RETURN_PSW diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 29fd0f1e6ec4..52106d53271c 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -946,7 +946,7 @@ cleanup_critical: clc 8(8,%r12),BASED(cleanup_table_io_work_loop) jl 0f clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) - jl cleanup_io_return + jl cleanup_io_work_loop 0: br %r14 @@ -1020,6 +1020,12 @@ cleanup_sysc_leave_insn: .quad sysc_done - 16 cleanup_io_return: + mvc __LC_RETURN_PSW(8),0(%r12) + mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return) + la %r12,__LC_RETURN_PSW + br %r14 + +cleanup_io_work_loop: mvc __LC_RETURN_PSW(8),0(%r12) mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) la %r12,__LC_RETURN_PSW