diff options
-rw-r--r-- | arch/s390/kernel/entry.S | 212 |
1 files changed, 109 insertions, 103 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 68d1a02..af8bd3b 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -9,7 +9,6 @@ * Heiko Carstens <heiko.carstens@de.ibm.com> */ -#include <linux/sys.h> #include <linux/linkage.h> #include <linux/init.h> #include <asm/cache.h> @@ -110,31 +109,36 @@ STACK_SIZE = 1 << STACK_SHIFT 1: stm %r10,%r11,\lc_sum .endm - .macro SAVE_ALL_BASE savearea + .macro SAVE_ALL_SVC psworg,savearea stm %r12,%r15,\savearea l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 + l %r15,__LC_KERNEL_STACK # problem state -> load ksp + s %r15,BASED(.Lc_spsize) # make room for registers & psw .endm - .macro SAVE_ALL_SVC psworg,savearea - la %r12,\psworg - l %r15,__LC_KERNEL_STACK # problem state -> load ksp + .macro SAVE_ALL_BASE savearea + stm %r12,%r15,\savearea + l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 .endm - .macro SAVE_ALL_SYNC psworg,savearea - la %r12,\psworg + .macro SAVE_ALL_PGM psworg,savearea tm \psworg+1,0x01 # test problem state bit - bz BASED(2f) # skip stack setup save - l %r15,__LC_KERNEL_STACK # problem state -> load ksp #ifdef CONFIG_CHECK_STACK - b BASED(3f) -2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD - bz BASED(stack_overflow) -3: + bnz BASED(1f) + tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + bnz BASED(2f) + la %r12,\psworg + b BASED(stack_overflow) +#else + bz BASED(2f) #endif -2: +1: l %r15,__LC_KERNEL_STACK # problem state -> load ksp +2: s %r15,BASED(.Lc_spsize) # make room for registers & psw .endm .macro SAVE_ALL_ASYNC psworg,savearea + stm %r12,%r15,\savearea + l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 la %r12,\psworg tm \psworg+1,0x01 # test problem state bit bnz BASED(1f) # from user -> load async stack @@ -149,27 +153,23 @@ STACK_SIZE = 1 << STACK_SHIFT 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? slr %r14,%r15 sra %r14,STACK_SHIFT - be BASED(2f) -1: l %r15,__LC_ASYNC_STACK #ifdef CONFIG_CHECK_STACK - b BASED(3f) -2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD - bz BASED(stack_overflow) -3: + bnz BASED(1f) + tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + bnz BASED(2f) + b BASED(stack_overflow) +#else + bz BASED(2f) #endif -2: +1: l %r15,__LC_ASYNC_STACK +2: s %r15,BASED(.Lc_spsize) # make room for registers & psw .endm - .macro CREATE_STACK_FRAME psworg,savearea - s %r15,BASED(.Lc_spsize) # make room for registers & psw - mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack + .macro CREATE_STACK_FRAME savearea + xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 - icm %r12,12,__LC_SVC_ILC - stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack - st %r12,SP_ILC(%r15) mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack - la %r12,0 - st %r12,__SF_BACKCHAIN(%r15) # clear back chain + stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack .endm .macro RESTORE_ALL psworg,sync @@ -237,10 +237,11 @@ __critical_start: system_call: stpt __LC_SYNC_ENTER_TIMER sysc_saveall: - SAVE_ALL_BASE __LC_SAVE_AREA SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA - lh %r7,0x8a # get svc number from lowcore + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW + mvc SP_ILC(4,%r15),__LC_SVC_ILC + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct sysc_vtime: UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER sysc_stime: @@ -248,20 +249,20 @@ sysc_stime: sysc_update: mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER sysc_do_svc: - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - ltr %r7,%r7 # test for svc 0 + xr %r7,%r7 + icm %r7,3,SP_SVCNR(%r15) # load svc number and test for svc 0 bnz BASED(sysc_nr_ok) # svc number > 0 # svc 0: system call number in %r1 cl %r1,BASED(.Lnr_syscalls) bnl BASED(sysc_nr_ok) + sth %r1,SP_SVCNR(%r15) lr %r7,%r1 # copy svc number to %r7 sysc_nr_ok: - sth %r7,SP_SVCNR(%r15) sll %r7,2 # svc number *4 - l %r8,BASED(.Lsysc_table) - tm __TI_flags+2(%r9),_TIF_SYSCALL + l %r10,BASED(.Lsysc_table) + tm __TI_flags+2(%r12),_TIF_SYSCALL mvc SP_ARGS(4,%r15),SP_R7(%r15) - l %r8,0(%r7,%r8) # get system call addr. + l %r8,0(%r7,%r10) # get system call addr. bnz BASED(sysc_tracesys) basr %r14,%r8 # call sys_xxxx st %r2,SP_R2(%r15) # store return value (change R2 on stack) @@ -269,7 +270,7 @@ sysc_nr_ok: sysc_return: LOCKDEP_SYS_EXIT sysc_tif: - tm __TI_flags+3(%r9),_TIF_WORK_SVC + tm __TI_flags+3(%r12),_TIF_WORK_SVC bnz BASED(sysc_work) # there is work to do (signals etc.) sysc_restore: RESTORE_ALL __LC_RETURN_PSW,1 @@ -286,17 +287,17 @@ sysc_work: # One of the work bits is on. Find out which one. # sysc_work_tif: - tm __TI_flags+3(%r9),_TIF_MCCK_PENDING + tm __TI_flags+3(%r12),_TIF_MCCK_PENDING bo BASED(sysc_mcck_pending) - tm __TI_flags+3(%r9),_TIF_NEED_RESCHED + tm __TI_flags+3(%r12),_TIF_NEED_RESCHED bo BASED(sysc_reschedule) - tm __TI_flags+3(%r9),_TIF_SIGPENDING + tm __TI_flags+3(%r12),_TIF_SIGPENDING bo BASED(sysc_sigpending) - tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME + tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME bo BASED(sysc_notify_resume) - tm __TI_flags+3(%r9),_TIF_RESTART_SVC + tm __TI_flags+3(%r12),_TIF_RESTART_SVC bo BASED(sysc_restart) - tm __TI_flags+3(%r9),_TIF_SINGLE_STEP + tm __TI_flags+3(%r12),_TIF_SINGLE_STEP bo BASED(sysc_singlestep) b BASED(sysc_return) # beware of critical section cleanup @@ -320,13 +321,13 @@ sysc_mcck_pending: # _TIF_SIGPENDING is set, call do_signal # sysc_sigpending: - ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP + ni __TI_flags+3(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP la %r2,SP_PTREGS(%r15) # load pt_regs l %r1,BASED(.Ldo_signal) basr %r14,%r1 # call do_signal - tm __TI_flags+3(%r9),_TIF_RESTART_SVC + tm __TI_flags+3(%r12),_TIF_RESTART_SVC bo BASED(sysc_restart) - tm __TI_flags+3(%r9),_TIF_SINGLE_STEP + tm __TI_flags+3(%r12),_TIF_SINGLE_STEP bo BASED(sysc_singlestep) b BASED(sysc_return) @@ -344,19 +345,19 @@ sysc_notify_resume: # _TIF_RESTART_SVC is set, set up registers and restart svc # sysc_restart: - ni __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC + ni __TI_flags+3(%r12),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC l %r7,SP_R2(%r15) # load new svc number mvc SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument lm %r2,%r6,SP_R2(%r15) # load svc arguments + sth %r7,SP_SVCNR(%r15) b BASED(sysc_nr_ok) # restart svc # # _TIF_SINGLE_STEP is set, call do_single_step # sysc_singlestep: - ni __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP - mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check - mvi SP_SVCNR+1(%r15),0xff + ni __TI_flags+3(%r12),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP + xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number la %r2,SP_PTREGS(%r15) # address of register-save area l %r1,BASED(.Lhandle_per) # load adr. of per handler la %r14,BASED(sysc_return) # load adr. of system return @@ -370,15 +371,15 @@ sysc_tracesys: l %r1,BASED(.Ltrace_entry) la %r2,SP_PTREGS(%r15) # load pt_regs la %r3,0 - srl %r7,2 - st %r7,SP_R2(%r15) + xr %r0,%r0 + icm %r0,3,SP_SVCNR(%r15) + st %r0,SP_R2(%r15) basr %r14,%r1 cl %r2,BASED(.Lnr_syscalls) bnl BASED(sysc_tracenogo) - l %r8,BASED(.Lsysc_table) lr %r7,%r2 sll %r7,2 # svc number *4 - l %r8,0(%r7,%r8) + l %r8,0(%r7,%r10) sysc_tracego: lm %r3,%r6,SP_R3(%r15) mvc SP_ARGS(4,%r15),SP_R7(%r15) @@ -386,7 +387,7 @@ sysc_tracego: basr %r14,%r8 # call sys_xxx st %r2,SP_R2(%r15) # store return value sysc_tracenogo: - tm __TI_flags+2(%r9),_TIF_SYSCALL + tm __TI_flags+2(%r12),_TIF_SYSCALL bz BASED(sysc_return) l %r1,BASED(.Ltrace_exit) la %r2,SP_PTREGS(%r15) # load pt_regs @@ -399,7 +400,7 @@ sysc_tracenogo: .globl ret_from_fork ret_from_fork: l %r13,__LC_SVC_NEW_PSW+4 - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? bo BASED(0f) st %r15,SP_R15(%r15) # store stack pointer for new kthread @@ -434,8 +435,8 @@ kernel_execve: 0: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts l %r15,__LC_KERNEL_STACK # load ksp s %r15,BASED(.Lc_spsize) # make room for registers & psw - l %r9,__LC_THREAD_INFO mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs + l %r12,__LC_THREAD_INFO xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) stosm __SF_EMPTY(%r15),0x03 # reenable interrupts l %r1,BASED(.Lexecve_tail) @@ -465,26 +466,27 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception bnz BASED(pgm_per) # got per exception -> special case - SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA + CREATE_STACK_FRAME __LC_SAVE_AREA + xc SP_ILC(4,%r15),SP_ILC(%r15) + mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(pgm_no_vtime) UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime: - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct l %r3,__LC_PGM_ILC # load program interruption code l %r4,__LC_TRANS_EXC_CODE REENABLE_IRQS la %r8,0x7f nr %r8,%r3 -pgm_do_call: - l %r7,BASED(.Ljump_table) sll %r8,2 - l %r7,0(%r8,%r7) # load address of handler routine + l %r1,BASED(.Ljump_table) + l %r1,0(%r8,%r1) # load address of handler routine la %r2,SP_PTREGS(%r15) # address of register-save area - basr %r14,%r7 # branch to interrupt-handler + basr %r14,%r1 # branch to interrupt-handler pgm_exit: b BASED(sysc_return) @@ -505,33 +507,34 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(pgm_no_vtime2) UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER pgm_no_vtime2: - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - l %r1,__TI_task(%r9) + l %r1,__TI_task(%r12) tm SP_PSW+1(%r15),0x01 # kernel per event ? bz BASED(kernel_per) mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID - oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP + oi __TI_flags+3(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP l %r3,__LC_PGM_ILC # load program interruption code l %r4,__LC_TRANS_EXC_CODE REENABLE_IRQS la %r8,0x7f nr %r8,%r3 # clear per-event-bit and ilc be BASED(pgm_exit2) # only per or per+check ? - l %r7,BASED(.Ljump_table) sll %r8,2 - l %r7,0(%r8,%r7) # load address of handler routine + l %r1,BASED(.Ljump_table) + l %r1,0(%r8,%r1) # load address of handler routine la %r2,SP_PTREGS(%r15) # address of register-save area - basr %r14,%r7 # branch to interrupt-handler + basr %r14,%r1 # branch to interrupt-handler pgm_exit2: b BASED(sysc_return) @@ -539,18 +542,19 @@ pgm_exit2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA + SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW + mvc SP_ILC(4,%r15),__LC_SVC_ILC + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER - lh %r7,0x8a # get svc number from lowcore - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct - l %r8,__TI_task(%r9) + l %r8,__TI_task(%r12) mvc __THREAD_per+__PER_atmid(2,%r8),__LC_PER_ATMID mvc __THREAD_per+__PER_address(4,%r8),__LC_PER_ADDRESS mvc __THREAD_per+__PER_access_id(1,%r8),__LC_PER_ACCESS_ID - oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP + oi __TI_flags+3(%r12),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP stosm __SF_EMPTY(%r15),0x03 # reenable interrupts lm %r2,%r6,SP_R2(%r15) # load svc arguments b BASED(sysc_do_svc) @@ -560,8 +564,7 @@ pgm_svcper: # kernel_per: REENABLE_IRQS - mvi SP_SVCNR(%r15),0xff # set trap indication to pgm check - mvi SP_SVCNR+1(%r15),0xff + xc SP_SVCNR(2,%r15),SP_SVCNR(%r15) la %r2,SP_PTREGS(%r15) # address of register-save area l %r1,BASED(.Lhandle_per) # load adr. of per handler basr %r14,%r1 # branch to do_single_step @@ -575,9 +578,10 @@ kernel_per: io_int_handler: stck __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER - SAVE_ALL_BASE __LC_SAVE_AREA+16 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 - CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 + CREATE_STACK_FRAME __LC_SAVE_AREA+16 + mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(io_no_vtime) UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER @@ -585,7 +589,6 @@ io_int_handler: mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER io_no_vtime: TRACE_IRQS_OFF - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ la %r2,SP_PTREGS(%r15) # address of register-save area basr %r14,%r1 # branch to standard irq handler @@ -593,7 +596,7 @@ io_return: LOCKDEP_SYS_EXIT TRACE_IRQS_ON io_tif: - tm __TI_flags+3(%r9),_TIF_WORK_INT + tm __TI_flags+3(%r12),_TIF_WORK_INT bnz BASED(io_work) # there is work to do (signals etc.) io_restore: RESTORE_ALL __LC_RETURN_PSW,0 @@ -611,9 +614,9 @@ io_work: bo BASED(io_work_user) # yes -> do resched & signal #ifdef CONFIG_PREEMPT # check for preemptive scheduling - icm %r0,15,__TI_precount(%r9) + icm %r0,15,__TI_precount(%r12) bnz BASED(io_restore) # preemption disabled - tm __TI_flags+3(%r9),_TIF_NEED_RESCHED + tm __TI_flags+3(%r12),_TIF_NEED_RESCHED bno BASED(io_restore) # switch to kernel stack l %r1,SP_R15(%r15) @@ -647,13 +650,13 @@ io_work_user: # and _TIF_MCCK_PENDING # io_work_tif: - tm __TI_flags+3(%r9),_TIF_MCCK_PENDING + tm __TI_flags+3(%r12),_TIF_MCCK_PENDING bo BASED(io_mcck_pending) - tm __TI_flags+3(%r9),_TIF_NEED_RESCHED + tm __TI_flags+3(%r12),_TIF_NEED_RESCHED bo BASED(io_reschedule) - tm __TI_flags+3(%r9),_TIF_SIGPENDING + tm __TI_flags+3(%r12),_TIF_SIGPENDING bo BASED(io_sigpending) - tm __TI_flags+3(%r9),_TIF_NOTIFY_RESUME + tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME bo BASED(io_notify_resume) b BASED(io_return) # beware of critical section cleanup @@ -713,16 +716,16 @@ io_notify_resume: ext_int_handler: stck __LC_INT_CLOCK stpt __LC_ASYNC_ENTER_TIMER - SAVE_ALL_BASE __LC_SAVE_AREA+16 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 - CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 + CREATE_STACK_FRAME __LC_SAVE_AREA+16 + mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(ext_no_vtime) UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER ext_no_vtime: - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct TRACE_IRQS_OFF la %r2,SP_PTREGS(%r15) # address of register-save area l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code @@ -777,7 +780,10 @@ mcck_int_main: sra %r14,PAGE_SHIFT be BASED(0f) l %r15,__LC_PANIC_STACK # load panic stack -0: CREATE_STACK_FRAME __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32 +0: s %r15,BASED(.Lc_spsize) # make room for registers & psw + CREATE_STACK_FRAME __LC_SAVE_AREA+32 + mvc SP_PSW(8,%r15),0(%r12) + l %r12,__LC_THREAD_INFO # load pointer to thread_info struct tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -786,7 +792,6 @@ mcck_int_main: UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER mcck_no_vtime: - l %r9,__LC_THREAD_INFO # load pointer to thread_info struct la %r2,SP_PTREGS(%r15) # load pt_regs l %r1,BASED(.Ls390_mcck) basr %r14,%r1 # call machine check handler @@ -798,7 +803,7 @@ mcck_no_vtime: xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain lr %r15,%r1 stosm __SF_EMPTY(%r15),0x04 # turn dat on - tm __TI_flags+3(%r9),_TIF_MCCK_PENDING + tm __TI_flags+3(%r12),_TIF_MCCK_PENDING bno BASED(mcck_return) TRACE_IRQS_OFF l %r1,BASED(.Ls390_handle_mcck) @@ -947,12 +952,13 @@ cleanup_system_call: bh BASED(0f) mvc __LC_SAVE_AREA(16),0(%r12) 0: st %r13,4(%r12) - st %r12,__LC_SAVE_AREA+48 # argh - SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA - CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA - l %r12,__LC_SAVE_AREA+48 # argh + l %r15,__LC_KERNEL_STACK # problem state -> load ksp + s %r15,BASED(.Lc_spsize) # make room for registers & psw st %r15,12(%r12) - lh %r7,0x8a + CREATE_STACK_FRAME __LC_SAVE_AREA + mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW + mvc SP_ILC(4,%r15),__LC_SVC_ILC + mvc 0(4,%r12),__LC_THREAD_INFO cleanup_vtime: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) bhe BASED(cleanup_stime) |