diff options
Diffstat (limited to 'arch/s390/kernel/entry64.S')
-rw-r--r-- | arch/s390/kernel/entry64.S | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 4e1c292fa7e3..229fe1d07749 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -81,16 +81,14 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | |||
81 | 81 | ||
82 | .macro HANDLE_SIE_INTERCEPT scratch | 82 | .macro HANDLE_SIE_INTERCEPT scratch |
83 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 83 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) |
84 | tm __TI_flags+6(%r12),_TIF_SIE>>8 | 84 | tmhh %r8,0x0001 # interrupting from user ? |
85 | jz .+42 | 85 | jnz .+42 |
86 | tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP | ||
87 | jz .+8 | ||
88 | .insn s,0xb2800000,BASED(.Lhost_id) # set host id | ||
89 | lgr \scratch,%r9 | 86 | lgr \scratch,%r9 |
90 | slg \scratch,BASED(.Lsie_loop) | 87 | slg \scratch,BASED(.Lsie_loop) |
91 | clg \scratch,BASED(.Lsie_length) | 88 | clg \scratch,BASED(.Lsie_length) |
92 | jhe .+10 | 89 | jhe .+22 |
93 | lg %r9,BASED(.Lsie_loop) | 90 | lg %r9,BASED(.Lsie_loop) |
91 | SPP BASED(.Lhost_id) # set host id | ||
94 | #endif | 92 | #endif |
95 | .endm | 93 | .endm |
96 | 94 | ||
@@ -148,6 +146,14 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | |||
148 | ssm __LC_RETURN_PSW | 146 | ssm __LC_RETURN_PSW |
149 | .endm | 147 | .endm |
150 | 148 | ||
149 | .macro STCK savearea | ||
150 | #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES | ||
151 | .insn s,0xb27c0000,\savearea # store clock fast | ||
152 | #else | ||
153 | .insn s,0xb2050000,\savearea # store clock | ||
154 | #endif | ||
155 | .endm | ||
156 | |||
151 | .section .kprobes.text, "ax" | 157 | .section .kprobes.text, "ax" |
152 | 158 | ||
153 | /* | 159 | /* |
@@ -158,22 +164,23 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | |||
158 | * gpr2 = prev | 164 | * gpr2 = prev |
159 | */ | 165 | */ |
160 | ENTRY(__switch_to) | 166 | ENTRY(__switch_to) |
167 | stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task | ||
168 | stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev | ||
161 | lg %r4,__THREAD_info(%r2) # get thread_info of prev | 169 | lg %r4,__THREAD_info(%r2) # get thread_info of prev |
162 | lg %r5,__THREAD_info(%r3) # get thread_info of next | 170 | lg %r5,__THREAD_info(%r3) # get thread_info of next |
171 | lgr %r15,%r5 | ||
172 | aghi %r15,STACK_SIZE # end of kernel stack of next | ||
173 | stg %r3,__LC_CURRENT # store task struct of next | ||
174 | stg %r5,__LC_THREAD_INFO # store thread info of next | ||
175 | stg %r15,__LC_KERNEL_STACK # store end of kernel stack | ||
176 | lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 | ||
177 | mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next | ||
178 | lg %r15,__THREAD_ksp(%r3) # load kernel stack of next | ||
163 | tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? | 179 | tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? |
164 | jz 0f | 180 | jz 0f |
165 | ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev | 181 | ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev |
166 | oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next | 182 | oi __TI_flags+7(%r5),_TIF_MCCK_PENDING # set it in next |
167 | 0: stmg %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task | 183 | 0: lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task |
168 | stg %r15,__THREAD_ksp(%r2) # store kernel stack of prev | ||
169 | lg %r15,__THREAD_ksp(%r3) # load kernel stack of next | ||
170 | lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 | ||
171 | lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task | ||
172 | stg %r3,__LC_CURRENT # store task struct of next | ||
173 | mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next | ||
174 | stg %r5,__LC_THREAD_INFO # store thread info of next | ||
175 | aghi %r5,STACK_SIZE # end of kernel stack of next | ||
176 | stg %r5,__LC_KERNEL_STACK # store end of kernel stack | ||
177 | br %r14 | 184 | br %r14 |
178 | 185 | ||
179 | __critical_start: | 186 | __critical_start: |
@@ -458,7 +465,7 @@ pgm_svcper: | |||
458 | * IO interrupt handler routine | 465 | * IO interrupt handler routine |
459 | */ | 466 | */ |
460 | ENTRY(io_int_handler) | 467 | ENTRY(io_int_handler) |
461 | stck __LC_INT_CLOCK | 468 | STCK __LC_INT_CLOCK |
462 | stpt __LC_ASYNC_ENTER_TIMER | 469 | stpt __LC_ASYNC_ENTER_TIMER |
463 | stmg %r8,%r15,__LC_SAVE_AREA_ASYNC | 470 | stmg %r8,%r15,__LC_SAVE_AREA_ASYNC |
464 | lg %r10,__LC_LAST_BREAK | 471 | lg %r10,__LC_LAST_BREAK |
@@ -604,7 +611,7 @@ io_notify_resume: | |||
604 | * External interrupt handler routine | 611 | * External interrupt handler routine |
605 | */ | 612 | */ |
606 | ENTRY(ext_int_handler) | 613 | ENTRY(ext_int_handler) |
607 | stck __LC_INT_CLOCK | 614 | STCK __LC_INT_CLOCK |
608 | stpt __LC_ASYNC_ENTER_TIMER | 615 | stpt __LC_ASYNC_ENTER_TIMER |
609 | stmg %r8,%r15,__LC_SAVE_AREA_ASYNC | 616 | stmg %r8,%r15,__LC_SAVE_AREA_ASYNC |
610 | lg %r10,__LC_LAST_BREAK | 617 | lg %r10,__LC_LAST_BREAK |
@@ -622,6 +629,7 @@ ext_skip: | |||
622 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC | 629 | mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC |
623 | stmg %r8,%r9,__PT_PSW(%r11) | 630 | stmg %r8,%r9,__PT_PSW(%r11) |
624 | TRACE_IRQS_OFF | 631 | TRACE_IRQS_OFF |
632 | xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) | ||
625 | lghi %r1,4096 | 633 | lghi %r1,4096 |
626 | lgr %r2,%r11 # pass pointer to pt_regs | 634 | lgr %r2,%r11 # pass pointer to pt_regs |
627 | llgf %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code | 635 | llgf %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code |
@@ -638,7 +646,7 @@ ENTRY(psw_idle) | |||
638 | larl %r1,psw_idle_lpsw+4 | 646 | larl %r1,psw_idle_lpsw+4 |
639 | stg %r1,__SF_EMPTY+8(%r15) | 647 | stg %r1,__SF_EMPTY+8(%r15) |
640 | larl %r1,.Lvtimer_max | 648 | larl %r1,.Lvtimer_max |
641 | stck __IDLE_ENTER(%r2) | 649 | STCK __IDLE_ENTER(%r2) |
642 | ltr %r5,%r5 | 650 | ltr %r5,%r5 |
643 | stpt __VQ_IDLE_ENTER(%r3) | 651 | stpt __VQ_IDLE_ENTER(%r3) |
644 | jz psw_idle_lpsw | 652 | jz psw_idle_lpsw |
@@ -654,7 +662,7 @@ __critical_end: | |||
654 | * Machine check handler routines | 662 | * Machine check handler routines |
655 | */ | 663 | */ |
656 | ENTRY(mcck_int_handler) | 664 | ENTRY(mcck_int_handler) |
657 | stck __LC_MCCK_CLOCK | 665 | STCK __LC_MCCK_CLOCK |
658 | la %r1,4095 # revalidate r1 | 666 | la %r1,4095 # revalidate r1 |
659 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer | 667 | spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer |
660 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs | 668 | lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs |
@@ -967,7 +975,6 @@ ENTRY(sie64a) | |||
967 | xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 | 975 | xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 |
968 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 | 976 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 |
969 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | 977 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct |
970 | oi __TI_flags+6(%r14),_TIF_SIE>>8 | ||
971 | sie_loop: | 978 | sie_loop: |
972 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | 979 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct |
973 | tm __TI_flags+7(%r14),_TIF_EXIT_SIE | 980 | tm __TI_flags+7(%r14),_TIF_EXIT_SIE |
@@ -985,7 +992,6 @@ sie_done: | |||
985 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | 992 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct |
986 | sie_exit: | 993 | sie_exit: |
987 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 994 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
988 | ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) | ||
989 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area | 995 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area |
990 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | 996 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 |
991 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers | 997 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers |
@@ -994,7 +1000,6 @@ sie_exit: | |||
994 | sie_fault: | 1000 | sie_fault: |
995 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 1001 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
996 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | 1002 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct |
997 | ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) | ||
998 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area | 1003 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area |
999 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | 1004 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 |
1000 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers | 1005 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers |