diff options
| -rw-r--r-- | arch/openrisc/include/asm/sigcontext.h | 7 | ||||
| -rw-r--r-- | arch/openrisc/kernel/signal.c | 29 | 
2 files changed, 12 insertions, 24 deletions
diff --git a/arch/openrisc/include/asm/sigcontext.h b/arch/openrisc/include/asm/sigcontext.h index 54a5c50132e3..b79c2b19afbe 100644 --- a/arch/openrisc/include/asm/sigcontext.h +++ b/arch/openrisc/include/asm/sigcontext.h @@ -23,16 +23,11 @@  /* 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 */ 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 {  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(®s->pc, &sc->regs.pc, sizeof(unsigned long))) +		goto badframe; +	if (__copy_from_user(®s->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, ®s->pc, sizeof(unsigned long)); +	err |= __copy_to_user(&sc->regs.sr, ®s->sr, sizeof(unsigned long));  	/* then some other stuff */  	err |= __put_user(mask, &sc->oldmask); -	err |= __put_user(usp, &sc->usp); -  	return err;  }  |