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.S97
1 files changed, 88 insertions, 9 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 51527ab8c8f9..57ca75d0ad7f 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -7,6 +7,7 @@
7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8 * Hartmut Penner (hp@de.ibm.com), 8 * Hartmut Penner (hp@de.ibm.com),
9 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), 9 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
10 * Heiko Carstens <heiko.carstens@de.ibm.com>
10 */ 11 */
11 12
12#include <linux/sys.h> 13#include <linux/sys.h>
@@ -52,9 +53,9 @@ SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
52STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 53STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
53STACK_SIZE = 1 << STACK_SHIFT 54STACK_SIZE = 1 << STACK_SHIFT
54 55
55_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 56_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
56 _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 57 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
57_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) 58_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
58 59
59#define BASED(name) name-system_call(%r13) 60#define BASED(name) name-system_call(%r13)
60 61
@@ -114,7 +115,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
114 jz stack_overflow 115 jz stack_overflow
1153: 1163:
116#endif 117#endif
1172: aghi %r15,-SP_SIZE # make room for registers & psw 1182:
119 .endm
120
121 .macro CREATE_STACK_FRAME psworg,savearea
122 aghi %r15,-SP_SIZE # make room for registers & psw
118 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 123 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
119 la %r12,\psworg 124 la %r12,\psworg
120 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 125 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
@@ -152,6 +157,13 @@ __switch_to:
152 je __switch_to_noper # we got away without bashing TLB's 157 je __switch_to_noper # we got away without bashing TLB's
153 lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't 158 lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't
154__switch_to_noper: 159__switch_to_noper:
160 lg %r4,__THREAD_info(%r2) # get thread_info of prev
161 tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
162 jz __switch_to_no_mcck
163 ni __TI_flags+7(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
164 lg %r4,__THREAD_info(%r3) # get thread_info of next
165 oi __TI_flags+7(%r4),_TIF_MCCK_PENDING # set it in next
166__switch_to_no_mcck:
155 stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task 167 stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
156 stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp 168 stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp
157 lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp 169 lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp
@@ -176,6 +188,7 @@ system_call:
176sysc_saveall: 188sysc_saveall:
177 SAVE_ALL_BASE __LC_SAVE_AREA 189 SAVE_ALL_BASE __LC_SAVE_AREA
178 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 190 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
191 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
179 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 192 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
180#ifdef CONFIG_VIRT_CPU_ACCOUNTING 193#ifdef CONFIG_VIRT_CPU_ACCOUNTING
181sysc_vtime: 194sysc_vtime:
@@ -232,6 +245,8 @@ sysc_work_loop:
232# One of the work bits is on. Find out which one. 245# One of the work bits is on. Find out which one.
233# 246#
234sysc_work: 247sysc_work:
248 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
249 jo sysc_mcck_pending
235 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 250 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
236 jo sysc_reschedule 251 jo sysc_reschedule
237 tm __TI_flags+7(%r9),_TIF_SIGPENDING 252 tm __TI_flags+7(%r9),_TIF_SIGPENDING
@@ -250,6 +265,13 @@ sysc_reschedule:
250 jg schedule # return point is sysc_return 265 jg schedule # return point is sysc_return
251 266
252# 267#
268# _TIF_MCCK_PENDING is set, call handler
269#
270sysc_mcck_pending:
271 larl %r14,sysc_work_loop
272 jg s390_handle_mcck # TIF bit will be cleared by handler
273
274#
253# _TIF_SIGPENDING is set, call do_signal 275# _TIF_SIGPENDING is set, call do_signal
254# 276#
255sysc_sigpending: 277sysc_sigpending:
@@ -474,6 +496,7 @@ pgm_check_handler:
474 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 496 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
475 jnz pgm_per # got per exception -> special case 497 jnz pgm_per # got per exception -> special case
476 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 498 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
499 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
477#ifdef CONFIG_VIRT_CPU_ACCOUNTING 500#ifdef CONFIG_VIRT_CPU_ACCOUNTING
478 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 501 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
479 jz pgm_no_vtime 502 jz pgm_no_vtime
@@ -512,6 +535,7 @@ pgm_per:
512# 535#
513pgm_per_std: 536pgm_per_std:
514 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 537 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
538 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
515#ifdef CONFIG_VIRT_CPU_ACCOUNTING 539#ifdef CONFIG_VIRT_CPU_ACCOUNTING
516 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 540 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
517 jz pgm_no_vtime2 541 jz pgm_no_vtime2
@@ -537,6 +561,7 @@ pgm_no_vtime2:
537# 561#
538pgm_svcper: 562pgm_svcper:
539 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 563 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
564 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
540#ifdef CONFIG_VIRT_CPU_ACCOUNTING 565#ifdef CONFIG_VIRT_CPU_ACCOUNTING
541 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 566 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
542 jz pgm_no_vtime3 567 jz pgm_no_vtime3
@@ -564,6 +589,7 @@ io_int_handler:
564 stck __LC_INT_CLOCK 589 stck __LC_INT_CLOCK
565 SAVE_ALL_BASE __LC_SAVE_AREA+32 590 SAVE_ALL_BASE __LC_SAVE_AREA+32
566 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 591 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
592 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
567#ifdef CONFIG_VIRT_CPU_ACCOUNTING 593#ifdef CONFIG_VIRT_CPU_ACCOUNTING
568 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 594 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
569 jz io_no_vtime 595 jz io_no_vtime
@@ -621,9 +647,11 @@ io_work:
621 lgr %r15,%r1 647 lgr %r15,%r1
622# 648#
623# One of the work bits is on. Find out which one. 649# One of the work bits is on. Find out which one.
624# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED 650# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
625# 651#
626io_work_loop: 652io_work_loop:
653 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
654 jo io_mcck_pending
627 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED 655 tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
628 jo io_reschedule 656 jo io_reschedule
629 tm __TI_flags+7(%r9),_TIF_SIGPENDING 657 tm __TI_flags+7(%r9),_TIF_SIGPENDING
@@ -631,6 +659,13 @@ io_work_loop:
631 j io_leave 659 j io_leave
632 660
633# 661#
662# _TIF_MCCK_PENDING is set, call handler
663#
664io_mcck_pending:
665 larl %r14,io_work_loop
666 jg s390_handle_mcck # TIF bit will be cleared by handler
667
668#
634# _TIF_NEED_RESCHED is set, call schedule 669# _TIF_NEED_RESCHED is set, call schedule
635# 670#
636io_reschedule: 671io_reschedule:
@@ -661,6 +696,7 @@ ext_int_handler:
661 stck __LC_INT_CLOCK 696 stck __LC_INT_CLOCK
662 SAVE_ALL_BASE __LC_SAVE_AREA+32 697 SAVE_ALL_BASE __LC_SAVE_AREA+32
663 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 698 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
699 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
664#ifdef CONFIG_VIRT_CPU_ACCOUNTING 700#ifdef CONFIG_VIRT_CPU_ACCOUNTING
665 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 701 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
666 jz ext_no_vtime 702 jz ext_no_vtime
@@ -680,18 +716,60 @@ ext_no_vtime:
680 */ 716 */
681 .globl mcck_int_handler 717 .globl mcck_int_handler
682mcck_int_handler: 718mcck_int_handler:
683 STORE_TIMER __LC_ASYNC_ENTER_TIMER 719 la %r1,4095 # revalidate r1
720 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
721 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
684 SAVE_ALL_BASE __LC_SAVE_AREA+64 722 SAVE_ALL_BASE __LC_SAVE_AREA+64
685 SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0 723 la %r12,__LC_MCK_OLD_PSW
724 tm __LC_MCCK_CODE,0x80 # system damage?
725 jo mcck_int_main # yes -> rest of mcck code invalid
726 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
727 jo 0f
728 spt __LC_LAST_UPDATE_TIMER
686#ifdef CONFIG_VIRT_CPU_ACCOUNTING 729#ifdef CONFIG_VIRT_CPU_ACCOUNTING
687 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 730 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
731 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
732 mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_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 ?
688 jz mcck_no_vtime 736 jz mcck_no_vtime
689 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 737 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
690 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 738 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
691 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 739 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
692mcck_no_vtime: 740mcck_no_vtime:
693#endif 741#endif
694 brasl %r14,s390_do_machine_check 7420:
743 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
744 jno mcck_int_main # no -> skip cleanup critical
745 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
746 jnz mcck_int_main # from user -> load kernel stack
747 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end)
748 jhe mcck_int_main
749 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start)
750 jl mcck_int_main
751 brasl %r14,cleanup_critical
752mcck_int_main:
753 lg %r14,__LC_PANIC_STACK # are we already on the panic stack?
754 slgr %r14,%r15
755 srag %r14,%r14,PAGE_SHIFT
756 jz 0f
757 lg %r15,__LC_PANIC_STACK # load panic stack
7580: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64
759 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
760 la %r2,SP_PTREGS(%r15) # load pt_regs
761 brasl %r14,s390_do_machine_check
762 tm SP_PSW+1(%r15),0x01 # returning to user ?
763 jno mcck_return
764 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
765 aghi %r1,-SP_SIZE
766 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
767 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
768 lgr %r15,%r1
769 stosm __SF_EMPTY(%r15),0x04 # turn dat on
770 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
771 jno mcck_return
772 brasl %r14,s390_handle_mcck
695mcck_return: 773mcck_return:
696 RESTORE_ALL 0 774 RESTORE_ALL 0
697 775
@@ -775,7 +853,7 @@ cleanup_critical:
775 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop) 853 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop)
776 jl 0f 854 jl 0f
777 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) 855 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
778 jl cleanup_sysc_leave 856 jl cleanup_sysc_return
7790: 8570:
780 br %r14 858 br %r14
781 859
@@ -793,6 +871,7 @@ cleanup_system_call:
793 mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32 871 mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32
7940: stg %r13,__LC_SAVE_AREA+40 8720: stg %r13,__LC_SAVE_AREA+40
795 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 873 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
874 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
796 stg %r15,__LC_SAVE_AREA+56 875 stg %r15,__LC_SAVE_AREA+56
797 llgh %r7,__LC_SVC_INT_CODE 876 llgh %r7,__LC_SVC_INT_CODE
798#ifdef CONFIG_VIRT_CPU_ACCOUNTING 877#ifdef CONFIG_VIRT_CPU_ACCOUNTING