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.S139
1 files changed, 80 insertions, 59 deletions
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 412a7b8783d..4e1c292fa7e 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -2,7 +2,7 @@
2 * arch/s390/kernel/entry64.S 2 * arch/s390/kernel/entry64.S
3 * S390 low-level entry points. 3 * S390 low-level entry points.
4 * 4 *
5 * Copyright (C) IBM Corp. 1999,2010 5 * Copyright (C) IBM Corp. 1999,2012
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
7 * Hartmut Penner (hp@de.ibm.com), 7 * Hartmut Penner (hp@de.ibm.com),
8 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), 8 * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com),
@@ -489,7 +489,6 @@ io_restore:
489 lg %r14,__LC_VDSO_PER_CPU 489 lg %r14,__LC_VDSO_PER_CPU
490 lmg %r0,%r10,__PT_R0(%r11) 490 lmg %r0,%r10,__PT_R0(%r11)
491 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11) 491 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
492 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
493 stpt __LC_EXIT_TIMER 492 stpt __LC_EXIT_TIMER
494 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 493 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
495 lmg %r11,%r15,__PT_R11(%r11) 494 lmg %r11,%r15,__PT_R11(%r11)
@@ -625,12 +624,30 @@ ext_skip:
625 TRACE_IRQS_OFF 624 TRACE_IRQS_OFF
626 lghi %r1,4096 625 lghi %r1,4096
627 lgr %r2,%r11 # pass pointer to pt_regs 626 lgr %r2,%r11 # pass pointer to pt_regs
628 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 627 llgf %r3,__LC_EXT_CPU_ADDR # get cpu address + interruption code
629 llgf %r4,__LC_EXT_PARAMS # get external parameter 628 llgf %r4,__LC_EXT_PARAMS # get external parameter
630 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter 629 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
631 brasl %r14,do_extint 630 brasl %r14,do_extint
632 j io_return 631 j io_return
633 632
633/*
634 * Load idle PSW. The second "half" of this function is in cleanup_idle.
635 */
636ENTRY(psw_idle)
637 stg %r4,__SF_EMPTY(%r15)
638 larl %r1,psw_idle_lpsw+4
639 stg %r1,__SF_EMPTY+8(%r15)
640 larl %r1,.Lvtimer_max
641 stck __IDLE_ENTER(%r2)
642 ltr %r5,%r5
643 stpt __VQ_IDLE_ENTER(%r3)
644 jz psw_idle_lpsw
645 spt 0(%r1)
646psw_idle_lpsw:
647 lpswe __SF_EMPTY(%r15)
648 br %r14
649psw_idle_end:
650
634__critical_end: 651__critical_end:
635 652
636/* 653/*
@@ -696,7 +713,6 @@ mcck_return:
696 lg %r14,__LC_VDSO_PER_CPU 713 lg %r14,__LC_VDSO_PER_CPU
697 lmg %r0,%r10,__PT_R0(%r11) 714 lmg %r0,%r10,__PT_R0(%r11)
698 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW 715 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
699 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
700 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 716 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
701 jno 0f 717 jno 0f
702 stpt __LC_EXIT_TIMER 718 stpt __LC_EXIT_TIMER
@@ -713,68 +729,30 @@ mcck_panic:
7130: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE) 7290: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
714 j mcck_skip 730 j mcck_skip
715 731
716/*
717 * Restart interruption handler, kick starter for additional CPUs
718 */
719#ifdef CONFIG_SMP
720 __CPUINIT
721ENTRY(restart_int_handler)
722 basr %r1,0
723restart_base:
724 spt restart_vtime-restart_base(%r1)
725 stck __LC_LAST_UPDATE_CLOCK
726 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
727 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
728 lghi %r10,__LC_GPREGS_SAVE_AREA
729 lg %r15,120(%r10) # load ksp
730 lghi %r10,__LC_CREGS_SAVE_AREA
731 lctlg %c0,%c15,0(%r10) # get new ctl regs
732 lghi %r10,__LC_AREGS_SAVE_AREA
733 lam %a0,%a15,0(%r10)
734 lmg %r6,%r15,__SF_GPRS(%r15)# load registers from clone
735 lg %r1,__LC_THREAD_INFO
736 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
737 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
738 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
739 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
740 brasl %r14,start_secondary
741 .align 8
742restart_vtime:
743 .long 0x7fffffff,0xffffffff
744 .previous
745#else
746/*
747 * If we do not run with SMP enabled, let the new CPU crash ...
748 */
749ENTRY(restart_int_handler)
750 basr %r1,0
751restart_base:
752 lpswe restart_crash-restart_base(%r1)
753 .align 8
754restart_crash:
755 .long 0x000a0000,0x00000000,0x00000000,0x00000000
756restart_go:
757#endif
758
759# 732#
760# PSW restart interrupt handler 733# PSW restart interrupt handler
761# 734#
762ENTRY(psw_restart_int_handler) 735ENTRY(restart_int_handler)
763 stg %r15,__LC_SAVE_AREA_RESTART 736 stg %r15,__LC_SAVE_AREA_RESTART
764 larl %r15,restart_stack # load restart stack 737 lg %r15,__LC_RESTART_STACK
765 lg %r15,0(%r15)
766 aghi %r15,-__PT_SIZE # create pt_regs on stack 738 aghi %r15,-__PT_SIZE # create pt_regs on stack
739 xc 0(__PT_SIZE,%r15),0(%r15)
767 stmg %r0,%r14,__PT_R0(%r15) 740 stmg %r0,%r14,__PT_R0(%r15)
768 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART 741 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
769 mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw 742 mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
770 aghi %r15,-STACK_FRAME_OVERHEAD 743 aghi %r15,-STACK_FRAME_OVERHEAD # create stack frame on stack
771 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 744 xc 0(STACK_FRAME_OVERHEAD,%r15),0(%r15)
772 brasl %r14,do_restart 745 lmg %r1,%r3,__LC_RESTART_FN # load fn, parm & source cpu
773 larl %r14,restart_psw_crash # load disabled wait PSW if 746 ltgr %r3,%r3 # test source cpu address
774 lpswe 0(%r14) # do_restart returns 747 jm 1f # negative -> skip source stop
775 .align 8 7480: sigp %r4,%r3,1 # sigp sense to source cpu
776restart_psw_crash: 749 brc 10,0b # wait for status stored
777 .quad 0x0002000080000000,0x0000000000000000 + restart_psw_crash 7501: basr %r14,%r1 # call function
751 stap __SF_EMPTY(%r15) # store cpu address
752 llgh %r3,__SF_EMPTY(%r15)
7532: sigp %r4,%r3,5 # sigp stop to current cpu
754 brc 2,2b
7553: j 3b
778 756
779 .section .kprobes.text, "ax" 757 .section .kprobes.text, "ax"
780 758
@@ -808,6 +786,8 @@ cleanup_table:
808 .quad io_tif 786 .quad io_tif
809 .quad io_restore 787 .quad io_restore
810 .quad io_done 788 .quad io_done
789 .quad psw_idle
790 .quad psw_idle_end
811 791
812cleanup_critical: 792cleanup_critical:
813 clg %r9,BASED(cleanup_table) # system_call 793 clg %r9,BASED(cleanup_table) # system_call
@@ -826,6 +806,10 @@ cleanup_critical:
826 jl cleanup_io_tif 806 jl cleanup_io_tif
827 clg %r9,BASED(cleanup_table+56) # io_done 807 clg %r9,BASED(cleanup_table+56) # io_done
828 jl cleanup_io_restore 808 jl cleanup_io_restore
809 clg %r9,BASED(cleanup_table+64) # psw_idle
810 jl 0f
811 clg %r9,BASED(cleanup_table+72) # psw_idle_end
812 jl cleanup_idle
8290: br %r14 8130: br %r14
830 814
831 815
@@ -915,7 +899,6 @@ cleanup_io_restore:
915 je 0f 899 je 0f
916 lg %r9,24(%r11) # get saved r11 pointer to pt_regs 900 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
917 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9) 901 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
918 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
919 mvc 0(64,%r11),__PT_R8(%r9) 902 mvc 0(64,%r11),__PT_R8(%r9)
920 lmg %r0,%r7,__PT_R0(%r9) 903 lmg %r0,%r7,__PT_R0(%r9)
9210: lmg %r8,%r9,__LC_RETURN_PSW 9040: lmg %r8,%r9,__LC_RETURN_PSW
@@ -923,6 +906,42 @@ cleanup_io_restore:
923cleanup_io_restore_insn: 906cleanup_io_restore_insn:
924 .quad io_done - 4 907 .quad io_done - 4
925 908
909cleanup_idle:
910 # copy interrupt clock & cpu timer
911 mvc __IDLE_EXIT(8,%r2),__LC_INT_CLOCK
912 mvc __VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER
913 cghi %r11,__LC_SAVE_AREA_ASYNC
914 je 0f
915 mvc __IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
916 mvc __VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER
9170: # check if stck & stpt have been executed
918 clg %r9,BASED(cleanup_idle_insn)
919 jhe 1f
920 mvc __IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2)
921 mvc __VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3)
922 j 2f
9231: # check if the cpu timer has been reprogrammed
924 ltr %r5,%r5
925 jz 2f
926 spt __VQ_IDLE_ENTER(%r3)
9272: # account system time going idle
928 lg %r9,__LC_STEAL_TIMER
929 alg %r9,__IDLE_ENTER(%r2)
930 slg %r9,__LC_LAST_UPDATE_CLOCK
931 stg %r9,__LC_STEAL_TIMER
932 mvc __LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2)
933 lg %r9,__LC_SYSTEM_TIMER
934 alg %r9,__LC_LAST_UPDATE_TIMER
935 slg %r9,__VQ_IDLE_ENTER(%r3)
936 stg %r9,__LC_SYSTEM_TIMER
937 mvc __LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3)
938 # prepare return psw
939 nihh %r8,0xfffd # clear wait state bit
940 lg %r9,48(%r11) # return from psw_idle
941 br %r14
942cleanup_idle_insn:
943 .quad psw_idle_lpsw
944
926/* 945/*
927 * Integer constants 946 * Integer constants
928 */ 947 */
@@ -931,6 +950,8 @@ cleanup_io_restore_insn:
931 .quad __critical_start 950 .quad __critical_start
932.Lcritical_length: 951.Lcritical_length:
933 .quad __critical_end - __critical_start 952 .quad __critical_end - __critical_start
953.Lvtimer_max:
954 .quad 0x7fffffffffffffff
934 955
935 956
936#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 957#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)