#include <asm/thread_info.h>
#include <asm/offsets.h>
#include <asm/unistd.h>
+#include <asm/page.h>
/*
* Stack layout for the system_call stack entry.
SP_TRAP = STACK_FRAME_OVERHEAD + __PT_TRAP
SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
+STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
+STACK_SIZE = 1 << STACK_SHIFT
+
_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
_TIF_RESTART_SVC | _TIF_SINGLE_STEP )
_TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
jnz 1f
0: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ?
slgr %r14,%r15
- srag %r14,%r14,14
+ srag %r14,%r14,STACK_SHIFT
jz 2f
1: lg %r15,__LC_ASYNC_STACK # load async stack
.endif
+#ifdef CONFIG_CHECK_STACK
+ j 3f
+2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD
+ jz stack_overflow
+3:
+#endif
2: aghi %r15,-SP_SIZE # make room for registers & psw
mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
la %r12,\psworg
st %r12,SP_ILC(%r15)
mvc SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
la %r12,0
- stg %r12,0(%r15)
+ stg %r12,__SF_BACKCHAIN(%r15)
.endm
.macro RESTORE_ALL sync
__switch_to:
tm __THREAD_per+4(%r3),0xe8 # is the new process using per ?
jz __switch_to_noper # if not we're fine
- stctg %c9,%c11,48(%r15) # We are using per stuff
- clc __THREAD_per(24,%r3),48(%r15)
+ stctg %c9,%c11,__SF_EMPTY(%r15)# We are using per stuff
+ clc __THREAD_per(24,%r3),__SF_EMPTY(%r15)
je __switch_to_noper # we got away without bashing TLB's
lctlg %c9,%c11,__THREAD_per(%r3) # Nope we didn't
__switch_to_noper:
- stmg %r6,%r15,48(%r15) # store __switch_to registers of prev task
+ stmg %r6,%r15,__SF_GPRS(%r15)# store __switch_to registers of prev task
stg %r15,__THREAD_ksp(%r2) # store kernel stack to prev->tss.ksp
lg %r15,__THREAD_ksp(%r3) # load kernel stack from next->tss.ksp
- lmg %r6,%r15,48(%r15) # load __switch_to registers of next task
+ lmg %r6,%r15,__SF_GPRS(%r15)# load __switch_to registers of next task
stg %r3,__LC_CURRENT # __LC_CURRENT = current task struct
lg %r3,__THREAD_info(%r3) # load thread_info from task struct
stg %r3,__LC_THREAD_INFO
- aghi %r3,16384
+ aghi %r3,STACK_SIZE
stg %r3,__LC_KERNEL_STACK # __LC_KERNEL_STACK = new kernel stack
br %r14
-/*
- * do_softirq calling function. We want to run the softirq functions on the
- * asynchronous interrupt stack.
- */
- .global do_call_softirq
-do_call_softirq:
- stnsm 48(%r15),0xfc
- stmg %r12,%r15,56(%r15)
- lgr %r12,%r15
- lg %r0,__LC_ASYNC_STACK
- slgr %r0,%r15
- srag %r0,%r0,14
- je 0f
- lg %r15,__LC_ASYNC_STACK
-0: aghi %r15,-STACK_FRAME_OVERHEAD
- stg %r12,0(%r15) # store back chain
- brasl %r14,do_softirq
- lmg %r12,%r15,56(%r12)
- ssm 48(%r15)
- br %r14
-
__critical_start:
/*
* SVC interrupt handler routine. System calls are synchronous events and
ret_from_fork:
lg %r13,__LC_SVC_NEW_PSW+8
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
- brasl %r14,schedule_tail
+ tm SP_PSW+1(%r15),0x01 # forking a kernel thread ?
+ jo 0f
+ stg %r15,SP_R15(%r15) # store stack pointer for new kthread
+0: brasl %r14,schedule_tail
stosm 24(%r15),0x03 # reenable interrupts
j sysc_return
mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
- stosm 48(%r15),0x03 # reenable interrupts
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
j sysc_do_svc
/*
lg %r1,SP_R15(%r15)
aghi %r1,-SP_SIZE
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
- xc 0(8,%r1),0(%r1) # clear back chain
+ xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
lgr %r15,%r1
io_resume_loop:
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
jno io_leave
larl %r1,.Lc_pactive
mvc __TI_precount(4,%r9),0(%r1)
- stosm 48(%r15),0x03 # reenable interrupts
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
brasl %r14,schedule # call schedule
- stnsm 48(%r15),0xfc # disable I/O and ext. interrupts
+ stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
xc __TI_precount(4,%r9),__TI_precount(%r9)
j io_resume_loop
#endif
lg %r1,__LC_KERNEL_STACK
aghi %r1,-SP_SIZE
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
- xc 0(8,%r1),0(%r1) # clear back chain
+ xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain
lgr %r15,%r1
#
# One of the work bits is on. Find out which one.
# _TIF_NEED_RESCHED is set, call schedule
#
io_reschedule:
- stosm 48(%r15),0x03 # reenable interrupts
- brasl %r14,schedule # call scheduler
- stnsm 48(%r15),0xfc # disable I/O and ext. interrupts
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
+ brasl %r14,schedule # call scheduler
+ stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
tm __TI_flags+7(%r9),_TIF_WORK_INT
- jz io_leave # there is no work to do
+ jz io_leave # there is no work to do
j io_work_loop
#
# _TIF_SIGPENDING is set, call do_signal
#
io_sigpending:
- stosm 48(%r15),0x03 # reenable interrupts
- la %r2,SP_PTREGS(%r15) # load pt_regs
- slgr %r3,%r3 # clear *oldset
- brasl %r14,do_signal # call do_signal
- stnsm 48(%r15),0xfc # disable I/O and ext. interrupts
- j sysc_leave # out of here, do NOT recheck
+ stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+ slgr %r3,%r3 # clear *oldset
+ brasl %r14,do_signal # call do_signal
+ stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts
+ j sysc_leave # out of here, do NOT recheck
/*
* External interrupt handler routine
lctlg %c0,%c15,0(%r10) # get new ctl regs
lghi %r10,__LC_AREGS_SAVE_AREA
lam %a0,%a15,0(%r10)
- stosm 0(%r15),0x04 # now we can turn dat on
- lmg %r6,%r15,48(%r15) # load registers from clone
+ lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone
+ stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on
jg start_secondary
#else
/*
restart_go:
#endif
+#ifdef CONFIG_CHECK_STACK
+/*
+ * The synchronous or the asynchronous stack overflowed. We are dead.
+ * No need to properly save the registers, we are going to panic anyway.
+ * Setup a pt_regs so that show_trace can provide a good call trace.
+ */
+stack_overflow:
+ lg %r15,__LC_PANIC_STACK # change to panic stack
+ aghi %r1,-SP_SIZE
+ mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack
+ stmg %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack
+ la %r1,__LC_SAVE_AREA
+ chi %r12,__LC_SVC_OLD_PSW
+ je 0f
+ chi %r12,__LC_PGM_OLD_PSW
+ je 0f
+ la %r1,__LC_SAVE_AREA+16
+0: mvc SP_R12(32,%r15),0(%r1) # move %r12-%r15 to stack
+ xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
+ la %r2,SP_PTREGS(%r15) # load pt_regs
+ jg kernel_stack_overflow
+#endif
+
cleanup_table_system_call:
.quad system_call, sysc_do_svc
cleanup_table_sysc_return: