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.S80
1 files changed, 57 insertions, 23 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 2ac095bc0e25..f3222a1b2861 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -87,13 +87,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
87 larl %r13,system_call 87 larl %r13,system_call
88 .endm 88 .endm
89 89
90 .macro SAVE_ALL psworg,savearea,sync 90 .macro SAVE_ALL_SYNC psworg,savearea
91 la %r12,\psworg 91 la %r12,\psworg
92 .if \sync
93 tm \psworg+1,0x01 # test problem state bit 92 tm \psworg+1,0x01 # test problem state bit
94 jz 2f # skip stack setup save 93 jz 2f # skip stack setup save
95 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 94 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
96 .else 95#ifdef CONFIG_CHECK_STACK
96 j 3f
972: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
98 jz stack_overflow
993:
100#endif
1012:
102 .endm
103
104 .macro SAVE_ALL_ASYNC psworg,savearea
105 la %r12,\psworg
97 tm \psworg+1,0x01 # test problem state bit 106 tm \psworg+1,0x01 # test problem state bit
98 jnz 1f # from user -> load kernel stack 107 jnz 1f # from user -> load kernel stack
99 clc \psworg+8(8),BASED(.Lcritical_end) 108 clc \psworg+8(8),BASED(.Lcritical_end)
@@ -108,7 +117,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
108 srag %r14,%r14,STACK_SHIFT 117 srag %r14,%r14,STACK_SHIFT
109 jz 2f 118 jz 2f
1101: lg %r15,__LC_ASYNC_STACK # load async stack 1191: lg %r15,__LC_ASYNC_STACK # load async stack
111 .endif
112#ifdef CONFIG_CHECK_STACK 120#ifdef CONFIG_CHECK_STACK
113 j 3f 121 j 3f
1142: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 1222: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
@@ -187,7 +195,7 @@ system_call:
187 STORE_TIMER __LC_SYNC_ENTER_TIMER 195 STORE_TIMER __LC_SYNC_ENTER_TIMER
188sysc_saveall: 196sysc_saveall:
189 SAVE_ALL_BASE __LC_SAVE_AREA 197 SAVE_ALL_BASE __LC_SAVE_AREA
190 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 198 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
191 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 199 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
192 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 200 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
193#ifdef CONFIG_VIRT_CPU_ACCOUNTING 201#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -446,7 +454,7 @@ pgm_check_handler:
446 SAVE_ALL_BASE __LC_SAVE_AREA 454 SAVE_ALL_BASE __LC_SAVE_AREA
447 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 455 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
448 jnz pgm_per # got per exception -> special case 456 jnz pgm_per # got per exception -> special case
449 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 457 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
450 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 458 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
451#ifdef CONFIG_VIRT_CPU_ACCOUNTING 459#ifdef CONFIG_VIRT_CPU_ACCOUNTING
452 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 460 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -485,7 +493,7 @@ pgm_per:
485# Normal per exception 493# Normal per exception
486# 494#
487pgm_per_std: 495pgm_per_std:
488 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 496 SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA
489 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA 497 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
490#ifdef CONFIG_VIRT_CPU_ACCOUNTING 498#ifdef CONFIG_VIRT_CPU_ACCOUNTING
491 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 499 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -511,7 +519,7 @@ pgm_no_vtime2:
511# it was a single stepped SVC that is causing all the trouble 519# it was a single stepped SVC that is causing all the trouble
512# 520#
513pgm_svcper: 521pgm_svcper:
514 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 522 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
515 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 523 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
516#ifdef CONFIG_VIRT_CPU_ACCOUNTING 524#ifdef CONFIG_VIRT_CPU_ACCOUNTING
517 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 525 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -539,7 +547,7 @@ io_int_handler:
539 STORE_TIMER __LC_ASYNC_ENTER_TIMER 547 STORE_TIMER __LC_ASYNC_ENTER_TIMER
540 stck __LC_INT_CLOCK 548 stck __LC_INT_CLOCK
541 SAVE_ALL_BASE __LC_SAVE_AREA+32 549 SAVE_ALL_BASE __LC_SAVE_AREA+32
542 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 550 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
543 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 551 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32
544#ifdef CONFIG_VIRT_CPU_ACCOUNTING 552#ifdef CONFIG_VIRT_CPU_ACCOUNTING
545 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 553 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -647,7 +655,7 @@ ext_int_handler:
647 STORE_TIMER __LC_ASYNC_ENTER_TIMER 655 STORE_TIMER __LC_ASYNC_ENTER_TIMER
648 stck __LC_INT_CLOCK 656 stck __LC_INT_CLOCK
649 SAVE_ALL_BASE __LC_SAVE_AREA+32 657 SAVE_ALL_BASE __LC_SAVE_AREA+32
650 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 658 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
651 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 659 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32
652#ifdef CONFIG_VIRT_CPU_ACCOUNTING 660#ifdef CONFIG_VIRT_CPU_ACCOUNTING
653 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 661 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
@@ -672,21 +680,32 @@ __critical_end:
672mcck_int_handler: 680mcck_int_handler:
673 la %r1,4095 # revalidate r1 681 la %r1,4095 # revalidate r1
674 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 682 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
675 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1)
676 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 683 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
677 SAVE_ALL_BASE __LC_SAVE_AREA+64 684 SAVE_ALL_BASE __LC_SAVE_AREA+64
678 la %r12,__LC_MCK_OLD_PSW 685 la %r12,__LC_MCK_OLD_PSW
679 tm __LC_MCCK_CODE,0x80 # system damage? 686 tm __LC_MCCK_CODE,0x80 # system damage?
680 jo mcck_int_main # yes -> rest of mcck code invalid 687 jo mcck_int_main # yes -> rest of mcck code invalid
681 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
682 jo 0f
683 spt __LC_LAST_UPDATE_TIMER
684#ifdef CONFIG_VIRT_CPU_ACCOUNTING 688#ifdef CONFIG_VIRT_CPU_ACCOUNTING
685 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 689 la %r14,4095
686 mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER 690 mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER
687 mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER 691 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14)
692 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
693 jo 1f
694 la %r14,__LC_SYNC_ENTER_TIMER
695 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
696 jl 0f
697 la %r14,__LC_ASYNC_ENTER_TIMER
6980: clc 0(8,%r14),__LC_EXIT_TIMER
699 jl 0f
700 la %r14,__LC_EXIT_TIMER
7010: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
702 jl 0f
703 la %r14,__LC_LAST_UPDATE_TIMER
7040: spt 0(%r14)
705 mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14)
7061:
688#endif 707#endif
6890: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 708 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
690 jno mcck_int_main # no -> skip cleanup critical 709 jno mcck_int_main # no -> skip cleanup critical
691 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 710 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
692 jnz mcck_int_main # from user -> load kernel stack 711 jnz mcck_int_main # from user -> load kernel stack
@@ -705,7 +724,7 @@ mcck_int_main:
705#ifdef CONFIG_VIRT_CPU_ACCOUNTING 724#ifdef CONFIG_VIRT_CPU_ACCOUNTING
706 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? 725 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
707 jno mcck_no_vtime # no -> no timer update 726 jno mcck_no_vtime # no -> no timer update
708 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? 727 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
709 jz mcck_no_vtime 728 jz mcck_no_vtime
710 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 729 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
711 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 730 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
@@ -727,7 +746,17 @@ mcck_no_vtime:
727 jno mcck_return 746 jno mcck_return
728 brasl %r14,s390_handle_mcck 747 brasl %r14,s390_handle_mcck
729mcck_return: 748mcck_return:
730 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 749 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
750 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
751 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
752#ifdef CONFIG_VIRT_CPU_ACCOUNTING
753 mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104
754 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
755 jno 0f
756 stpt __LC_EXIT_TIMER
7570:
758#endif
759 lpswe __LC_RETURN_MCCK_PSW # back to caller
731 760
732#ifdef CONFIG_SMP 761#ifdef CONFIG_SMP
733/* 762/*
@@ -789,6 +818,8 @@ cleanup_table_sysc_leave:
789 .quad sysc_leave, sysc_work_loop 818 .quad sysc_leave, sysc_work_loop
790cleanup_table_sysc_work_loop: 819cleanup_table_sysc_work_loop:
791 .quad sysc_work_loop, sysc_reschedule 820 .quad sysc_work_loop, sysc_reschedule
821cleanup_table_io_return:
822 .quad io_return, io_leave
792cleanup_table_io_leave: 823cleanup_table_io_leave:
793 .quad io_leave, io_done 824 .quad io_leave, io_done
794cleanup_table_io_work_loop: 825cleanup_table_io_work_loop:
@@ -815,6 +846,11 @@ cleanup_critical:
815 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) 846 clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8)
816 jl cleanup_sysc_return 847 jl cleanup_sysc_return
8170: 8480:
849 clc 8(8,%r12),BASED(cleanup_table_io_return)
850 jl 0f
851 clc 8(8,%r12),BASED(cleanup_table_io_return+8)
852 jl cleanup_io_return
8530:
818 clc 8(8,%r12),BASED(cleanup_table_io_leave) 854 clc 8(8,%r12),BASED(cleanup_table_io_leave)
819 jl 0f 855 jl 0f
820 clc 8(8,%r12),BASED(cleanup_table_io_leave+8) 856 clc 8(8,%r12),BASED(cleanup_table_io_leave+8)
@@ -847,7 +883,7 @@ cleanup_system_call:
847 mvc __LC_SAVE_AREA(32),0(%r12) 883 mvc __LC_SAVE_AREA(32),0(%r12)
8480: stg %r13,8(%r12) 8840: stg %r13,8(%r12)
849 stg %r12,__LC_SAVE_AREA+96 # argh 885 stg %r12,__LC_SAVE_AREA+96 # argh
850 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 886 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
851 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 887 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
852 lg %r12,__LC_SAVE_AREA+96 # argh 888 lg %r12,__LC_SAVE_AREA+96 # argh
853 stg %r15,24(%r12) 889 stg %r15,24(%r12)
@@ -957,7 +993,6 @@ cleanup_io_leave_insn:
957 .quad __critical_end 993 .quad __critical_end
958 994
959#define SYSCALL(esa,esame,emu) .long esame 995#define SYSCALL(esa,esame,emu) .long esame
960 .globl sys_call_table
961sys_call_table: 996sys_call_table:
962#include "syscalls.S" 997#include "syscalls.S"
963#undef SYSCALL 998#undef SYSCALL
@@ -965,7 +1000,6 @@ sys_call_table:
965#ifdef CONFIG_COMPAT 1000#ifdef CONFIG_COMPAT
966 1001
967#define SYSCALL(esa,esame,emu) .long emu 1002#define SYSCALL(esa,esame,emu) .long emu
968 .globl sys_call_table_emu
969sys_call_table_emu: 1003sys_call_table_emu:
970#include "syscalls.S" 1004#include "syscalls.S"
971#undef SYSCALL 1005#undef SYSCALL