openrisc: don't use pt_regs in struct sigcontext
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>
This commit is contained in:
parent
93ee7a9340
commit
d7cb666709
|
@ -23,16 +23,11 @@
|
||||||
|
|
||||||
/* This struct is saved by setup_frame in signal.c, to keep the current
|
/* 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.
|
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 sigcontext {
|
||||||
struct pt_regs regs; /* needs to be first */
|
struct user_regs_struct regs; /* needs to be first */
|
||||||
unsigned long oldmask;
|
unsigned long oldmask;
|
||||||
unsigned long usp; /* usp before stacking this gunk on it */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
|
#endif /* __ASM_OPENRISC_SIGCONTEXT_H */
|
||||||
|
|
|
@ -52,31 +52,25 @@ struct rt_sigframe {
|
||||||
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
|
static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
|
||||||
{
|
{
|
||||||
unsigned int err = 0;
|
unsigned int err = 0;
|
||||||
unsigned long old_usp;
|
|
||||||
|
|
||||||
/* Alwys make any pending restarted system call return -EINTR */
|
/* Alwys make any pending restarted system call return -EINTR */
|
||||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
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
|
* (sc is already checked for VERIFY_READ since the sigframe was
|
||||||
* checked in sys_sigreturn previously)
|
* checked in sys_sigreturn previously)
|
||||||
*/
|
*/
|
||||||
|
if (__copy_from_user(regs, sc->regs.gpr, 32 * sizeof(unsigned long)))
|
||||||
if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
|
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;
|
goto badframe;
|
||||||
|
|
||||||
/* make sure the SM-bit is cleared so user-mode cannot fool us */
|
/* make sure the SM-bit is cleared so user-mode cannot fool us */
|
||||||
regs->sr &= ~SPR_SR_SM;
|
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
|
/* 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
|
* after this completes, but we don't use that mechanism. maybe we can
|
||||||
* use it now ?
|
* use it now ?
|
||||||
|
@ -137,18 +131,17 @@ static int setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
|
||||||
unsigned long mask)
|
unsigned long mask)
|
||||||
{
|
{
|
||||||
int err = 0;
|
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 */
|
/* then some other stuff */
|
||||||
|
|
||||||
err |= __put_user(mask, &sc->oldmask);
|
err |= __put_user(mask, &sc->oldmask);
|
||||||
|
|
||||||
err |= __put_user(usp, &sc->usp);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue