aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/entry.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r--arch/s390/kernel/entry.S102
1 files changed, 93 insertions, 9 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index c0e09b33febe..5b262b5d869f 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.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>
@@ -49,9 +50,9 @@ SP_ILC = STACK_FRAME_OVERHEAD + __PT_ILC
49SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP 50SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
50SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE 51SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
51 52
52_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \ 53_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING | \
53 _TIF_RESTART_SVC | _TIF_SINGLE_STEP ) 54 _TIF_RESTART_SVC | _TIF_SINGLE_STEP )
54_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED) 55_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
55 56
56STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 57STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
57STACK_SIZE = 1 << STACK_SHIFT 58STACK_SIZE = 1 << STACK_SHIFT
@@ -121,7 +122,11 @@ STACK_SIZE = 1 << STACK_SHIFT
121 bz BASED(stack_overflow) 122 bz BASED(stack_overflow)
1223: 1233:
123#endif 124#endif
1242: s %r15,BASED(.Lc_spsize) # make room for registers & psw 1252:
126 .endm
127
128 .macro CREATE_STACK_FRAME psworg,savearea
129 s %r15,BASED(.Lc_spsize) # make room for registers & psw
125 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 130 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack
126 la %r12,\psworg 131 la %r12,\psworg
127 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 132 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
@@ -161,6 +166,13 @@ __switch_to_base:
161 be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's 166 be __switch_to_noper-__switch_to_base(%r1) # we got away w/o bashing TLB's
162 lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't 167 lctl %c9,%c11,__THREAD_per(%r3) # Nope we didn't
163__switch_to_noper: 168__switch_to_noper:
169 l %r4,__THREAD_info(%r2) # get thread_info of prev
170 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
171 bz __switch_to_no_mcck-__switch_to_base(%r1)
172 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
173 l %r4,__THREAD_info(%r3) # get thread_info of next
174 oi __TI_flags+3(%r4),_TIF_MCCK_PENDING # set it in next
175__switch_to_no_mcck:
164 stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task 176 stm %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
165 st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp 177 st %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp
166 l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp 178 l %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp
@@ -185,6 +197,7 @@ system_call:
185sysc_saveall: 197sysc_saveall:
186 SAVE_ALL_BASE __LC_SAVE_AREA 198 SAVE_ALL_BASE __LC_SAVE_AREA
187 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 199 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
200 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
188 lh %r7,0x8a # get svc number from lowcore 201 lh %r7,0x8a # get svc number from lowcore
189#ifdef CONFIG_VIRT_CPU_ACCOUNTING 202#ifdef CONFIG_VIRT_CPU_ACCOUNTING
190sysc_vtime: 203sysc_vtime:
@@ -234,6 +247,8 @@ sysc_work_loop:
234# One of the work bits is on. Find out which one. 247# One of the work bits is on. Find out which one.
235# 248#
236sysc_work: 249sysc_work:
250 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
251 bo BASED(sysc_mcck_pending)
237 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 252 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
238 bo BASED(sysc_reschedule) 253 bo BASED(sysc_reschedule)
239 tm __TI_flags+3(%r9),_TIF_SIGPENDING 254 tm __TI_flags+3(%r9),_TIF_SIGPENDING
@@ -253,6 +268,14 @@ sysc_reschedule:
253 br %r1 # call scheduler 268 br %r1 # call scheduler
254 269
255# 270#
271# _TIF_MCCK_PENDING is set, call handler
272#
273sysc_mcck_pending:
274 l %r1,BASED(.Ls390_handle_mcck)
275 la %r14,BASED(sysc_work_loop)
276 br %r1 # TIF bit will be cleared by handler
277
278#
256# _TIF_SIGPENDING is set, call do_signal 279# _TIF_SIGPENDING is set, call do_signal
257# 280#
258sysc_sigpending: 281sysc_sigpending:
@@ -430,6 +453,7 @@ pgm_check_handler:
430 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 453 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
431 bnz BASED(pgm_per) # got per exception -> special case 454 bnz BASED(pgm_per) # got per exception -> special case
432 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 455 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
456 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
433#ifdef CONFIG_VIRT_CPU_ACCOUNTING 457#ifdef CONFIG_VIRT_CPU_ACCOUNTING
434 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 458 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
435 bz BASED(pgm_no_vtime) 459 bz BASED(pgm_no_vtime)
@@ -468,6 +492,7 @@ pgm_per:
468# 492#
469pgm_per_std: 493pgm_per_std:
470 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 494 SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
495 CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA
471#ifdef CONFIG_VIRT_CPU_ACCOUNTING 496#ifdef CONFIG_VIRT_CPU_ACCOUNTING
472 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 497 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
473 bz BASED(pgm_no_vtime2) 498 bz BASED(pgm_no_vtime2)
@@ -493,6 +518,7 @@ pgm_no_vtime2:
493# 518#
494pgm_svcper: 519pgm_svcper:
495 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 520 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
521 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
496#ifdef CONFIG_VIRT_CPU_ACCOUNTING 522#ifdef CONFIG_VIRT_CPU_ACCOUNTING
497 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 523 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
498 bz BASED(pgm_no_vtime3) 524 bz BASED(pgm_no_vtime3)
@@ -521,6 +547,7 @@ io_int_handler:
521 stck __LC_INT_CLOCK 547 stck __LC_INT_CLOCK
522 SAVE_ALL_BASE __LC_SAVE_AREA+16 548 SAVE_ALL_BASE __LC_SAVE_AREA+16
523 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 549 SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
550 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16
524#ifdef CONFIG_VIRT_CPU_ACCOUNTING 551#ifdef CONFIG_VIRT_CPU_ACCOUNTING
525 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 552 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
526 bz BASED(io_no_vtime) 553 bz BASED(io_no_vtime)
@@ -578,9 +605,11 @@ io_work:
578 lr %r15,%r1 605 lr %r15,%r1
579# 606#
580# One of the work bits is on. Find out which one. 607# One of the work bits is on. Find out which one.
581# Checked are: _TIF_SIGPENDING and _TIF_NEED_RESCHED 608# Checked are: _TIF_SIGPENDING, _TIF_NEED_RESCHED and _TIF_MCCK_PENDING
582# 609#
583io_work_loop: 610io_work_loop:
611 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
612 bo BASED(io_mcck_pending)
584 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED 613 tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
585 bo BASED(io_reschedule) 614 bo BASED(io_reschedule)
586 tm __TI_flags+3(%r9),_TIF_SIGPENDING 615 tm __TI_flags+3(%r9),_TIF_SIGPENDING
@@ -588,6 +617,14 @@ io_work_loop:
588 b BASED(io_leave) 617 b BASED(io_leave)
589 618
590# 619#
620# _TIF_MCCK_PENDING is set, call handler
621#
622io_mcck_pending:
623 l %r1,BASED(.Ls390_handle_mcck)
624 l %r14,BASED(io_work_loop)
625 br %r1 # TIF bit will be cleared by handler
626
627#
591# _TIF_NEED_RESCHED is set, call schedule 628# _TIF_NEED_RESCHED is set, call schedule
592# 629#
593io_reschedule: 630io_reschedule:
@@ -621,6 +658,7 @@ ext_int_handler:
621 stck __LC_INT_CLOCK 658 stck __LC_INT_CLOCK
622 SAVE_ALL_BASE __LC_SAVE_AREA+16 659 SAVE_ALL_BASE __LC_SAVE_AREA+16
623 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 660 SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
661 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16
624#ifdef CONFIG_VIRT_CPU_ACCOUNTING 662#ifdef CONFIG_VIRT_CPU_ACCOUNTING
625 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 663 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
626 bz BASED(ext_no_vtime) 664 bz BASED(ext_no_vtime)
@@ -642,19 +680,62 @@ ext_no_vtime:
642 680
643 .globl mcck_int_handler 681 .globl mcck_int_handler
644mcck_int_handler: 682mcck_int_handler:
645 STORE_TIMER __LC_ASYNC_ENTER_TIMER 683 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
684 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
646 SAVE_ALL_BASE __LC_SAVE_AREA+32 685 SAVE_ALL_BASE __LC_SAVE_AREA+32
647 SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0 686 la %r12,__LC_MCK_OLD_PSW
687 tm __LC_MCCK_CODE,0x80 # system damage?
688 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid
689 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
690 bo BASED(0f)
691 spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer
648#ifdef CONFIG_VIRT_CPU_ACCOUNTING 692#ifdef CONFIG_VIRT_CPU_ACCOUNTING
649 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 693 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
694 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
695 mvc __LC_LAST_UPDATE_TIMER(8),__LC_EXIT_TIMER
6960: tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
697 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
698 tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ?
650 bz BASED(mcck_no_vtime) 699 bz BASED(mcck_no_vtime)
651 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 700 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
652 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 701 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
653 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 702 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
654mcck_no_vtime: 703mcck_no_vtime:
655#endif 704#endif
7050:
706 tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
707 bno BASED(mcck_int_main) # no -> skip cleanup critical
708 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit
709 bnz BASED(mcck_int_main) # from user -> load async stack
710 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end)
711 bhe BASED(mcck_int_main)
712 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start)
713 bl BASED(mcck_int_main)
714 l %r14,BASED(.Lcleanup_critical)
715 basr %r14,%r14
716mcck_int_main:
717 l %r14,__LC_PANIC_STACK # are we already on the panic stack?
718 slr %r14,%r15
719 sra %r14,PAGE_SHIFT
720 be BASED(0f)
721 l %r15,__LC_PANIC_STACK # load panic stack
7220: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32
723 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
724 la %r2,SP_PTREGS(%r15) # load pt_regs
656 l %r1,BASED(.Ls390_mcck) 725 l %r1,BASED(.Ls390_mcck)
657 basr %r14,%r1 # call machine check handler 726 basr %r14,%r1 # call machine check handler
727 tm SP_PSW+1(%r15),0x01 # returning to user ?
728 bno BASED(mcck_return)
729 l %r1,__LC_KERNEL_STACK # switch to kernel stack
730 s %r1,BASED(.Lc_spsize)
731 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
732 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain
733 lr %r15,%r1
734 stosm __SF_EMPTY(%r15),0x04 # turn dat on
735 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
736 bno BASED(mcck_return)
737 l %r1,BASED(.Ls390_handle_mcck)
738 basr %r14,%r1 # call machine check handler
658mcck_return: 739mcck_return:
659 RESTORE_ALL 0 740 RESTORE_ALL 0
660 741
@@ -742,7 +823,7 @@ cleanup_critical:
742 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop) 823 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop)
743 bl BASED(0f) 824 bl BASED(0f)
744 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) 825 clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4)
745 bl BASED(cleanup_sysc_leave) 826 bl BASED(cleanup_sysc_return)
7460: 8270:
747 br %r14 828 br %r14
748 829
@@ -760,6 +841,7 @@ cleanup_system_call:
760 mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16 841 mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16
7610: st %r13,__LC_SAVE_AREA+20 8420: st %r13,__LC_SAVE_AREA+20
762 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 843 SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
844 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
763 st %r15,__LC_SAVE_AREA+28 845 st %r15,__LC_SAVE_AREA+28
764 lh %r7,0x8a 846 lh %r7,0x8a
765#ifdef CONFIG_VIRT_CPU_ACCOUNTING 847#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -834,6 +916,8 @@ cleanup_sysc_leave_insn:
834 * Symbol constants 916 * Symbol constants
835 */ 917 */
836.Ls390_mcck: .long s390_do_machine_check 918.Ls390_mcck: .long s390_do_machine_check
919.Ls390_handle_mcck:
920 .long s390_handle_mcck
837.Ldo_IRQ: .long do_IRQ 921.Ldo_IRQ: .long do_IRQ
838.Ldo_extint: .long do_extint 922.Ldo_extint: .long do_extint
839.Ldo_signal: .long do_signal 923.Ldo_signal: .long do_signal