openrisc: don't use pt_regs in struct sigcontext
authorJonas Bonn <jonas@southpole.se>
Sat, 30 Jul 2011 14:15:42 +0000 (16:15 +0200)
committerJonas Bonn <jonas@southpole.se>
Mon, 5 Sep 2011 12:29:12 +0000 (14:29 +0200)
As it was decided not to export struct pt_regs to userspace, struct
sigcontext shouldn't be using it either.  The pt_regs struct for OpenRISC
is kernel internal and the layout of the registers may change in the
future.  The struct user_regs_struct is what is guaranteed to remain
stable, so struct sigcontext may use that instead.

This patch removes the usage of struct pt_regs in struct sigcontext and
makes according changes in signal.c to get the register layout right.

The usp field is removed from the sigcontext structure as this information
is already contained in the user_regs_struct.

Signed-off-by: Jonas Bonn <jonas@southpole.se>
Reviewed-by: Emilio Cota <cota@braap.org>
arch/openrisc/include/asm/sigcontext.h
arch/openrisc/kernel/signal.c

index 54a5c50132e35e4000e45f874c6c1618894b9f9f..b79c2b19afbe6cfe9f4327535e257e12c9aaa29f 100644 (file)
 
 /* This struct is saved by setup_frame in signal.c, to keep the current
    context while a signal handler is executed. It's restored by sys_sigreturn.
-
-   To keep things simple, we use pt_regs here even though normally you just
-   specify the list of regs to save. Then we can use copy_from_user on the
-   entire regs instead of a bunch of get_user's as well...
 */
 
 struct sigcontext {
-       struct pt_regs regs;  /* needs to be first */
+       struct user_regs_struct regs;  /* needs to be first */
        unsigned long oldmask;
-       unsigned long usp;    /* usp before stacking this gunk on it */
 };
 
 #endif /* __ASM_OPENRISC_SIGCONTEXT_H */
index 5f759c76834eee10dd821edc8a0b560d6d3931df..95207ab0c99ed536016e88b8be1a2b077ec3bae5 100644 (file)
@@ -52,31 +52,25 @@ struct rt_sigframe {
 static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 {
        unsigned int err = 0;
-       unsigned long old_usp;
 
        /* Alwys make any pending restarted system call return -EINTR */
        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
-       /* restore the regs from &sc->regs (same as sc, since regs is first)
+       /*
+        * Restore the regs from &sc->regs.
         * (sc is already checked for VERIFY_READ since the sigframe was
         *  checked in sys_sigreturn previously)
         */
-
-       if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
+       if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
+               goto badframe;
+       if (__copy_from_user(&regs->pc, &sc->regs.pc, sizeof(unsigned long)))
+               goto badframe;
+       if (__copy_from_user(&regs->sr, &sc->regs.sr, sizeof(unsigned long)))
                goto badframe;
 
        /* make sure the SM-bit is cleared so user-mode cannot fool us */
        regs->sr &= ~SPR_SR_SM;
 
-       /* restore the old USP as it was before we stacked the sc etc.
-        * (we cannot just pop the sigcontext since we aligned the sp and
-        *  stuff after pushing it)
-        */
-
-       err |= __get_user(old_usp, &sc->usp);
-
-       regs->sp = old_usp;
-
        /* TODO: the other ports use regs->orig_XX to disable syscall checks
         * after this completes, but we don't use that mechanism. maybe we can
         * use it now ?
@@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
                            unsigned long mask)
 {
        int err = 0;
-       unsigned long usp = regs->sp;
 
-       /* copy the regs. they are first in sc so we can use sc directly */
+       /* copy the regs */
 
-       err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
+       err |= __copy_to_user(sc->regs.gpr, regs, 32 * sizeof(unsigned long));
+       err |= __copy_to_user(&sc->regs.pc, &regs->pc, sizeof(unsigned long));
+       err |= __copy_to_user(&sc->regs.sr, &regs->sr, sizeof(unsigned long));
 
        /* then some other stuff */
 
        err |= __put_user(mask, &sc->oldmask);
 
-       err |= __put_user(usp, &sc->usp);
-
        return err;
 }