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.S111
1 files changed, 82 insertions, 29 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index d61967e2eab0..7a0fd426ca92 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -9,8 +9,8 @@
9 * Heiko Carstens <heiko.carstens@de.ibm.com> 9 * Heiko Carstens <heiko.carstens@de.ibm.com>
10 */ 10 */
11 11
12#include <linux/linkage.h>
13#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/linkage.h>
14#include <asm/cache.h> 14#include <asm/cache.h>
15#include <asm/errno.h> 15#include <asm/errno.h>
16#include <asm/ptrace.h> 16#include <asm/ptrace.h>
@@ -56,15 +56,28 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
56 _TIF_MCCK_PENDING) 56 _TIF_MCCK_PENDING)
57_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ 57_TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
58 _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) 58 _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)
59_TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
59 60
60#define BASED(name) name-system_call(%r13) 61#define BASED(name) name-system_call(%r13)
61 62
63 .macro SPP newpp
64#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
65 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
66 jz .+8
67 .insn s,0xb2800000,\newpp
68#endif
69 .endm
70
62 .macro HANDLE_SIE_INTERCEPT 71 .macro HANDLE_SIE_INTERCEPT
63#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 72#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
64 lg %r3,__LC_SIE_HOOK 73 tm __TI_flags+6(%r12),_TIF_SIE>>8
65 ltgr %r3,%r3
66 jz 0f 74 jz 0f
67 basr %r14,%r3 75 SPP __LC_CMF_HPP # set host id
76 clc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
77 jl 0f
78 clc SP_PSW+8(8,%r15),BASED(.Lsie_done)
79 jhe 0f
80 mvc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
680: 810:
69#endif 82#endif
70 .endm 83 .endm
@@ -206,8 +219,7 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \
206 * Returns: 219 * Returns:
207 * gpr2 = prev 220 * gpr2 = prev
208 */ 221 */
209 .globl __switch_to 222ENTRY(__switch_to)
210__switch_to:
211 lg %r4,__THREAD_info(%r2) # get thread_info of prev 223 lg %r4,__THREAD_info(%r2) # get thread_info of prev
212 lg %r5,__THREAD_info(%r3) # get thread_info of next 224 lg %r5,__THREAD_info(%r3) # get thread_info of next
213 tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending? 225 tm __TI_flags+7(%r4),_TIF_MCCK_PENDING # machine check pending?
@@ -232,8 +244,7 @@ __critical_start:
232 * are executed with interrupts enabled. 244 * are executed with interrupts enabled.
233 */ 245 */
234 246
235 .globl system_call 247ENTRY(system_call)
236system_call:
237 stpt __LC_SYNC_ENTER_TIMER 248 stpt __LC_SYNC_ENTER_TIMER
238sysc_saveall: 249sysc_saveall:
239 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 250 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
@@ -395,8 +406,7 @@ sysc_tracenogo:
395# 406#
396# a new process exits the kernel with ret_from_fork 407# a new process exits the kernel with ret_from_fork
397# 408#
398 .globl ret_from_fork 409ENTRY(ret_from_fork)
399ret_from_fork:
400 lg %r13,__LC_SVC_NEW_PSW+8 410 lg %r13,__LC_SVC_NEW_PSW+8
401 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 411 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
402 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 412 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ?
@@ -411,8 +421,7 @@ ret_from_fork:
411# kernel_execve function needs to deal with pt_regs that is not 421# kernel_execve function needs to deal with pt_regs that is not
412# at the usual place 422# at the usual place
413# 423#
414 .globl kernel_execve 424ENTRY(kernel_execve)
415kernel_execve:
416 stmg %r12,%r15,96(%r15) 425 stmg %r12,%r15,96(%r15)
417 lgr %r14,%r15 426 lgr %r14,%r15
418 aghi %r15,-SP_SIZE 427 aghi %r15,-SP_SIZE
@@ -442,8 +451,7 @@ kernel_execve:
442 * Program check handler routine 451 * Program check handler routine
443 */ 452 */
444 453
445 .globl pgm_check_handler 454ENTRY(pgm_check_handler)
446pgm_check_handler:
447/* 455/*
448 * First we need to check for a special case: 456 * First we need to check for a special case:
449 * Single stepping an instruction that disables the PER event mask will 457 * Single stepping an instruction that disables the PER event mask will
@@ -465,6 +473,7 @@ pgm_check_handler:
465 xc SP_ILC(4,%r15),SP_ILC(%r15) 473 xc SP_ILC(4,%r15),SP_ILC(%r15)
466 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 474 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
467 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 475 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
476 HANDLE_SIE_INTERCEPT
468 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 477 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
469 jz pgm_no_vtime 478 jz pgm_no_vtime
470 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 479 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -472,7 +481,6 @@ pgm_check_handler:
472 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 481 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
473 LAST_BREAK 482 LAST_BREAK
474pgm_no_vtime: 483pgm_no_vtime:
475 HANDLE_SIE_INTERCEPT
476 stg %r11,SP_ARGS(%r15) 484 stg %r11,SP_ARGS(%r15)
477 lgf %r3,__LC_PGM_ILC # load program interruption code 485 lgf %r3,__LC_PGM_ILC # load program interruption code
478 lg %r4,__LC_TRANS_EXC_CODE 486 lg %r4,__LC_TRANS_EXC_CODE
@@ -507,6 +515,7 @@ pgm_per_std:
507 CREATE_STACK_FRAME __LC_SAVE_AREA 515 CREATE_STACK_FRAME __LC_SAVE_AREA
508 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 516 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
509 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 517 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
518 HANDLE_SIE_INTERCEPT
510 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 519 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
511 jz pgm_no_vtime2 520 jz pgm_no_vtime2
512 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 521 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -514,7 +523,6 @@ pgm_per_std:
514 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 523 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
515 LAST_BREAK 524 LAST_BREAK
516pgm_no_vtime2: 525pgm_no_vtime2:
517 HANDLE_SIE_INTERCEPT
518 lg %r1,__TI_task(%r12) 526 lg %r1,__TI_task(%r12)
519 tm SP_PSW+1(%r15),0x01 # kernel per event ? 527 tm SP_PSW+1(%r15),0x01 # kernel per event ?
520 jz kernel_per 528 jz kernel_per
@@ -571,14 +579,14 @@ kernel_per:
571/* 579/*
572 * IO interrupt handler routine 580 * IO interrupt handler routine
573 */ 581 */
574 .globl io_int_handler 582ENTRY(io_int_handler)
575io_int_handler:
576 stck __LC_INT_CLOCK 583 stck __LC_INT_CLOCK
577 stpt __LC_ASYNC_ENTER_TIMER 584 stpt __LC_ASYNC_ENTER_TIMER
578 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 585 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40
579 CREATE_STACK_FRAME __LC_SAVE_AREA+40 586 CREATE_STACK_FRAME __LC_SAVE_AREA+40
580 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 587 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
581 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 588 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
589 HANDLE_SIE_INTERCEPT
582 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 590 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
583 jz io_no_vtime 591 jz io_no_vtime
584 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 592 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -586,7 +594,6 @@ io_int_handler:
586 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 594 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
587 LAST_BREAK 595 LAST_BREAK
588io_no_vtime: 596io_no_vtime:
589 HANDLE_SIE_INTERCEPT
590 TRACE_IRQS_OFF 597 TRACE_IRQS_OFF
591 la %r2,SP_PTREGS(%r15) # address of register-save area 598 la %r2,SP_PTREGS(%r15) # address of register-save area
592 brasl %r14,do_IRQ # call standard irq handler 599 brasl %r14,do_IRQ # call standard irq handler
@@ -706,14 +713,14 @@ io_notify_resume:
706/* 713/*
707 * External interrupt handler routine 714 * External interrupt handler routine
708 */ 715 */
709 .globl ext_int_handler 716ENTRY(ext_int_handler)
710ext_int_handler:
711 stck __LC_INT_CLOCK 717 stck __LC_INT_CLOCK
712 stpt __LC_ASYNC_ENTER_TIMER 718 stpt __LC_ASYNC_ENTER_TIMER
713 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 719 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40
714 CREATE_STACK_FRAME __LC_SAVE_AREA+40 720 CREATE_STACK_FRAME __LC_SAVE_AREA+40
715 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 721 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
716 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 722 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
723 HANDLE_SIE_INTERCEPT
717 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 724 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
718 jz ext_no_vtime 725 jz ext_no_vtime
719 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 726 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
@@ -721,7 +728,6 @@ ext_int_handler:
721 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 728 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
722 LAST_BREAK 729 LAST_BREAK
723ext_no_vtime: 730ext_no_vtime:
724 HANDLE_SIE_INTERCEPT
725 TRACE_IRQS_OFF 731 TRACE_IRQS_OFF
726 lghi %r1,4096 732 lghi %r1,4096
727 la %r2,SP_PTREGS(%r15) # address of register-save area 733 la %r2,SP_PTREGS(%r15) # address of register-save area
@@ -736,8 +742,7 @@ __critical_end:
736/* 742/*
737 * Machine check handler routines 743 * Machine check handler routines
738 */ 744 */
739 .globl mcck_int_handler 745ENTRY(mcck_int_handler)
740mcck_int_handler:
741 stck __LC_MCCK_CLOCK 746 stck __LC_MCCK_CLOCK
742 la %r1,4095 # revalidate r1 747 la %r1,4095 # revalidate r1
743 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 748 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
@@ -785,6 +790,7 @@ mcck_int_main:
785 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 790 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
786 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? 791 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
787 jno mcck_no_vtime # no -> no timer update 792 jno mcck_no_vtime # no -> no timer update
793 HANDLE_SIE_INTERCEPT
788 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 794 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
789 jz mcck_no_vtime 795 jz mcck_no_vtime
790 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER 796 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
@@ -804,7 +810,6 @@ mcck_no_vtime:
804 stosm __SF_EMPTY(%r15),0x04 # turn dat on 810 stosm __SF_EMPTY(%r15),0x04 # turn dat on
805 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING 811 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
806 jno mcck_return 812 jno mcck_return
807 HANDLE_SIE_INTERCEPT
808 TRACE_IRQS_OFF 813 TRACE_IRQS_OFF
809 brasl %r14,s390_handle_mcck 814 brasl %r14,s390_handle_mcck
810 TRACE_IRQS_ON 815 TRACE_IRQS_ON
@@ -823,8 +828,7 @@ mcck_done:
823 */ 828 */
824#ifdef CONFIG_SMP 829#ifdef CONFIG_SMP
825 __CPUINIT 830 __CPUINIT
826 .globl restart_int_handler 831ENTRY(restart_int_handler)
827restart_int_handler:
828 basr %r1,0 832 basr %r1,0
829restart_base: 833restart_base:
830 spt restart_vtime-restart_base(%r1) 834 spt restart_vtime-restart_base(%r1)
@@ -851,8 +855,7 @@ restart_vtime:
851/* 855/*
852 * If we do not run with SMP enabled, let the new CPU crash ... 856 * If we do not run with SMP enabled, let the new CPU crash ...
853 */ 857 */
854 .globl restart_int_handler 858ENTRY(restart_int_handler)
855restart_int_handler:
856 basr %r1,0 859 basr %r1,0
857restart_base: 860restart_base:
858 lpswe restart_crash-restart_base(%r1) 861 lpswe restart_crash-restart_base(%r1)
@@ -1036,6 +1039,56 @@ cleanup_io_restore_insn:
1036.Lcritical_end: 1039.Lcritical_end:
1037 .quad __critical_end 1040 .quad __critical_end
1038 1041
1042#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
1043/*
1044 * sie64a calling convention:
1045 * %r2 pointer to sie control block
1046 * %r3 guest register save area
1047 */
1048ENTRY(sie64a)
1049 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
1050 stg %r2,__SF_EMPTY(%r15) # save control block pointer
1051 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
1052 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
1053 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1054 oi __TI_flags+6(%r14),_TIF_SIE>>8
1055sie_loop:
1056 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1057 tm __TI_flags+7(%r14),_TIF_EXIT_SIE
1058 jnz sie_exit
1059 lg %r14,__SF_EMPTY(%r15) # get control block pointer
1060 SPP __SF_EMPTY(%r15) # set guest id
1061 sie 0(%r14)
1062sie_done:
1063 SPP __LC_CMF_HPP # set host id
1064 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1065sie_exit:
1066 ni __TI_flags+6(%r14),255-(_TIF_SIE>>8)
1067 lg %r14,__SF_EMPTY+8(%r15) # load guest register save area
1068 stmg %r0,%r13,0(%r14) # save guest gprs 0-13
1069 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
1070 lghi %r2,0
1071 br %r14
1072sie_fault:
1073 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1074 ni __TI_flags+6(%r14),255-(_TIF_SIE>>8)
1075 lg %r14,__SF_EMPTY+8(%r15) # load guest register save area
1076 stmg %r0,%r13,0(%r14) # save guest gprs 0-13
1077 lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
1078 lghi %r2,-EFAULT
1079 br %r14
1080
1081 .align 8
1082.Lsie_loop:
1083 .quad sie_loop
1084.Lsie_done:
1085 .quad sie_done
1086
1087 .section __ex_table,"a"
1088 .quad sie_loop,sie_fault
1089 .previous
1090#endif
1091
1039 .section .rodata, "a" 1092 .section .rodata, "a"
1040#define SYSCALL(esa,esame,emu) .long esame 1093#define SYSCALL(esa,esame,emu) .long esame
1041 .globl sys_call_table 1094 .globl sys_call_table