Correct stack handling is signal deliver to user processes

This commit is contained in:
Gregory Nutt 2014-09-16 13:33:13 -06:00
parent 0bedf06b49
commit 058229b626

View File

@ -352,10 +352,6 @@ uint32_t *arm_syscall(uint32_t *regs)
case SYS_signal_handler: case SYS_signal_handler:
{ {
FAR struct tcb_s *rtcb = sched_self(); FAR struct tcb_s *rtcb = sched_self();
#ifdef CONFIG_ARCH_KERNEL_STACK
int depth;
#endif
/* Remember the caller's return address */ /* Remember the caller's return address */
DEBUGASSERT(rtcb->xcp.sigreturn == 0); DEBUGASSERT(rtcb->xcp.sigreturn == 0);
@ -384,20 +380,19 @@ uint32_t *arm_syscall(uint32_t *regs)
regs[REG_R3] = *(uint32_t*)(regs[REG_SP]+4); regs[REG_R3] = *(uint32_t*)(regs[REG_SP]+4);
#ifdef CONFIG_ARCH_KERNEL_STACK #ifdef CONFIG_ARCH_KERNEL_STACK
/* If this is a nested SYSCALL and if there is an allocated kernel /* If we are signalling a user process, then we must be operating
* stack, then we must be operating on the kernal stack now. We * on the kernel stack now. We need to switch back to the user
* need to switch back to the user stack before dispatching the * stack before dispatching the signal handler to the user code.
* signal handler to the user code. * The existence of an allocated kernel stack is sufficient
* information to make this decision.
*/ */
depth = rtcb->xcp.nsyscalls; if (rtcb->xcp.kstack != NULL)
if (depth > 0 && rtcb->xcp.kstack != NULL)
{ {
DEBUGASSERT(rtcb->xcp.kstkptr == NULL && DEBUGASSERT(rtcb->xcp.kstkptr == NULL && rtcb->xcp.ustkptr != NULL);
rtcb->xcp.ustkptr[depth - 1] != 0);
rtcb->xcp.kstkptr = (FAR uint32_t *)regs[REG_SP]; rtcb->xcp.kstkptr = (FAR uint32_t *)regs[REG_SP];
regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr[depth - 1]; regs[REG_SP] = (uint32_t)rtcb->xcp.ustkptr;
} }
#endif #endif
} }
@ -417,9 +412,6 @@ uint32_t *arm_syscall(uint32_t *regs)
case SYS_signal_handler_return: case SYS_signal_handler_return:
{ {
FAR struct tcb_s *rtcb = sched_self(); FAR struct tcb_s *rtcb = sched_self();
#ifdef CONFIG_ARCH_KERNEL_STACK
int depth;
#endif
/* Set up to return to the kernel-mode signal dispatching logic. */ /* Set up to return to the kernel-mode signal dispatching logic. */
@ -431,17 +423,15 @@ uint32_t *arm_syscall(uint32_t *regs)
rtcb->xcp.sigreturn = 0; rtcb->xcp.sigreturn = 0;
#ifdef CONFIG_ARCH_KERNEL_STACK #ifdef CONFIG_ARCH_KERNEL_STACK
/* If this is a nested SYSCALL and if there is an allocated kernel /* We must enter here be using the user stack. We need to switch
* stack, we must be using the user stack to dispatch to the signal * to back to the kernel user stack before returning to the kernel
* handler. We need to switch to back to the kernel user stack * mode signal trampoline.
* before returning to the kernel mode signal trampoline.
*/ */
depth = rtcb->xcp.nsyscalls; if (rtcb->xcp.kstack != NULL)
if (depth > 0 && rtcb->xcp.kstack != NULL)
{ {
DEBUGASSERT(rtcb->xcp.kstkptr != NULL && DEBUGASSERT(rtcb->xcp.kstkptr != NULL &&
(uint32_t)rtcb->xcp.ustkptr[depth - 1] == regs[REG_SP]); (uint32_t)rtcb->xcp.ustkptr == regs[REG_SP]);
regs[REG_SP] = (uint32_t)rtcb->xcp.kstkptr; regs[REG_SP] = (uint32_t)rtcb->xcp.kstkptr;
rtcb->xcp.kstkptr = NULL; rtcb->xcp.kstkptr = NULL;