aboutsummaryrefslogtreecommitdiffstats
path: root/arch/openrisc/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/openrisc/kernel/signal.c')
-rw-r--r--arch/openrisc/kernel/signal.c29
1 files changed, 11 insertions, 18 deletions
diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
index 5f759c76834e..95207ab0c99e 100644
--- a/arch/openrisc/kernel/signal.c
+++ b/arch/openrisc/kernel/signal.c
@@ -52,31 +52,25 @@ struct rt_sigframe {
52static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) 52static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
53{ 53{
54 unsigned int err = 0; 54 unsigned int err = 0;
55 unsigned long old_usp;
56 55
57 /* Alwys make any pending restarted system call return -EINTR */ 56 /* Alwys make any pending restarted system call return -EINTR */
58 current_thread_info()->restart_block.fn = do_no_restart_syscall; 57 current_thread_info()->restart_block.fn = do_no_restart_syscall;
59 58
60 /* restore the regs from &sc->regs (same as sc, since regs is first) 59 /*
60 * Restore the regs from &sc->regs.
61 * (sc is already checked for VERIFY_READ since the sigframe was 61 * (sc is already checked for VERIFY_READ since the sigframe was
62 * checked in sys_sigreturn previously) 62 * checked in sys_sigreturn previously)
63 */ 63 */
64 64 if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
65 if (__copy_from_user(regs, sc, sizeof(struct pt_regs))) 65 goto badframe;
66 if (__copy_from_user(&regs->pc, &sc->regs.pc, sizeof(unsigned long)))
67 goto badframe;
68 if (__copy_from_user(&regs->sr, &sc->regs.sr, sizeof(unsigned long)))
66 goto badframe; 69 goto badframe;
67 70
68 /* make sure the SM-bit is cleared so user-mode cannot fool us */ 71 /* make sure the SM-bit is cleared so user-mode cannot fool us */
69 regs->sr &= ~SPR_SR_SM; 72 regs->sr &= ~SPR_SR_SM;
70 73
71 /* restore the old USP as it was before we stacked the sc etc.
72 * (we cannot just pop the sigcontext since we aligned the sp and
73 * stuff after pushing it)
74 */
75
76 err |= __get_user(old_usp, &sc->usp);
77
78 regs->sp = old_usp;
79
80 /* TODO: the other ports use regs->orig_XX to disable syscall checks 74 /* TODO: the other ports use regs->orig_XX to disable syscall checks
81 * after this completes, but we don't use that mechanism. maybe we can 75 * after this completes, but we don't use that mechanism. maybe we can
82 * use it now ? 76 * use it now ?
@@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
137 unsigned long mask) 131 unsigned long mask)
138{ 132{
139 int err = 0; 133 int err = 0;
140 unsigned long usp = regs->sp;
141 134
142 /* copy the regs. they are first in sc so we can use sc directly */ 135 /* copy the regs */
143 136
144 err |= __copy_to_user(sc, regs, sizeof(struct pt_regs)); 137 err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
138 err |= __copy_to_user(&sc->regs.pc, &regs->pc, sizeof(unsigned long));
139 err |= __copy_to_user(&sc->regs.sr, &regs->sr, sizeof(unsigned long));
145 140
146 /* then some other stuff */ 141 /* then some other stuff */
147 142
148 err |= __put_user(mask, &sc->oldmask); 143 err |= __put_user(mask, &sc->oldmask);
149 144
150 err |= __put_user(usp, &sc->usp);
151
152 return err; 145 return err;
153} 146}
154 147