aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry64.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry64.S')
-rw-r--r--arch/s390/kernel/entry64.S117
1 files changed, 88 insertions, 29 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index d9f22915008c..fb77b72ab262 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -131,14 +131,14 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
131 stg %r12,__SF_BACKCHAIN(%r15) 131 stg %r12,__SF_BACKCHAIN(%r15)
132 .endm 132 .endm
133 133
134 .macro RESTORE_ALL sync 134 .macro RESTORE_ALL psworg,sync
135 mvc __LC_RETURN_PSW(16),SP_PSW(%r15) # move user PSW to lowcore 135 mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore
136 .if !\sync 136 .if !\sync
137 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit 137 ni \psworg+1,0xfd # clear wait state bit
138 .endif 138 .endif
139 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user 139 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
140 STORE_TIMER __LC_EXIT_TIMER 140 STORE_TIMER __LC_EXIT_TIMER
141 lpswe __LC_RETURN_PSW # back to caller 141 lpswe \psworg # back to caller
142 .endm 142 .endm
143 143
144/* 144/*
@@ -214,8 +214,8 @@ sysc_nr_ok:
214sysc_do_restart: 214sysc_do_restart:
215 larl %r10,sys_call_table 215 larl %r10,sys_call_table
216#ifdef CONFIG_S390_SUPPORT 216#ifdef CONFIG_S390_SUPPORT
217 tm SP_PSW+3(%r15),0x01 # are we running in 31 bit mode ? 217 tm __TI_flags+5(%r9),(_TIF_31BIT>>16) # running in 31 bit mode ?
218 jo sysc_noemu 218 jno sysc_noemu
219 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 219 larl %r10,sys_call_table_emu # use 31 bit emulation system calls
220sysc_noemu: 220sysc_noemu:
221#endif 221#endif
@@ -233,7 +233,7 @@ sysc_return:
233 tm __TI_flags+7(%r9),_TIF_WORK_SVC 233 tm __TI_flags+7(%r9),_TIF_WORK_SVC
234 jnz sysc_work # there is work to do (signals etc.) 234 jnz sysc_work # there is work to do (signals etc.)
235sysc_leave: 235sysc_leave:
236 RESTORE_ALL 1 236 RESTORE_ALL __LC_RETURN_PSW,1
237 237
238# 238#
239# recheck if there is more work to do 239# recheck if there is more work to do
@@ -308,8 +308,6 @@ sysc_singlestep:
308 jg do_single_step # branch to do_sigtrap 308 jg do_single_step # branch to do_sigtrap
309 309
310 310
311__critical_end:
312
313# 311#
314# call syscall_trace before and after system call 312# call syscall_trace before and after system call
315# special linkage: %r12 contains the return address for trace_svc 313# special linkage: %r12 contains the return address for trace_svc
@@ -612,7 +610,8 @@ io_return:
612 tm __TI_flags+7(%r9),_TIF_WORK_INT 610 tm __TI_flags+7(%r9),_TIF_WORK_INT
613 jnz io_work # there is work to do (signals etc.) 611 jnz io_work # there is work to do (signals etc.)
614io_leave: 612io_leave:
615 RESTORE_ALL 0 613 RESTORE_ALL __LC_RETURN_PSW,0
614io_done:
616 615
617#ifdef CONFIG_PREEMPT 616#ifdef CONFIG_PREEMPT
618io_preempt: 617io_preempt:
@@ -711,6 +710,8 @@ ext_no_vtime:
711 brasl %r14,do_extint 710 brasl %r14,do_extint
712 j io_return 711 j io_return
713 712
713__critical_end:
714
714/* 715/*
715 * Machine check handler routines 716 * Machine check handler routines
716 */ 717 */
@@ -718,6 +719,7 @@ ext_no_vtime:
718mcck_int_handler: 719mcck_int_handler:
719 la %r1,4095 # revalidate r1 720 la %r1,4095 # revalidate r1
720 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 721 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
722 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1)
721 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 723 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
722 SAVE_ALL_BASE __LC_SAVE_AREA+64 724 SAVE_ALL_BASE __LC_SAVE_AREA+64
723 la %r12,__LC_MCK_OLD_PSW 725 la %r12,__LC_MCK_OLD_PSW
@@ -730,17 +732,8 @@ mcck_int_handler:
730 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 732 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
731 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 733 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
732 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 734 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
7330: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
734 jno mcck_no_vtime # no -> no timer update
735 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
736 jz mcck_no_vtime
737 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
738 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
739 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
740mcck_no_vtime:
741#endif 735#endif
7420: 7360: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
743 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
744 jno mcck_int_main # no -> skip cleanup critical 737 jno mcck_int_main # no -> skip cleanup critical
745 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 738 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
746 jnz mcck_int_main # from user -> load kernel stack 739 jnz mcck_int_main # from user -> load kernel stack
@@ -756,6 +749,16 @@ mcck_int_main:
756 jz 0f 749 jz 0f
757 lg %r15,__LC_PANIC_STACK # load panic stack 750 lg %r15,__LC_PANIC_STACK # load panic stack
7580: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64 7510: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64
752#ifdef CONFIG_VIRT_CPU_ACCOUNTING
753 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
754 jno mcck_no_vtime # no -> no timer update
755 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
756 jz mcck_no_vtime
757 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
758 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
759 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
760mcck_no_vtime:
761#endif
759 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 762 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
760 la %r2,SP_PTREGS(%r15) # load pt_regs 763 la %r2,SP_PTREGS(%r15) # load pt_regs
761 brasl %r14,s390_do_machine_check 764 brasl %r14,s390_do_machine_check
@@ -771,7 +774,7 @@ mcck_int_main:
771 jno mcck_return 774 jno mcck_return
772 brasl %r14,s390_handle_mcck 775 brasl %r14,s390_handle_mcck
773mcck_return: 776mcck_return:
774 RESTORE_ALL 0 777 RESTORE_ALL __LC_RETURN_MCCK_PSW,0
775 778
776#ifdef CONFIG_SMP 779#ifdef CONFIG_SMP
777/* 780/*
@@ -833,6 +836,10 @@ cleanup_table_sysc_leave:
833 .quad sysc_leave, sysc_work_loop 836 .quad sysc_leave, sysc_work_loop
834cleanup_table_sysc_work_loop: 837cleanup_table_sysc_work_loop:
835 .quad sysc_work_loop, sysc_reschedule 838 .quad sysc_work_loop, sysc_reschedule
839cleanup_table_io_leave:
840 .quad io_leave, io_done
841cleanup_table_io_work_loop:
842 .quad io_work_loop, io_mcck_pending
836 843
837cleanup_critical: 844cleanup_critical:
838 clc 8(8,%r12),BASED(cleanup_table_system_call) 845 clc 8(8,%r12),BASED(cleanup_table_system_call)
@@ -855,10 +862,26 @@ cleanup_critical:
855 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) 862 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
856 jl cleanup_sysc_return 863 jl cleanup_sysc_return
8570: 8640:
865 clc 8(8,%r12),BASED(cleanup_table_io_leave)
866 jl 0f
867 clc 8(8,%r12),BASED(cleanup_table_io_leave+8)
868 jl cleanup_io_leave
8690:
870 clc 8(8,%r12),BASED(cleanup_table_io_work_loop)
871 jl 0f
872 clc 8(8,%r12),BASED(cleanup_table_io_work_loop+8)
873 jl cleanup_io_return
8740:
858 br %r14 875 br %r14
859 876
860cleanup_system_call: 877cleanup_system_call:
861 mvc __LC_RETURN_PSW(16),0(%r12) 878 mvc __LC_RETURN_PSW(16),0(%r12)
879 cghi %r12,__LC_MCK_OLD_PSW
880 je 0f
881 la %r12,__LC_SAVE_AREA+32
882 j 1f
8830: la %r12,__LC_SAVE_AREA+64
8841:
862#ifdef CONFIG_VIRT_CPU_ACCOUNTING 885#ifdef CONFIG_VIRT_CPU_ACCOUNTING
863 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) 886 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8)
864 jh 0f 887 jh 0f
@@ -868,11 +891,13 @@ cleanup_system_call:
868#endif 891#endif
869 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn) 892 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
870 jh 0f 893 jh 0f
871 mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32 894 mvc __LC_SAVE_AREA(32),0(%r12)
8720: stg %r13,__LC_SAVE_AREA+40 8950: stg %r13,8(%r12)
896 stg %r12,__LC_SAVE_AREA+96 # argh
873 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 897 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
874 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 898 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
875 stg %r15,__LC_SAVE_AREA+56 899 lg %r12,__LC_SAVE_AREA+96 # argh
900 stg %r15,24(%r12)
876 llgh %r7,__LC_SVC_INT_CODE 901 llgh %r7,__LC_SVC_INT_CODE
877#ifdef CONFIG_VIRT_CPU_ACCOUNTING 902#ifdef CONFIG_VIRT_CPU_ACCOUNTING
878cleanup_vtime: 903cleanup_vtime:
@@ -909,17 +934,21 @@ cleanup_sysc_return:
909 934
910cleanup_sysc_leave: 935cleanup_sysc_leave:
911 clc 8(8,%r12),BASED(cleanup_sysc_leave_insn) 936 clc 8(8,%r12),BASED(cleanup_sysc_leave_insn)
912 je 0f 937 je 2f
913#ifdef CONFIG_VIRT_CPU_ACCOUNTING 938#ifdef CONFIG_VIRT_CPU_ACCOUNTING
914 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 939 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
915 clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8) 940 clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8)
916 je 0f 941 je 2f
917#endif 942#endif
918 mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 943 mvc __LC_RETURN_PSW(16),SP_PSW(%r15)
919 mvc __LC_SAVE_AREA+32(32),SP_R12(%r15) 944 cghi %r12,__LC_MCK_OLD_PSW
920 lmg %r0,%r11,SP_R0(%r15) 945 jne 0f
946 mvc __LC_SAVE_AREA+64(32),SP_R12(%r15)
947 j 1f
9480: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15)
9491: lmg %r0,%r11,SP_R0(%r15)
921 lg %r15,SP_R15(%r15) 950 lg %r15,SP_R15(%r15)
9220: la %r12,__LC_RETURN_PSW 9512: la %r12,__LC_RETURN_PSW
923 br %r14 952 br %r14
924cleanup_sysc_leave_insn: 953cleanup_sysc_leave_insn:
925#ifdef CONFIG_VIRT_CPU_ACCOUNTING 954#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -927,6 +956,36 @@ cleanup_sysc_leave_insn:
927#endif 956#endif
928 .quad sysc_leave + 12 957 .quad sysc_leave + 12
929 958
959cleanup_io_return:
960 mvc __LC_RETURN_PSW(8),0(%r12)
961 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_work_loop)
962 la %r12,__LC_RETURN_PSW
963 br %r14
964
965cleanup_io_leave:
966 clc 8(8,%r12),BASED(cleanup_io_leave_insn)
967 je 2f
968#ifdef CONFIG_VIRT_CPU_ACCOUNTING
969 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
970 clc 8(8,%r12),BASED(cleanup_io_leave_insn+8)
971 je 2f
972#endif
973 mvc __LC_RETURN_PSW(16),SP_PSW(%r15)
974 cghi %r12,__LC_MCK_OLD_PSW
975 jne 0f
976 mvc __LC_SAVE_AREA+64(32),SP_R12(%r15)
977 j 1f
9780: mvc __LC_SAVE_AREA+32(32),SP_R12(%r15)
9791: lmg %r0,%r11,SP_R0(%r15)
980 lg %r15,SP_R15(%r15)
9812: la %r12,__LC_RETURN_PSW
982 br %r14
983cleanup_io_leave_insn:
984#ifdef CONFIG_VIRT_CPU_ACCOUNTING
985 .quad io_leave + 20
986#endif
987 .quad io_leave + 16
988
930/* 989/*
931 * Integer constants 990 * Integer constants
932 */ 991 */