Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223423
b: refs/heads/master
c: 81711ce
h: refs/heads/master
i:
  223421: bba6001
  223419: 7aec3ef
  223415: 67c96ed
  223407: cb1f8ec
  223391: bd6ba77
  223359: 02f68c9
v: v3
  • Loading branch information
Chris Metcalf committed Dec 17, 2010
1 parent 7f6e2ee commit 31c8376
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bc4cf2bb271b2d557fc510426755da786fc985be
refs/heads/master: 81711cee933599fa114abb0d258d8bbabef8adfb
2 changes: 1 addition & 1 deletion trunk/arch/tile/include/asm/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
struct pt_regs;
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
void do_signal(struct pt_regs *regs);
#endif
Expand Down
6 changes: 3 additions & 3 deletions trunk/arch/tile/kernel/compat_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
return ret;
}

/* The assembly shim for this function arranges to ignore the return value. */
long compat_sys_rt_sigreturn(struct pt_regs *regs)
{
struct compat_rt_sigframe __user *frame =
(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
sigset_t set;
long r0;

if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
Expand All @@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);

if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;

if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
goto badframe;

return r0;
return 0;

badframe:
force_sig(SIGSEGV, current);
Expand Down
24 changes: 21 additions & 3 deletions trunk/arch/tile/kernel/intvec_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -1342,8 +1342,8 @@ handle_syscall:
lw r20, r20

/* Jump to syscall handler. */
jalr r20; .Lhandle_syscall_link:
FEEDBACK_REENTER(handle_syscall)
jalr r20
.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */

/*
* Write our r0 onto the stack so it gets restored instead
Expand All @@ -1352,6 +1352,9 @@ handle_syscall:
PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
sw r29, r0

.Lsyscall_sigreturn_skip:
FEEDBACK_REENTER(handle_syscall)

/* Do syscall trace again, if requested. */
lw r30, r31
andi r30, r30, _TIF_SYSCALL_TRACE
Expand Down Expand Up @@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr)
}; \
STD_ENDPROC(_##x)

/*
* Special-case sigreturn to not write r0 to the stack on return.
* This is technically more efficient, but it also avoids difficulties
* in the 64-bit OS when handling 32-bit compat code, since we must not
* sign-extend r0 for the sigreturn return-value case.
*/
#define PTREGS_SYSCALL_SIGRETURN(x, reg) \
STD_ENTRY(_##x); \
addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
{ \
PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
j x \
}; \
STD_ENDPROC(_##x)

PTREGS_SYSCALL(sys_execve, r3)
PTREGS_SYSCALL(sys_sigaltstack, r2)
PTREGS_SYSCALL(sys_rt_sigreturn, r0)
PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)

/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
Expand Down
10 changes: 4 additions & 6 deletions trunk/arch/tile/kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
*/

int restore_sigcontext(struct pt_regs *regs,
struct sigcontext __user *sc, long *pr0)
struct sigcontext __user *sc)
{
int err = 0;
int i;
Expand All @@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs,

regs->faultnum = INT_SWINT_1_SIGRETURN;

err |= __get_user(*pr0, &sc->gregs[0]);
return err;
}

/* sigreturn() returns long since it restores r0 in the interrupted code. */
/* The assembly shim for this function arranges to ignore the return value. */
SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
{
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(regs->sp);
sigset_t set;
long r0;

if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
Expand All @@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock);

if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;

if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
goto badframe;

return r0;
return 0;

badframe:
force_sig(SIGSEGV, current);
Expand Down

0 comments on commit 31c8376

Please sign in to comment.