diff options
| author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-04-09 07:43:00 -0400 |
|---|---|---|
| committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-04-09 07:43:02 -0400 |
| commit | 176b1803ce4690d0dd94e16f118dbd14af045034 (patch) | |
| tree | 92601341680bf89e42ed0073bd5086d16405356c | |
| parent | 35ac734f72d846f250c0344913a91f954ea764c3 (diff) | |
[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 <schwidefsky@de.ibm.com>
| -rw-r--r-- | arch/s390/kernel/entry.S | 8 | ||||
| -rw-r--r-- | 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: | |||
| 964 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop) | 964 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop) |
| 965 | bl BASED(0f) | 965 | bl BASED(0f) |
| 966 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) | 966 | clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4) |
| 967 | bl BASED(cleanup_io_return) | 967 | bl BASED(cleanup_io_work_loop) |
| 968 | 0: | 968 | 0: |
| 969 | br %r14 | 969 | br %r14 |
| 970 | 970 | ||
| @@ -1039,6 +1039,12 @@ cleanup_sysc_leave_insn: | |||
| 1039 | 1039 | ||
| 1040 | cleanup_io_return: | 1040 | cleanup_io_return: |
| 1041 | mvc __LC_RETURN_PSW(4),0(%r12) | 1041 | mvc __LC_RETURN_PSW(4),0(%r12) |
| 1042 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_return) | ||
| 1043 | la %r12,__LC_RETURN_PSW | ||
| 1044 | br %r14 | ||
| 1045 | |||
| 1046 | cleanup_io_work_loop: | ||
| 1047 | mvc __LC_RETURN_PSW(4),0(%r12) | ||
| 1042 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) | 1048 | mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) |
| 1043 | la %r12,__LC_RETURN_PSW | 1049 | la %r12,__LC_RETURN_PSW |
| 1044 | br %r14 | 1050 | br %r14 |
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: | |||
| 946 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop) | 946 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop) |
| 947 | jl 0f | 947 | jl 0f |
| 948 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) | 948 | clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) |
| 949 | jl cleanup_io_return | 949 | jl cleanup_io_work_loop |
| 950 | 0: | 950 | 0: |
| 951 | br %r14 | 951 | br %r14 |
| 952 | 952 | ||
| @@ -1021,6 +1021,12 @@ cleanup_sysc_leave_insn: | |||
| 1021 | 1021 | ||
| 1022 | cleanup_io_return: | 1022 | cleanup_io_return: |
| 1023 | mvc __LC_RETURN_PSW(8),0(%r12) | 1023 | mvc __LC_RETURN_PSW(8),0(%r12) |
| 1024 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_return) | ||
| 1025 | la %r12,__LC_RETURN_PSW | ||
| 1026 | br %r14 | ||
| 1027 | |||
| 1028 | cleanup_io_work_loop: | ||
| 1029 | mvc __LC_RETURN_PSW(8),0(%r12) | ||
| 1024 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) | 1030 | mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) |
| 1025 | la %r12,__LC_RETURN_PSW | 1031 | la %r12,__LC_RETURN_PSW |
| 1026 | br %r14 | 1032 | br %r14 |
