aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kernel/entry.S116
-rw-r--r--arch/s390/kernel/entry64.S113
-rw-r--r--drivers/s390/s390mach.c2
-rw-r--r--include/asm-s390/lowcore.h8
4 files changed, 181 insertions, 58 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 1a271b16cb5c..cbe7d6a2d02c 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -138,14 +138,14 @@ STACK_SIZE = 1 << STACK_SHIFT
138 st %r12,__SF_BACKCHAIN(%r15) # clear back chain 138 st %r12,__SF_BACKCHAIN(%r15) # clear back chain
139 .endm 139 .endm
140 140
141 .macro RESTORE_ALL sync 141 .macro RESTORE_ALL psworg,sync
142 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) # move user PSW to lowcore 142 mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore
143 .if !\sync 143 .if !\sync
144 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit 144 ni \psworg+1,0xfd # clear wait state bit
145 .endif 145 .endif
146 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user 146 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
147 STORE_TIMER __LC_EXIT_TIMER 147 STORE_TIMER __LC_EXIT_TIMER
148 lpsw __LC_RETURN_PSW # back to caller 148 lpsw \psworg # back to caller
149 .endm 149 .endm
150 150
151/* 151/*
@@ -235,7 +235,7 @@ sysc_return:
235 tm __TI_flags+3(%r9),_TIF_WORK_SVC 235 tm __TI_flags+3(%r9),_TIF_WORK_SVC
236 bnz BASED(sysc_work) # there is work to do (signals etc.) 236 bnz BASED(sysc_work) # there is work to do (signals etc.)
237sysc_leave: 237sysc_leave:
238 RESTORE_ALL 1 238 RESTORE_ALL __LC_RETURN_PSW,1
239 239
240# 240#
241# recheck if there is more work to do 241# recheck if there is more work to do
@@ -312,8 +312,6 @@ sysc_singlestep:
312 la %r14,BASED(sysc_return) # load adr. of system return 312 la %r14,BASED(sysc_return) # load adr. of system return
313 br %r1 # branch to do_single_step 313 br %r1 # branch to do_single_step
314 314
315__critical_end:
316
317# 315#
318# call trace before and after sys_call 316# call trace before and after sys_call
319# 317#
@@ -571,7 +569,8 @@ io_return:
571 tm __TI_flags+3(%r9),_TIF_WORK_INT 569 tm __TI_flags+3(%r9),_TIF_WORK_INT
572 bnz BASED(io_work) # there is work to do (signals etc.) 570 bnz BASED(io_work) # there is work to do (signals etc.)
573io_leave: 571io_leave:
574 RESTORE_ALL 0 572 RESTORE_ALL __LC_RETURN_PSW,0
573io_done:
575 574
576#ifdef CONFIG_PREEMPT 575#ifdef CONFIG_PREEMPT
577io_preempt: 576io_preempt:
@@ -621,7 +620,7 @@ io_work_loop:
621# 620#
622io_mcck_pending: 621io_mcck_pending:
623 l %r1,BASED(.Ls390_handle_mcck) 622 l %r1,BASED(.Ls390_handle_mcck)
624 l %r14,BASED(io_work_loop) 623 la %r14,BASED(io_work_loop)
625 br %r1 # TIF bit will be cleared by handler 624 br %r1 # TIF bit will be cleared by handler
626 625
627# 626#
@@ -674,6 +673,8 @@ ext_no_vtime:
674 basr %r14,%r1 673 basr %r14,%r1
675 b BASED(io_return) 674 b BASED(io_return)
676 675
676__critical_end:
677
677/* 678/*
678 * Machine check handler routines 679 * Machine check handler routines
679 */ 680 */
@@ -681,6 +682,7 @@ ext_no_vtime:
681 .globl mcck_int_handler 682 .globl mcck_int_handler
682mcck_int_handler: 683mcck_int_handler:
683 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 684 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
685 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA
684 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 686 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
685 SAVE_ALL_BASE __LC_SAVE_AREA+32 687 SAVE_ALL_BASE __LC_SAVE_AREA+32
686 la %r12,__LC_MCK_OLD_PSW 688 la %r12,__LC_MCK_OLD_PSW
@@ -693,17 +695,8 @@ mcck_int_handler:
693 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 695 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
694 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 696 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER
695 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 697 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER
6960: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
697 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
698 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
699 bz BASED(mcck_no_vtime)
700 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
701 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
702 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
703mcck_no_vtime:
704#endif 698#endif
7050: 6990: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
706 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
707 bno BASED(mcck_int_main) # no -> skip cleanup critical 700 bno BASED(mcck_int_main) # no -> skip cleanup critical
708 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 701 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
709 bnz BASED(mcck_int_main) # from user -> load async stack 702 bnz BASED(mcck_int_main) # from user -> load async stack
@@ -720,6 +713,16 @@ mcck_int_main:
720 be BASED(0f) 713 be BASED(0f)
721 l %r15,__LC_PANIC_STACK # load panic stack 714 l %r15,__LC_PANIC_STACK # load panic stack
7220: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 7150: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
716#ifdef CONFIG_VIRT_CPU_ACCOUNTING
717 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
718 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
719 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
720 bz BASED(mcck_no_vtime)
721 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
722 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
723 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
724mcck_no_vtime:
725#endif
723 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 726 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
724 la %r2,SP_PTREGS(%r15) # load pt_regs 727 la %r2,SP_PTREGS(%r15) # load pt_regs
725 l %r1,BASED(.Ls390_mcck) 728 l %r1,BASED(.Ls390_mcck)
@@ -737,7 +740,7 @@ mcck_int_main:
737 l %r1,BASED(.Ls390_handle_mcck) 740 l %r1,BASED(.Ls390_handle_mcck)
738 basr %r14,%r1 # call machine check handler 741 basr %r14,%r1 # call machine check handler
739mcck_return: 742mcck_return:
740 RESTORE_ALL 0 743 RESTORE_ALL __LC_RETURN_MCCK_PSW,0
741 744
742#ifdef CONFIG_SMP 745#ifdef CONFIG_SMP
743/* 746/*
@@ -803,6 +806,10 @@ cleanup_table_sysc_leave:
803 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 806 .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000
804cleanup_table_sysc_work_loop: 807cleanup_table_sysc_work_loop:
805 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 808 .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000
809cleanup_table_io_leave:
810 .long io_leave + 0x80000000, io_done + 0x80000000
811cleanup_table_io_work_loop:
812 .long io_work_loop + 0x80000000, io_mcck_pending + 0x80000000
806 813
807cleanup_critical: 814cleanup_critical:
808 clc 4(4,%r12),BASED(cleanup_table_system_call) 815 clc 4(4,%r12),BASED(cleanup_table_system_call)
@@ -825,10 +832,26 @@ cleanup_critical:
825 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) 832 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
826 bl BASED(cleanup_sysc_return) 833 bl BASED(cleanup_sysc_return)
8270: 8340:
835 clc 4(4,%r12),BASED(cleanup_table_io_leave)
836 bl BASED(0f)
837 clc 4(4,%r12),BASED(cleanup_table_io_leave+4)
838 bl BASED(cleanup_io_leave)
8390:
840 clc 4(4,%r12),BASED(cleanup_table_io_work_loop)
841 bl BASED(0f)
842 clc 4(4,%r12),BASED(cleanup_table_io_work_loop+4)
843 bl BASED(cleanup_io_return)
8440:
828 br %r14 845 br %r14
829 846
830cleanup_system_call: 847cleanup_system_call:
831 mvc __LC_RETURN_PSW(8),0(%r12) 848 mvc __LC_RETURN_PSW(8),0(%r12)
849 c %r12,BASED(.Lmck_old_psw)
850 be BASED(0f)
851 la %r12,__LC_SAVE_AREA+16
852 b BASED(1f)
8530: la %r12,__LC_SAVE_AREA+32
8541:
832#ifdef CONFIG_VIRT_CPU_ACCOUNTING 855#ifdef CONFIG_VIRT_CPU_ACCOUNTING
833 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) 856 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4)
834 bh BASED(0f) 857 bh BASED(0f)
@@ -838,11 +861,13 @@ cleanup_system_call:
838#endif 861#endif
839 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) 862 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn)
840 bh BASED(0f) 863 bh BASED(0f)
841 mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16 864 mvc __LC_SAVE_AREA(16),0(%r12)
8420: st %r13,__LC_SAVE_AREA+20 8650: st %r13,4(%r12)
866 st %r12,__LC_SAVE_AREA+48 # argh
843 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 867 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
844 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 868 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
845 st %r15,__LC_SAVE_AREA+28 869 l %r12,__LC_SAVE_AREA+48 # argh
870 st %r15,12(%r12)
846 lh %r7,0x8a 871 lh %r7,0x8a
847#ifdef CONFIG_VIRT_CPU_ACCOUNTING 872#ifdef CONFIG_VIRT_CPU_ACCOUNTING
848cleanup_vtime: 873cleanup_vtime:
@@ -879,17 +904,21 @@ cleanup_sysc_return:
879 904
880cleanup_sysc_leave: 905cleanup_sysc_leave:
881 clc 4(4,%r12),BASED(cleanup_sysc_leave_insn) 906 clc 4(4,%r12),BASED(cleanup_sysc_leave_insn)
882 be BASED(0f) 907 be BASED(2f)
883#ifdef CONFIG_VIRT_CPU_ACCOUNTING 908#ifdef CONFIG_VIRT_CPU_ACCOUNTING
884 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 909 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
885 clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4) 910 clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
886 be BASED(0f) 911 be BASED(2f)
887#endif 912#endif
888 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 913 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
889 mvc __LC_SAVE_AREA+16(16),SP_R12(%r15) 914 c %r12,BASED(.Lmck_old_psw)
890 lm %r0,%r11,SP_R0(%r15) 915 bne BASED(0f)
916 mvc __LC_SAVE_AREA+32(16),SP_R12(%r15)
917 b BASED(1f)
9180: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15)
9191: lm %r0,%r11,SP_R0(%r15)
891 l %r15,SP_R15(%r15) 920 l %r15,SP_R15(%r15)
8920: la %r12,__LC_RETURN_PSW 9212: la %r12,__LC_RETURN_PSW
893 br %r14 922 br %r14
894cleanup_sysc_leave_insn: 923cleanup_sysc_leave_insn:
895#ifdef CONFIG_VIRT_CPU_ACCOUNTING 924#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -897,6 +926,36 @@ cleanup_sysc_leave_insn:
897#endif 926#endif
898 .long sysc_leave + 10 + 0x80000000 927 .long sysc_leave + 10 + 0x80000000
899 928
929cleanup_io_return:
930 mvc __LC_RETURN_PSW(4),0(%r12)
931 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_work_loop)
932 la %r12,__LC_RETURN_PSW
933 br %r14
934
935cleanup_io_leave:
936 clc 4(4,%r12),BASED(cleanup_io_leave_insn)
937 be BASED(2f)
938#ifdef CONFIG_VIRT_CPU_ACCOUNTING
939 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
940 clc 4(4,%r12),BASED(cleanup_io_leave_insn+4)
941 be BASED(2f)
942#endif
943 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
944 c %r12,BASED(.Lmck_old_psw)
945 bne BASED(0f)
946 mvc __LC_SAVE_AREA+32(16),SP_R12(%r15)
947 b BASED(1f)
9480: mvc __LC_SAVE_AREA+16(16),SP_R12(%r15)
9491: lm %r0,%r11,SP_R0(%r15)
950 l %r15,SP_R15(%r15)
9512: la %r12,__LC_RETURN_PSW
952 br %r14
953cleanup_io_leave_insn:
954#ifdef CONFIG_VIRT_CPU_ACCOUNTING
955 .long io_leave + 18 + 0x80000000
956#endif
957 .long io_leave + 14 + 0x80000000
958
900/* 959/*
901 * Integer constants 960 * Integer constants
902 */ 961 */
@@ -918,6 +977,7 @@ cleanup_sysc_leave_insn:
918.Ls390_mcck: .long s390_do_machine_check 977.Ls390_mcck: .long s390_do_machine_check
919.Ls390_handle_mcck: 978.Ls390_handle_mcck:
920 .long s390_handle_mcck 979 .long s390_handle_mcck
980.Lmck_old_psw: .long __LC_MCK_OLD_PSW
921.Ldo_IRQ: .long do_IRQ 981.Ldo_IRQ: .long do_IRQ
922.Ldo_extint: .long do_extint 982.Ldo_extint: .long do_extint
923.Ldo_signal: .long do_signal 983.Ldo_signal: .long do_signal
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index d9f22915008c..5db5976ff594 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/*
@@ -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 */
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c
index 5bb255e02acc..4191fd9d4d11 100644
--- a/drivers/s390/s390mach.c
+++ b/drivers/s390/s390mach.c
@@ -240,7 +240,7 @@ s390_revalidate_registers(struct mci *mci)
240 * Floating point control register can't be restored. 240 * Floating point control register can't be restored.
241 * Task will be terminated. 241 * Task will be terminated.
242 */ 242 */
243 asm volatile ("lfpc 0(%0)" : : "a" (&zero)); 243 asm volatile ("lfpc 0(%0)" : : "a" (&zero), "m" (zero));
244 kill_task = 1; 244 kill_task = 1;
245 245
246 } 246 }
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index afe6a9f9b0ae..c6f51c9ce3ff 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -68,6 +68,7 @@
68#define __LC_SYSTEM_TIMER 0x270 68#define __LC_SYSTEM_TIMER 0x270
69#define __LC_LAST_UPDATE_CLOCK 0x278 69#define __LC_LAST_UPDATE_CLOCK 0x278
70#define __LC_STEAL_CLOCK 0x280 70#define __LC_STEAL_CLOCK 0x280
71#define __LC_RETURN_MCCK_PSW 0x288
71#define __LC_KERNEL_STACK 0xC40 72#define __LC_KERNEL_STACK 0xC40
72#define __LC_THREAD_INFO 0xC44 73#define __LC_THREAD_INFO 0xC44
73#define __LC_ASYNC_STACK 0xC48 74#define __LC_ASYNC_STACK 0xC48
@@ -90,6 +91,7 @@
90#define __LC_SYSTEM_TIMER 0x278 91#define __LC_SYSTEM_TIMER 0x278
91#define __LC_LAST_UPDATE_CLOCK 0x280 92#define __LC_LAST_UPDATE_CLOCK 0x280
92#define __LC_STEAL_CLOCK 0x288 93#define __LC_STEAL_CLOCK 0x288
94#define __LC_RETURN_MCCK_PSW 0x290
93#define __LC_KERNEL_STACK 0xD40 95#define __LC_KERNEL_STACK 0xD40
94#define __LC_THREAD_INFO 0xD48 96#define __LC_THREAD_INFO 0xD48
95#define __LC_ASYNC_STACK 0xD50 97#define __LC_ASYNC_STACK 0xD50
@@ -196,7 +198,8 @@ struct _lowcore
196 __u64 system_timer; /* 0x270 */ 198 __u64 system_timer; /* 0x270 */
197 __u64 last_update_clock; /* 0x278 */ 199 __u64 last_update_clock; /* 0x278 */
198 __u64 steal_clock; /* 0x280 */ 200 __u64 steal_clock; /* 0x280 */
199 __u8 pad8[0xc00-0x288]; /* 0x288 */ 201 psw_t return_mcck_psw; /* 0x288 */
202 __u8 pad8[0xc00-0x290]; /* 0x290 */
200 203
201 /* System info area */ 204 /* System info area */
202 __u32 save_area[16]; /* 0xc00 */ 205 __u32 save_area[16]; /* 0xc00 */
@@ -285,7 +288,8 @@ struct _lowcore
285 __u64 system_timer; /* 0x278 */ 288 __u64 system_timer; /* 0x278 */
286 __u64 last_update_clock; /* 0x280 */ 289 __u64 last_update_clock; /* 0x280 */
287 __u64 steal_clock; /* 0x288 */ 290 __u64 steal_clock; /* 0x288 */
288 __u8 pad8[0xc00-0x290]; /* 0x290 */ 291 psw_t return_mcck_psw; /* 0x290 */
292 __u8 pad8[0xc00-0x2a0]; /* 0x2a0 */
289 /* System info area */ 293 /* System info area */
290 __u64 save_area[16]; /* 0xc00 */ 294 __u64 save_area[16]; /* 0xc00 */
291 __u8 pad9[0xd40-0xc80]; /* 0xc80 */ 295 __u8 pad9[0xd40-0xc80]; /* 0xc80 */