diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index f280ddb903f6b1412634942fbc7d83d0b44476af..9fbf8d3c8aeea7eb56edaadfabd6220518e42d29 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -84,8 +84,8 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) regs->tnpc = npc; err |= __get_user(regs->y, &((*grp)[MC_Y])); err |= __get_user(tstate, &((*grp)[MC_TSTATE])); - regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); - regs->tstate |= (tstate & (TSTATE_ICC | TSTATE_XCC)); + regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC); + regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC)); err |= __get_user(regs->u_regs[UREG_G1], (&(*grp)[MC_G1])); err |= __get_user(regs->u_regs[UREG_G2], (&(*grp)[MC_G2])); err |= __get_user(regs->u_regs[UREG_G3], (&(*grp)[MC_G3])); @@ -408,9 +408,9 @@ void do_rt_sigreturn(struct pt_regs *regs) err |= __get_user(tstate, &sf->regs.tstate); err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs)); - /* User can only change condition codes in %tstate. */ - regs->tstate &= ~(TSTATE_ICC | TSTATE_XCC); - regs->tstate |= (tstate & (TSTATE_ICC | TSTATE_XCC)); + /* User can only change condition codes and %asi in %tstate. */ + regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC); + regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC)); err |= __get_user(fpu_save, &sf->fpu_save); if (fpu_save) diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index 2bedb8cf26b359cb6f45e4977ecca1d7cb6367e2..460b9466852606cce8bdd0550316c7d1a7e8cf6d 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -59,6 +59,16 @@ struct signal_sframe32 { unsigned int extramask[_COMPAT_NSIG_WORDS - 1]; }; +/* This magic should be in g_upper[0] for all upper parts + * to be valid. + */ +#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269 +typedef struct { + unsigned int g_upper[8]; + unsigned int o_upper[8]; + unsigned int asi; +} siginfo_extra_v8plus_t; + /* * And the new one, intended to be used for Linux applications only * (we have enough in there to work with clone). @@ -299,8 +309,13 @@ void do_new_sigreturn32(struct pt_regs *regs) if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) { err |= __get_user(i, &sf->v8plus.g_upper[0]); if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) { + unsigned long asi; + for (i = UREG_G1; i <= UREG_I7; i++) err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); + err |= __get_user(asi, &sf->v8plus.asi); + regs->tstate &= ~TSTATE_ASI; + regs->tstate |= ((asi & 0xffUL) << 24UL); } } @@ -447,8 +462,13 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) { err |= __get_user(i, &sf->v8plus.g_upper[0]); if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) { + unsigned long asi; + for (i = UREG_G1; i <= UREG_I7; i++) err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); + err |= __get_user(asi, &sf->v8plus.asi); + regs->tstate &= ~TSTATE_ASI; + regs->tstate |= ((asi & 0xffUL) << 24UL); } } @@ -715,7 +735,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs, err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size); err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]); for (i = 1; i < 16; i++) - err |= __put_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); + err |= __put_user(((u32 *)regs->u_regs)[2*i], + &sf->v8plus.g_upper[i]); + err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL, + &sf->v8plus.asi); if (psr & PSR_EF) { err |= save_fpu_state32(regs, &sf->fpu_state); @@ -1120,6 +1143,8 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs, for (i = 1; i < 16; i++) err |= __put_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]); + err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL, + &sf->v8plus.asi); if (psr & PSR_EF) { err |= save_fpu_state32(regs, &sf->fpu_state); diff --git a/include/asm-sparc/sigcontext.h b/include/asm-sparc/sigcontext.h index ff9ccda164ce5a47182ad8b585fb4357bff00c3a..86dc000ad681d4c1f0b969ea6a3085d6f0b84842 100644 --- a/include/asm-sparc/sigcontext.h +++ b/include/asm-sparc/sigcontext.h @@ -57,20 +57,6 @@ typedef struct { } si_fpqueue [16]; } __siginfo_fpu_t; -#ifdef __KERNEL__ - -/* This magic should be in g_upper[0] for all upper parts - to be valid. - This is generated by sparc64 only, but for 32bit processes, - so we define it here as well. */ -#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269 -typedef struct { - unsigned int g_upper[8]; - unsigned int o_upper[8]; -} siginfo_extra_v8plus_t; - -#endif - #endif /* !(__ASSEMBLY__) */ #endif /* !(__SPARC_SIGCONTEXT_H) */ diff --git a/include/asm-sparc64/sigcontext.h b/include/asm-sparc64/sigcontext.h index d7128a8757bfb4cf0691331d8bd924a88f883054..d8073373db8cb78cae1cd91b08e4e0615d19103e 100644 --- a/include/asm-sparc64/sigcontext.h +++ b/include/asm-sparc64/sigcontext.h @@ -83,18 +83,6 @@ struct sigcontext { unsigned long sigc_mask; }; -#ifdef __KERNEL__ - -/* This magic should be in g_upper[0] for all upper parts - to be valid. */ -#define SIGINFO_EXTRA_V8PLUS_MAGIC 0x130e269 -typedef struct { - unsigned int g_upper[8]; - unsigned int o_upper[8]; -} siginfo_extra_v8plus_t; - -#endif - #endif /* !(__ASSEMBLY__) */ #endif /* !(__SPARC64_SIGCONTEXT_H) */