[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>

authored by Martin Schwidefsky and committed by Martin Schwidefsky 176b1803 35ac734f

+14 -2
+7 -1
arch/s390/kernel/entry.S
··· 964 964 clc 4(4,%r12),BASED(cleanup_table_io_work_loop) 965 965 bl BASED(0f) 966 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 968 0: 969 969 br %r14 970 970 ··· 1038 1038 .long sysc_done - 8 + 0x80000000 1039 1039 1040 1040 cleanup_io_return: 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: 1041 1047 mvc __LC_RETURN_PSW(4),0(%r12) 1042 1048 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop) 1043 1049 la %r12,__LC_RETURN_PSW
+7 -1
arch/s390/kernel/entry64.S
··· 946 946 clc 8(8,%r12),BASED(cleanup_table_io_work_loop) 947 947 jl 0f 948 948 clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8) 949 - jl cleanup_io_return 949 + jl cleanup_io_work_loop 950 950 0: 951 951 br %r14 952 952 ··· 1020 1020 .quad sysc_done - 16 1021 1021 1022 1022 cleanup_io_return: 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: 1023 1029 mvc __LC_RETURN_PSW(8),0(%r12) 1024 1030 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop) 1025 1031 la %r12,__LC_RETURN_PSW