Commit 35ecc0e9 authored by David S. Miller's avatar David S. Miller

[SPARC]: __user attributes in signal handling.

parent f6aca97d
......@@ -56,7 +56,7 @@ struct signal_sframe {
struct reg_window sig_window;
int sig_num;
int sig_code;
struct sigcontext *sig_scptr;
struct sigcontext __user *sig_scptr;
int sig_address;
struct sigcontext sig_context;
unsigned int extramask[_NSIG_WORDS - 1];
......@@ -71,8 +71,8 @@ struct signal_sframe {
struct new_signal_frame {
struct sparc_stackf ss;
__siginfo_t info;
__siginfo_fpu_t *fpu_save;
unsigned long insns [2] __attribute__ ((aligned (8)));
__siginfo_fpu_t __user *fpu_save;
unsigned long insns[2] __attribute__ ((aligned (8)));
unsigned int extramask[_NSIG_WORDS - 1];
unsigned int extra_size; /* Should be 0 */
__siginfo_fpu_t fpu_state;
......@@ -83,8 +83,8 @@ struct rt_signal_frame {
siginfo_t info;
struct pt_regs regs;
sigset_t mask;
__siginfo_fpu_t *fpu_save;
unsigned int insns [2];
__siginfo_fpu_t __user *fpu_save;
unsigned int insns[2];
stack_t stack;
unsigned int extra_size; /* Should be 0 */
__siginfo_fpu_t fpu_state;
......@@ -142,7 +142,7 @@ asmlinkage void do_sigsuspend (struct pt_regs *regs)
_sigpause_common(regs->u_regs[UREG_I0], regs);
}
asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize,
asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
struct pt_regs *regs)
{
sigset_t oldset, set;
......@@ -190,7 +190,7 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize,
}
static inline int
restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
int err;
#ifdef CONFIG_SMP
......@@ -205,7 +205,7 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
current->used_math = 1;
clear_tsk_thread_flag(current, TIF_USEDFPU);
if (verify_area (VERIFY_READ, fpu, sizeof(*fpu)))
if (verify_area(VERIFY_READ, fpu, sizeof(*fpu)))
return -EFAULT;
err = __copy_from_user(&current->thread.float_regs[0], &fpu->si_float_regs[0],
......@@ -222,16 +222,16 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
static inline void do_new_sigreturn (struct pt_regs *regs)
{
struct new_signal_frame *sf;
struct new_signal_frame __user *sf;
unsigned long up_psr, pc, npc;
sigset_t set;
__siginfo_fpu_t *fpu_save;
__siginfo_fpu_t __user *fpu_save;
int err;
sf = (struct new_signal_frame *) regs->u_regs [UREG_FP];
sf = (struct new_signal_frame __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (verify_area (VERIFY_READ, sf, sizeof (*sf)))
if (verify_area(VERIFY_READ, sf, sizeof(*sf)))
goto segv_and_exit;
if (((uint) sf) & 3)
......@@ -245,7 +245,7 @@ static inline void do_new_sigreturn (struct pt_regs *regs)
/* 2. Restore the state */
up_psr = regs->psr;
err |= __copy_from_user(regs, &sf->info.si_regs, sizeof (struct pt_regs));
err |= __copy_from_user(regs, &sf->info.si_regs, sizeof(struct pt_regs));
/* User can only change condition codes and FPU enabling in %psr. */
regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
......@@ -279,7 +279,7 @@ static inline void do_new_sigreturn (struct pt_regs *regs)
asmlinkage void do_sigreturn(struct pt_regs *regs)
{
struct sigcontext *scptr;
struct sigcontext __user *scptr;
unsigned long pc, npc, psr;
sigset_t set;
int err;
......@@ -287,19 +287,19 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
synchronize_user_stack();
if (current->thread.new_signal)
return do_new_sigreturn (regs);
return do_new_sigreturn(regs);
scptr = (struct sigcontext *) regs->u_regs[UREG_I0];
scptr = (struct sigcontext __user *) regs->u_regs[UREG_I0];
/* Check sanity of the user arg. */
if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) ||
(((unsigned long) scptr) & 3))
if (verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext)) ||
(((unsigned long) scptr) & 3))
goto segv_and_exit;
err = __get_user(pc, &scptr->sigc_pc);
err |= __get_user(npc, &scptr->sigc_npc);
if((pc | npc) & 3)
if ((pc | npc) & 3)
goto segv_and_exit;
/* This is pretty much atomic, no amount locking would prevent
......@@ -341,17 +341,17 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
{
struct rt_signal_frame *sf;
struct rt_signal_frame __user *sf;
unsigned int psr, pc, npc;
__siginfo_fpu_t *fpu_save;
__siginfo_fpu_t __user *fpu_save;
sigset_t set;
stack_t st;
int err;
synchronize_user_stack();
sf = (struct rt_signal_frame *) regs->u_regs[UREG_FP];
if(verify_area(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 0x03))
sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
if (verify_area(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 0x03))
goto segv;
err = __get_user(pc, &sf->regs.pc);
......@@ -361,13 +361,14 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
err |= __get_user(regs->y, &sf->regs.y);
err |= __get_user(psr, &sf->regs.psr);
err |= __copy_from_user(&regs->u_regs[UREG_G1], &sf->regs.u_regs[UREG_G1], 15*sizeof(u32));
err |= __copy_from_user(&regs->u_regs[UREG_G1],
&sf->regs.u_regs[UREG_G1], 15 * sizeof(u32));
regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
err |= __get_user(fpu_save, &sf->fpu_save);
if(fpu_save)
if (fpu_save)
err |= restore_fpu_state(regs, fpu_save);
err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
......@@ -380,7 +381,8 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
regs->npc = npc;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
* call it and ignore errors.
*/
do_sigaltstack(&st, NULL, (unsigned long)sf);
sigdelsetmask(&set, ~_BLOCKABLE);
......@@ -394,7 +396,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
}
/* Checks if the fp is valid */
static inline int invalid_frame_pointer (void *fp, int fplen)
static inline int invalid_frame_pointer(void __user *fp, int fplen)
{
if ((((unsigned long) fp) & 7) ||
!__access_ok((unsigned long)fp, fplen) ||
......@@ -405,7 +407,7 @@ static inline int invalid_frame_pointer (void *fp, int fplen)
return 0;
}
static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
static inline void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
{
unsigned long sp;
......@@ -416,14 +418,14 @@ static inline void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, uns
if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
sp = current->sas_ss_sp + current->sas_ss_size;
}
return (void *)(sp - framesize);
return (void __user *)(sp - framesize);
}
static inline void
setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
{
struct signal_sframe *sframep;
struct sigcontext *sc;
struct signal_sframe __user *sframep;
struct sigcontext __user *sc;
int window = 0, err;
unsigned long pc = regs->pc;
unsigned long npc = regs->npc;
......@@ -431,8 +433,9 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
int sig_code;
synchronize_user_stack();
sframep = (struct signal_sframe *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){
sframep = (struct signal_sframe __user *)
get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer(sframep, sizeof(*sframep))){
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
......@@ -454,16 +457,16 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
err |= __put_user(current->thread.w_saved, &sc->sigc_oswins);
if(current->thread.w_saved)
for(window = 0; window < current->thread.w_saved; window++) {
sc->sigc_spbuf[window] =
(char *)current->thread.rwbuf_stkptrs[window];
if (current->thread.w_saved)
for (window = 0; window < current->thread.w_saved; window++) {
put_user((char *)current->thread.rwbuf_stkptrs[window],
&sc->sigc_spbuf[window]);
err |= __copy_to_user(&sc->sigc_wbuf[window],
&current->thread.reg_window[window],
sizeof(struct reg_window));
}
else
err |= __copy_to_user(sframep, (char *)regs->u_regs[UREG_FP],
err |= __copy_to_user(sframep, (char *) regs->u_regs[UREG_FP],
sizeof(struct reg_window));
current->thread.w_saved = 0; /* So process is allowed to execute. */
......@@ -484,7 +487,7 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
switch (info->si_code) {
case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
default: sig_code = SUBSIG_STACK; break;
}
break;
......@@ -541,7 +544,7 @@ setup_frame(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *old
static inline int
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
int err = 0;
#ifdef CONFIG_SMP
......@@ -561,12 +564,14 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
regs->psr &= ~(PSR_EF);
}
#endif
err |= __copy_to_user(&fpu->si_float_regs[0], &current->thread.float_regs[0],
err |= __copy_to_user(&fpu->si_float_regs[0],
&current->thread.float_regs[0],
(sizeof(unsigned long) * 32));
err |= __put_user(current->thread.fsr, &fpu->si_fsr);
err |= __put_user(current->thread.fpqdepth, &fpu->si_fpqdepth);
if (current->thread.fpqdepth != 0)
err |= __copy_to_user(&fpu->si_fpqueue[0], &current->thread.fpqueue[0],
err |= __copy_to_user(&fpu->si_fpqueue[0],
&current->thread.fpqueue[0],
((sizeof(unsigned long) +
(sizeof(unsigned long *)))*16));
current->used_math = 0;
......@@ -577,7 +582,7 @@ static inline void
new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset)
{
struct new_signal_frame *sf;
struct new_signal_frame __user *sf;
int sigframe_size, err;
/* 1. Make sure everything is clean */
......@@ -587,16 +592,17 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (!current->used_math)
sigframe_size -= sizeof(__siginfo_fpu_t);
sf = (struct new_signal_frame *)get_sigframe(&ka->sa, regs, sigframe_size);
sf = (struct new_signal_frame __user *)
get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size))
if (invalid_frame_pointer(sf, sigframe_size))
goto sigill_and_return;
if (current->thread.w_saved != 0)
goto sigill_and_return;
/* 2. Save the current process state */
err = __copy_to_user(&sf->info.si_regs, regs, sizeof (struct pt_regs));
err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs));
err |= __put_user(0, &sf->extra_size);
......@@ -610,8 +616,8 @@ new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __put_user(oldset->sig[0], &sf->info.si_mask);
err |= __copy_to_user(sf->extramask, &oldset->sig[1],
(_NSIG_WORDS - 1) * sizeof(unsigned int));
err |= __copy_to_user(sf, (char *) regs->u_regs [UREG_FP],
sizeof (struct reg_window));
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
sizeof(struct reg_window));
if (err)
goto sigsegv;
......@@ -653,32 +659,33 @@ static inline void
new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
{
struct rt_signal_frame *sf;
struct rt_signal_frame __user *sf;
int sigframe_size;
unsigned int psr;
int err;
synchronize_user_stack();
sigframe_size = RT_ALIGNEDSZ;
if(!current->used_math)
if (!current->used_math)
sigframe_size -= sizeof(__siginfo_fpu_t);
sf = (struct rt_signal_frame *)get_sigframe(&ka->sa, regs, sigframe_size);
if(invalid_frame_pointer(sf, sigframe_size))
sf = (struct rt_signal_frame __user *)
get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer(sf, sigframe_size))
goto sigill;
if(current->thread.w_saved != 0)
if (current->thread.w_saved != 0)
goto sigill;
err = __put_user(regs->pc, &sf->regs.pc);
err |= __put_user(regs->npc, &sf->regs.npc);
err |= __put_user(regs->y, &sf->regs.y);
psr = regs->psr;
if(current->used_math)
if (current->used_math)
psr |= PSR_EF;
err |= __put_user(psr, &sf->regs.psr);
err |= __copy_to_user(&sf->regs.u_regs, regs->u_regs, sizeof(regs->u_regs));
err |= __put_user(0, &sf->extra_size);
if(psr & PSR_EF) {
if (psr & PSR_EF) {
err |= save_fpu_state(regs, &sf->fpu_state);
err |= __put_user(&sf->fpu_state, &sf->fpu_save);
} else {
......@@ -691,8 +698,8 @@ new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
err |= __copy_to_user(sf, (char *) regs->u_regs [UREG_FP],
sizeof (struct reg_window));
err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
sizeof(struct reg_window));
err |= copy_siginfo_to_user(&sf->info, info);
......@@ -706,7 +713,7 @@ new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
regs->pc = (unsigned long) ka->sa.sa_handler;
regs->npc = (regs->pc + 4);
if(ka->ka_restorer)
if (ka->ka_restorer)
regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
else {
regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
......@@ -735,23 +742,24 @@ static inline void
setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
struct pt_regs *regs, int signr, sigset_t *oldset)
{
svr4_signal_frame_t *sfp;
svr4_gregset_t *gr;
svr4_siginfo_t *si;
svr4_mcontext_t *mc;
svr4_gwindows_t *gw;
svr4_ucontext_t *uc;
svr4_signal_frame_t __user *sfp;
svr4_gregset_t __user *gr;
svr4_siginfo_t __user *si;
svr4_mcontext_t __user *mc;
svr4_gwindows_t __user *gw;
svr4_ucontext_t __user *uc;
svr4_sigset_t setv;
int window = 0, err;
synchronize_user_stack();
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ);
sfp = (svr4_signal_frame_t __user *)
get_sigframe(sa, regs, SVR4_SF_ALIGNED + REGWIN_SZ);
if (invalid_frame_pointer (sfp, sizeof (*sfp)))
if (invalid_frame_pointer(sfp, sizeof(*sfp)))
goto sigill_and_return;
/* Start with a clean frame pointer and fill it */
err = __clear_user(sfp, sizeof (*sfp));
err = __clear_user(sfp, sizeof(*sfp));
/* Setup convenience variables */
si = &sfp->si;
......@@ -771,17 +779,20 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
setv.sigbits[3] = oldset->sig[3];
err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
} else
err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned int));
err |= __copy_to_user(&uc->sigmask, &setv,
2 * sizeof(unsigned int));
/* Store registers */
err |= __put_user(regs->pc, &((*gr) [SVR4_PC]));
err |= __put_user(regs->npc, &((*gr) [SVR4_NPC]));
err |= __put_user(regs->psr, &((*gr) [SVR4_PSR]));
err |= __put_user(regs->y, &((*gr) [SVR4_Y]));
err |= __put_user(regs->pc, &((*gr)[SVR4_PC]));
err |= __put_user(regs->npc, &((*gr)[SVR4_NPC]));
err |= __put_user(regs->psr, &((*gr)[SVR4_PSR]));
err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
/* Copy g [1..7] and o [0..7] registers */
err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (long) * 7);
err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (long) * 8);
/* Copy g[1..7] and o[0..7] registers */
err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs[UREG_G1],
sizeof(long) * 7);
err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs[UREG_I0],
sizeof(long) * 8);
/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
......@@ -793,7 +804,7 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* 1. Link sfp->uc->gwins to our windows */
err |= __put_user(gw, &mc->gwin);
/* 2. Number of windows to restore at setcontext (): */
/* 2. Number of windows to restore at setcontext(): */
err |= __put_user(current->thread.w_saved, &gw->count);
/* 3. Save each valid window
......@@ -807,12 +818,12 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
* These windows are just used in case synchronize_user_stack failed
* to flush the user windows.
*/
for(window = 0; window < current->thread.w_saved; window++) {
err |= __put_user((int *) &(gw->win [window]), &gw->winptr [window]);
err |= __copy_to_user(&gw->win [window],
&current->thread.reg_window [window],
sizeof (svr4_rwindow_t));
err |= __put_user(0, gw->winptr [window]);
for (window = 0; window < current->thread.w_saved; window++) {
err |= __put_user((int *) &(gw->win[window]), &gw->winptr[window]);
err |= __copy_to_user(&gw->win[window],
&current->thread.reg_window[window],
sizeof(svr4_rwindow_t));
err |= __put_user(0, gw->winptr[window]);
}
/* 4. We just pay attention to the gw->count field on setcontext */
......@@ -832,13 +843,14 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
regs->npc = (regs->pc + 4);
/* Arguments passed to signal handler */
if (regs->u_regs [14]){
struct reg_window *rw = (struct reg_window *) regs->u_regs [14];
err |= __put_user(signr, &rw->ins [0]);
err |= __put_user(si, &rw->ins [1]);
err |= __put_user(uc, &rw->ins [2]);
err |= __put_user(sfp, &rw->ins [6]); /* frame pointer */
if (regs->u_regs[14]){
struct reg_window *rw = (struct reg_window __user *)
regs->u_regs[14];
err |= __put_user(signr, &rw->ins[0]);
err |= __put_user(si, &rw->ins[1]);
err |= __put_user(uc, &rw->ins[2]);
err |= __put_user(sfp, &rw->ins[6]); /* frame pointer */
if (err)
goto sigsegv;
......@@ -854,10 +866,10 @@ setup_svr4_frame(struct sigaction *sa, unsigned long pc, unsigned long npc,
do_exit(SIGSEGV);
}
asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
asmlinkage int svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
{
svr4_gregset_t *gr;
svr4_mcontext_t *mc;
svr4_gregset_t __user *gr;
svr4_mcontext_t __user *mc;
svr4_sigset_t setv;
int err = 0;
......@@ -866,7 +878,7 @@ asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
if (current->thread.w_saved)
goto sigsegv_and_return;
err = clear_user(uc, sizeof (*uc));
err = clear_user(uc, sizeof(*uc));
if (err)
return -EFAULT;
......@@ -881,17 +893,20 @@ asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
setv.sigbits[3] = current->blocked.sig[3];
err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
} else
err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned int));
err |= __copy_to_user(&uc->sigmask, &setv,
2 * sizeof(unsigned int));
/* Store registers */
err |= __put_user(regs->pc, &uc->mcontext.greg [SVR4_PC]);
err |= __put_user(regs->npc, &uc->mcontext.greg [SVR4_NPC]);
err |= __put_user(regs->psr, &uc->mcontext.greg [SVR4_PSR]);
err |= __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
err |= __put_user(regs->pc, &uc->mcontext.greg[SVR4_PC]);
err |= __put_user(regs->npc, &uc->mcontext.greg[SVR4_NPC]);
err |= __put_user(regs->psr, &uc->mcontext.greg[SVR4_PSR]);
err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
/* Copy g [1..7] and o [0..7] registers */
err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs [UREG_G1], sizeof (uint) * 7);
err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs [UREG_I0], sizeof (uint) * 8);
/* Copy g[1..7] and o[0..7] registers */
err |= __copy_to_user(&(*gr)[SVR4_G1], &regs->u_regs[UREG_G1],
sizeof(uint) * 7);
err |= __copy_to_user(&(*gr)[SVR4_O0], &regs->u_regs[UREG_I0],
sizeof(uint) * 8);
/* Setup sigaltstack */
err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
......@@ -908,10 +923,10 @@ asmlinkage int svr4_getcontext (svr4_ucontext_t *uc, struct pt_regs *regs)
}
/* Set the context for a svr4 application, this is Solaris way to sigreturn */
asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
{
struct thread_struct *tp = &current->thread;
svr4_gregset_t *gr;
svr4_gregset_t __user *gr;
unsigned long pc, npc, psr;
sigset_t set;
svr4_sigset_t setv;
......@@ -929,7 +944,7 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
if (((uint) c) & 3)
goto sigsegv_and_return;
if(!__access_ok((unsigned long)c, sizeof(*c)))
if (!__access_ok((unsigned long)c, sizeof(*c)))
goto sigsegv_and_return;
/* Check for valid PC and nPC */
......@@ -937,7 +952,7 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
err = __get_user(pc, &((*gr)[SVR4_PC]));
err |= __get_user(npc, &((*gr)[SVR4_NPC]));
if((pc | npc) & 3)
if ((pc | npc) & 3)
goto sigsegv_and_return;
/* Retrieve information from passed ucontext */
......@@ -973,16 +988,16 @@ asmlinkage int svr4_setcontext (svr4_ucontext_t *c, struct pt_regs *regs)
spin_unlock_irq(&current->sighand->siglock);
regs->pc = pc;
regs->npc = npc | 1;
err |= __get_user(regs->y, &((*gr) [SVR4_Y]));
err |= __get_user(psr, &((*gr) [SVR4_PSR]));
err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
err |= __get_user(psr, &((*gr)[SVR4_PSR]));
regs->psr &= ~(PSR_ICC);
regs->psr |= (psr & PSR_ICC);
/* Restore g[1..7] and o[0..7] registers */
err |= __copy_from_user(&regs->u_regs [UREG_G1], &(*gr)[SVR4_G1],
sizeof (long) * 7);
err |= __copy_from_user(&regs->u_regs [UREG_I0], &(*gr)[SVR4_O0],
sizeof (long) * 8);
err |= __copy_from_user(&regs->u_regs[UREG_G1], &(*gr)[SVR4_G1],
sizeof(long) * 7);
err |= __copy_from_user(&regs->u_regs[UREG_I0], &(*gr)[SVR4_O0],
sizeof(long) * 8);
return (err ? -EFAULT : 0);
sigsegv_and_return:
......@@ -1000,13 +1015,13 @@ handle_signal(unsigned long signr, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_SIGINFO)
new_setup_rt_frame(ka, regs, signr, oldset, info);
else if (current->thread.new_signal)
new_setup_frame (ka, regs, signr, oldset);
new_setup_frame(ka, regs, signr, oldset);
else
setup_frame(&ka->sa, regs, signr, oldset, info);
}
if(ka->sa.sa_flags & SA_ONESHOT)
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if(!(ka->sa.sa_flags & SA_NOMASK)) {
if (!(ka->sa.sa_flags & SA_NOMASK)) {
spin_lock_irq(&current->sighand->siglock);
sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
sigaddset(&current->blocked, signr);
......@@ -1028,7 +1043,7 @@ static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
regs->psr |= PSR_C;
break;
case ERESTARTSYS:
if(!(sa->sa_flags & SA_RESTART))
if (!(sa->sa_flags & SA_RESTART))
goto no_system_call_restart;
/* fallthrough */
case ERESTARTNOINTR:
......@@ -1095,13 +1110,15 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
}
asmlinkage int
do_sys_sigstack(struct sigstack *ssptr, struct sigstack *ossptr, unsigned long sp)
do_sys_sigstack(struct sigstack __user *ssptr, struct sigstack __user *ossptr,
unsigned long sp)
{
int ret = -EFAULT;
/* First see if old state is wanted. */
if (ossptr) {
if (put_user(current->sas_ss_sp + current->sas_ss_size, &ossptr->the_stack) ||
if (put_user(current->sas_ss_sp + current->sas_ss_size,
&ossptr->the_stack) ||
__put_user(on_sig_stack(sp), &ossptr->cur_status))
goto out;
}
......
......@@ -42,8 +42,8 @@ static int do_signal(sigset_t *oldset, struct pt_regs * regs,
/* {set, get}context() needed for 64-bit SparcLinux userland. */
asmlinkage void sparc64_set_context(struct pt_regs *regs)
{
struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
mc_gregset_t *grp;
struct ucontext *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0];
mc_gregset_t __user *grp;
unsigned long pc, npc, tstate;
unsigned long fp, i7;
unsigned char fenab;
......@@ -104,9 +104,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
err |= __put_user(fp,
(&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
(&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
err |= __put_user(i7,
(&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
(&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
if (fenab) {
......@@ -121,7 +121,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
(sizeof(unsigned int) * 32));
if (fprs & FPRS_DU)
err |= copy_from_user(fpregs+16,
((unsigned long *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
((unsigned long __user *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
(sizeof(unsigned int) * 32));
err |= __get_user(current_thread_info()->xfsr[0],
&(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
......@@ -139,9 +139,9 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
asmlinkage void sparc64_get_context(struct pt_regs *regs)
{
struct ucontext *ucp = (struct ucontext *) regs->u_regs[UREG_I0];
mc_gregset_t *grp;
mcontext_t *mcp;
struct ucontext *ucp = (struct ucontext __user *) regs->u_regs[UREG_I0];
mc_gregset_t __user *grp;
mcontext_t __user *mcp;
unsigned long fp, i7;
unsigned char fenab;
int err;
......@@ -170,7 +170,7 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
err = 0;
if (_NSIG_WORDS == 1)
err |= __put_user(current->blocked.sig[0],
(unsigned long *)&ucp->uc_sigmask);
(unsigned long __user *)&ucp->uc_sigmask);
else
err |= __copy_to_user(&ucp->uc_sigmask, &current->blocked,
sizeof(sigset_t));
......@@ -196,9 +196,9 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
err |= __put_user(regs->u_regs[UREG_I7], &((*grp)[MC_O7]));
err |= __get_user(fp,
(&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
(&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
err |= __get_user(i7,
(&(((struct reg_window *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
(&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
err |= __put_user(fp, &(mcp->mc_fp));
err |= __put_user(i7, &(mcp->mc_i7));
......@@ -213,7 +213,7 @@ asmlinkage void sparc64_get_context(struct pt_regs *regs)
(sizeof(unsigned int) * 32));
if (fprs & FPRS_DU)
err |= copy_to_user(
((unsigned long *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
((unsigned long __user *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
(sizeof(unsigned int) * 32));
err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
......@@ -231,7 +231,7 @@ struct rt_signal_frame {
struct sparc_stackf ss;
siginfo_t info;
struct pt_regs regs;
__siginfo_fpu_t * fpu_save;
__siginfo_fpu_t __user *fpu_save;
stack_t stack;
sigset_t mask;
__siginfo_fpu_t fpu_state;
......@@ -300,7 +300,7 @@ asmlinkage void do_sigsuspend(struct pt_regs *regs)
_sigpause_common(regs->u_regs[UREG_I0], regs);
}
asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_regs *regs)
asmlinkage void do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize, struct pt_regs *regs)
{
sigset_t oldset, set;
......@@ -351,7 +351,7 @@ asmlinkage void do_rt_sigsuspend(sigset_t *uset, size_t sigsetsize, struct pt_re
}
static inline int
restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
unsigned long *fpregs = current_thread_info()->fpregs;
unsigned long fprs;
......@@ -374,16 +374,16 @@ restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
void do_rt_sigreturn(struct pt_regs *regs)
{
struct rt_signal_frame *sf;
struct rt_signal_frame __user *sf;
unsigned long tpc, tnpc, tstate;
__siginfo_fpu_t *fpu_save;
__siginfo_fpu_t __user *fpu_save;
mm_segment_t old_fs;
sigset_t set;
stack_t st;
int err;
synchronize_user_stack ();
sf = (struct rt_signal_frame *)
sf = (struct rt_signal_frame __user *)
(regs->u_regs [UREG_FP] + STACK_BIAS);
/* 1. Make sure we are not getting garbage from the user */
......@@ -438,7 +438,7 @@ void do_rt_sigreturn(struct pt_regs *regs)
}
/* Checks if the fp is valid */
static int invalid_frame_pointer(void *fp, int fplen)
static int invalid_frame_pointer(void __user *fp, int fplen)
{
if (((unsigned long) fp) & 7)
return 1;
......@@ -446,7 +446,7 @@ static int invalid_frame_pointer(void *fp, int fplen)
}
static inline int
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
unsigned long *fpregs = (unsigned long *)(regs+1);
unsigned long fprs;
......@@ -466,7 +466,7 @@ save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t *fpu)
return err;
}
static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
{
unsigned long sp;
......@@ -478,14 +478,14 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, u
!((current->sas_ss_sp + current->sas_ss_size) & 7))
sp = current->sas_ss_sp + current->sas_ss_size;
}
return (void *)(sp - framesize);
return (void __user *)(sp - framesize);
}
static inline void
setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset, siginfo_t *info)
{
struct rt_signal_frame *sf;
struct rt_signal_frame __user *sf;
int sigframe_size, err;
/* 1. Make sure everything is clean */
......@@ -496,7 +496,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
sf = (struct rt_signal_frame *)get_sigframe(ka, regs, sigframe_size);
sf = (struct rt_signal_frame __user *)
get_sigframe(ka, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size))
goto sigill;
......@@ -521,8 +522,8 @@ setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
err |= copy_in_user((u64 *)sf,
(u64 *)(regs->u_regs[UREG_FP]+STACK_BIAS),
err |= copy_in_user((u64 __user *)sf,
(u64 __user *)(regs->u_regs[UREG_FP]+STACK_BIAS),
sizeof(struct reg_window));
if (info)
......@@ -560,7 +561,8 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka,
siginfo_t *info,
sigset_t *oldset, struct pt_regs *regs)
{
setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
setup_rt_frame(ka, regs, signr, oldset,
(ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
if (ka->sa.sa_flags & SA_ONESHOT)
ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NOMASK)) {
......
......@@ -56,7 +56,7 @@ struct signal_sframe32 {
/* struct sigcontext32 * */ u32 sig_scptr;
int sig_address;
struct sigcontext32 sig_context;
unsigned extramask[_COMPAT_NSIG_WORDS - 1];
unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
};
/*
......@@ -68,9 +68,9 @@ struct new_signal_frame32 {
struct sparc_stackf32 ss;
__siginfo32_t info;
/* __siginfo_fpu32_t * */ u32 fpu_save;
unsigned int insns [2];
unsigned extramask[_COMPAT_NSIG_WORDS - 1];
unsigned extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
unsigned int insns[2];
unsigned int extramask[_COMPAT_NSIG_WORDS - 1];
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t v8plus;
__siginfo_fpu_t fpu_state;
......@@ -82,9 +82,9 @@ struct rt_signal_frame32 {
struct pt_regs32 regs;
compat_sigset_t mask;
/* __siginfo_fpu32_t * */ u32 fpu_save;
unsigned int insns [2];
unsigned int insns[2];
stack_t32 stack;
unsigned extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
unsigned int extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
/* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
siginfo_extra_v8plus_t v8plus;
__siginfo_fpu_t fpu_state;
......@@ -95,11 +95,11 @@ struct rt_signal_frame32 {
#define NF_ALIGNEDSZ (((sizeof(struct new_signal_frame32) + 7) & (~7)))
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame32) + 7) & (~7)))
int copy_siginfo_to_user32(siginfo_t32 *to, siginfo_t *from)
int copy_siginfo_to_user32(siginfo_t32 __user *to, siginfo_t *from)
{
int err;
if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t32)))
return -EFAULT;
/* If you change siginfo_t structure, please be sure
......@@ -187,7 +187,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *
regs->u_regs[UREG_I0] = EINVAL;
return;
}
if (copy_from_user(&set32, (void *)(long)uset, sizeof(set32))) {
if (copy_from_user(&set32, (void __user *)(long)uset, sizeof(set32))) {
regs->tstate |= TSTATE_ICARRY;
regs->u_regs[UREG_I0] = EFAULT;
return;
......@@ -231,7 +231,7 @@ asmlinkage void do_rt_sigsuspend32(u32 uset, size_t sigsetsize, struct pt_regs *
}
}
static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
unsigned long *fpregs = current_thread_info()->fpregs;
unsigned long fprs;
......@@ -252,7 +252,7 @@ static int restore_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
void do_new_sigreturn32(struct pt_regs *regs)
{
struct new_signal_frame32 *sf;
struct new_signal_frame32 __user *sf;
unsigned int psr;
unsigned pc, npc, fpu_save;
sigset_t set;
......@@ -260,10 +260,10 @@ void do_new_sigreturn32(struct pt_regs *regs)
int err, i;
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP];
sf = (struct new_signal_frame32 __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (verify_area (VERIFY_READ, sf, sizeof (*sf)) ||
if (verify_area(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 3))
goto segv;
......@@ -302,7 +302,8 @@ void do_new_sigreturn32(struct pt_regs *regs)
if (fpu_save)
err |= restore_fpu_state32(regs, &sf->fpu_state);
err |= __get_user(seta[0], &sf->info.si_mask);
err |= copy_from_user(seta+1, &sf->extramask, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
err |= copy_from_user(seta+1, &sf->extramask,
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
if (err)
goto segv;
switch (_NSIG_WORDS) {
......@@ -324,17 +325,17 @@ void do_new_sigreturn32(struct pt_regs *regs)
asmlinkage void do_sigreturn32(struct pt_regs *regs)
{
struct sigcontext32 *scptr;
unsigned pc, npc, psr;
struct sigcontext32 __user *scptr;
unsigned int pc, npc, psr;
sigset_t set;
unsigned seta[_COMPAT_NSIG_WORDS];
unsigned int seta[_COMPAT_NSIG_WORDS];
int err;
synchronize_user_stack();
if (test_thread_flag(TIF_NEWSIGNALS))
return do_new_sigreturn32(regs);
scptr = (struct sigcontext32 *)
scptr = (struct sigcontext32 __user *)
(regs->u_regs[UREG_I0] & 0x00000000ffffffffUL);
/* Check sanity of the user arg. */
if (verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
......@@ -349,7 +350,8 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
err |= __get_user(seta[0], &scptr->sigc_mask);
/* Note that scptr + 1 points to extramask */
err |= copy_from_user(seta+1, scptr + 1, (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
err |= copy_from_user(seta+1, scptr + 1,
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
if (err)
goto segv;
switch (_NSIG_WORDS) {
......@@ -388,9 +390,8 @@ asmlinkage void do_sigreturn32(struct pt_regs *regs)
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
{
struct rt_signal_frame32 *sf;
unsigned int psr;
unsigned pc, npc, fpu_save;
struct rt_signal_frame32 __user *sf;
unsigned int psr, pc, npc, fpu_save;
mm_segment_t old_fs;
sigset_t set;
compat_sigset_t seta;
......@@ -399,10 +400,10 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
synchronize_user_stack();
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
sf = (struct rt_signal_frame32 *) regs->u_regs [UREG_FP];
sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
/* 1. Make sure we are not getting garbage from the user */
if (verify_area (VERIFY_READ, sf, sizeof (*sf)) ||
if (verify_area(VERIFY_READ, sf, sizeof(*sf)) ||
(((unsigned long) sf) & 3))
goto segv;
......@@ -471,14 +472,14 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
}
/* Checks if the fp is valid */
static int invalid_frame_pointer(void *fp, int fplen)
static int invalid_frame_pointer(void __user *fp, int fplen)
{
if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
return 1;
return 0;
}
static void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
static void __user *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned long framesize)
{
unsigned long sp;
......@@ -490,25 +491,21 @@ static void *get_sigframe(struct sigaction *sa, struct pt_regs *regs, unsigned l
if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))
sp = current->sas_ss_sp + current->sas_ss_size;
}
return (void *)(sp - framesize);
return (void __user *)(sp - framesize);
}
static void
setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *oldset, siginfo_t *info)
{
struct signal_sframe32 *sframep;
struct sigcontext32 *sc;
unsigned seta[_COMPAT_NSIG_WORDS];
struct signal_sframe32 __user *sframep;
struct sigcontext32 __user *sc;
unsigned int seta[_COMPAT_NSIG_WORDS];
int err = 0;
void *sig_address;
int sig_code;
unsigned long pc = regs->tpc;
unsigned long npc = regs->tnpc;
#if 0
int window = 0;
#endif
unsigned psr;
unsigned int psr;
if (test_thread_flag(TIF_32BIT)) {
pc &= 0xffffffff;
......@@ -518,8 +515,9 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
synchronize_user_stack();
save_and_clear_fpu();
sframep = (struct signal_sframe32 *)get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer (sframep, sizeof(*sframep))){
sframep = (struct signal_sframe32 __user *)
get_sigframe(sa, regs, SF_ALIGNEDSZ);
if (invalid_frame_pointer(sframep, sizeof(*sframep))){
/* Don't change signal code and address, so that
* post mortem debuggers can have a look.
*/
......@@ -544,32 +542,21 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
}
err |= __put_user(seta[0], &sc->sigc_mask);
err |= __copy_to_user(sframep->extramask, seta + 1,
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
err |= __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
err |= __put_user(pc, &sc->sigc_pc);
err |= __put_user(npc, &sc->sigc_npc);
psr = tstate_to_psr (regs->tstate);
psr = tstate_to_psr(regs->tstate);
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
err |= __put_user(psr, &sc->sigc_psr);
err |= __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
err |= __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
err |= __put_user(get_thread_wsaved(), &sc->sigc_oswins);
#if 0
/* w_saved is not currently used... */
if (get_thread_wsaved())
for (window = 0; window < get_thread_wsaved(); window++) {
sc->sigc_spbuf[window] =
(char *) current_thread_info()->rwbuf_stkptrs[window];
err |= copy_to_user(&sc->sigc_wbuf[window],
&current_thread_info()->reg_window[window],
sizeof(struct reg_window));
}
else
#endif
err |= copy_in_user((u32 *)sframep,
(u32 *)(regs->u_regs[UREG_FP]),
sizeof(struct reg_window32));
err |= copy_in_user((u32 __user *)sframep,
(u32 __user *)(regs->u_regs[UREG_FP]),
sizeof(struct reg_window32));
set_thread_wsaved(0); /* So process is allowed to execute. */
err |= __put_user(signr, &sframep->sig_num);
......@@ -588,7 +575,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
switch (info->si_code) {
case ILL_ILLOPC: sig_code = SUBSIG_ILLINST; break;
case ILL_PRVOPC: sig_code = SUBSIG_PRIVINST; break;
case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP (info->si_trapno); break;
case ILL_ILLTRP: sig_code = SUBSIG_BADTRAP(info->si_trapno); break;
default: sig_code = SUBSIG_STACK; break;
}
break;
......@@ -646,7 +633,7 @@ setup_frame32(struct sigaction *sa, struct pt_regs *regs, int signr, sigset_t *o
}
static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
{
unsigned long *fpregs = current_thread_info()->fpregs;
unsigned long fprs;
......@@ -669,11 +656,11 @@ static int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
int signo, sigset_t *oldset)
{
struct new_signal_frame32 *sf;
struct new_signal_frame32 __user *sf;
int sigframe_size;
u32 psr;
int i, err;
unsigned seta[_COMPAT_NSIG_WORDS];
unsigned int seta[_COMPAT_NSIG_WORDS];
/* 1. Make sure everything is clean */
synchronize_user_stack();
......@@ -683,9 +670,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
sf = (struct new_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
sf = (struct new_signal_frame32 __user *)
get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size))
if (invalid_frame_pointer(sf, sigframe_size))
goto sigill;
if (get_thread_wsaved() != 0)
......@@ -699,7 +687,7 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err = put_user(regs->tpc, &sf->info.si_regs.pc);
err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
err |= __put_user(regs->y, &sf->info.si_regs.y);
psr = tstate_to_psr (regs->tstate);
psr = tstate_to_psr(regs->tstate);
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
err |= __put_user(psr, &sf->info.si_regs.psr);
......@@ -729,10 +717,10 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
err |= __put_user(seta[0], &sf->info.si_mask);
err |= __copy_to_user(sf->extramask, seta + 1,
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned));
(_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
err |= copy_in_user((u32 *)sf,
(u32 *)(regs->u_regs[UREG_FP]),
err |= copy_in_user((u32 __user *)sf,
(u32 __user *)(regs->u_regs[UREG_FP]),
sizeof(struct reg_window32));
if (err)
......@@ -771,7 +759,8 @@ static void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
preempt_disable();
ptep = pte_offset_map(pmdp, address);
if (pte_present(*ptep)) {
unsigned long page = (unsigned long) page_address(pte_page(*ptep));
unsigned long page = (unsigned long)
page_address(pte_page(*ptep));
__asm__ __volatile__(
" membar #StoreStore\n"
......@@ -795,30 +784,29 @@ static void
setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
struct pt_regs *regs, int signr, sigset_t *oldset)
{
svr4_signal_frame_t *sfp;
svr4_gregset_t *gr;
svr4_siginfo_t *si;
svr4_mcontext_t *mc;
svr4_gwindows_t *gw;
svr4_ucontext_t *uc;
svr4_signal_frame_t __user *sfp;
svr4_gregset_t __user *gr;
svr4_siginfo_t __user *si;
svr4_mcontext_t __user *mc;
svr4_gwindows_t __user *gw;
svr4_ucontext_t __user *uc;
svr4_sigset_t setv;
#if 0
int window = 0;
#endif
unsigned psr;
unsigned int psr;
int i, err;
synchronize_user_stack();
save_and_clear_fpu();
regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
sfp = (svr4_signal_frame_t *) get_sigframe(sa, regs, sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
sfp = (svr4_signal_frame_t __user *)
get_sigframe(sa, regs,
sizeof(struct reg_window32) + SVR4_SF_ALIGNED);
if (invalid_frame_pointer (sfp, sizeof (*sfp)))
if (invalid_frame_pointer(sfp, sizeof(*sfp)))
do_exit(SIGILL);
/* Start with a clean frame pointer and fill it */
err = clear_user(sfp, sizeof (*sfp));
err = clear_user(sfp, sizeof(*sfp));
/* Setup convenience variables */
si = &sfp->si;
......@@ -838,22 +826,23 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
setv.sigbits[3] = (oldset->sig[1] >> 32);
err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
} else
err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
err |= __copy_to_user(&uc->sigmask, &setv,
2 * sizeof(unsigned int));
/* Store registers */
if (test_thread_flag(TIF_32BIT)) {
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
}
err |= __put_user(regs->tpc, &((*gr) [SVR4_PC]));
err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC]));
psr = tstate_to_psr (regs->tstate);
err |= __put_user(regs->tpc, &((*gr)[SVR4_PC]));
err |= __put_user(regs->tnpc, &((*gr)[SVR4_NPC]));
psr = tstate_to_psr(regs->tstate);
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
err |= __put_user(psr, &((*gr) [SVR4_PSR]));
err |= __put_user(regs->y, &((*gr) [SVR4_Y]));
err |= __put_user(psr, &((*gr)[SVR4_PSR]));
err |= __put_user(regs->y, &((*gr)[SVR4_Y]));
/* Copy g [1..7] and o [0..7] registers */
/* Copy g[1..7] and o[0..7] registers */
for (i = 0; i < 7; i++)
err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
for (i = 0; i < 8; i++)
......@@ -872,29 +861,7 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
/* 2. Number of windows to restore at setcontext (): */
err |= __put_user(get_thread_wsaved(), &gw->count);
/* 3. Save each valid window
* Currently, it makes a copy of the windows from the kernel copy.
* David's code for SunOS, makes the copy but keeps the pointer to
* the kernel. My version makes the pointer point to a userland
* copy of those. Mhm, I wonder if I shouldn't just ignore those
* on setcontext and use those that are on the kernel, the signal
* handler should not be modyfing those, mhm.
*
* These windows are just used in case synchronize_user_stack failed
* to flush the user windows.
*/
#if 0
for (window = 0; window < get_thread_wsaved(); window++) {
err |= __put_user((int *) &(gw->win[window]),
(int **) gw->winptr + window);
err |= copy_to_user(&gw->win[window],
&current_thread_info()->reg_window[window],
sizeof (svr4_rwindow_t));
err |= __put_user(0, (int *) gw->winptr + window);
}
#endif
/* 4. We just pay attention to the gw->count field on setcontext */
/* 3. We just pay attention to the gw->count field on setcontext */
set_thread_wsaved(0); /* So process is allowed to execute. */
/* Setup the signal information. Solaris expects a bunch of
......@@ -915,14 +882,14 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
}
/* Arguments passed to signal handler */
if (regs->u_regs [14]){
struct reg_window32 *rw = (struct reg_window32 *)
(regs->u_regs [14] & 0x00000000ffffffffUL);
err |= __put_user(signr, &rw->ins [0]);
err |= __put_user((u64)si, &rw->ins [1]);
err |= __put_user((u64)uc, &rw->ins [2]);
err |= __put_user((u64)sfp, &rw->ins [6]); /* frame pointer */
if (regs->u_regs[14]){
struct reg_window32 __user *rw = (struct reg_window32 __user *)
(regs->u_regs[14] & 0x00000000ffffffffUL);
err |= __put_user(signr, &rw->ins[0]);
err |= __put_user((u64)si, &rw->ins[1]);
err |= __put_user((u64)uc, &rw->ins[2]);
err |= __put_user((u64)sfp, &rw->ins[6]); /* frame pointer */
if (err)
goto sigsegv;
......@@ -937,20 +904,21 @@ setup_svr4_frame32(struct sigaction *sa, unsigned long pc, unsigned long npc,
}
asmlinkage int
svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
svr4_getcontext(svr4_ucontext_t __user *uc, struct pt_regs *regs)
{
svr4_gregset_t *gr;
svr4_mcontext_t *mc;
svr4_gregset_t __user *gr;
svr4_mcontext_t __user *mc;
svr4_sigset_t setv;
int i, err;
u32 psr;
synchronize_user_stack();
save_and_clear_fpu();
if (get_thread_wsaved())
do_exit (SIGSEGV);
do_exit(SIGSEGV);
err = clear_user(uc, sizeof (*uc));
err = clear_user(uc, sizeof(*uc));
/* Setup convenience variables */
mc = &uc->mcontext;
......@@ -970,19 +938,17 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
}
err |= __put_user(regs->tpc, &uc->mcontext.greg [SVR4_PC]);
err |= __put_user(regs->tnpc, &uc->mcontext.greg [SVR4_NPC]);
#if 1
err |= __put_user(0, &uc->mcontext.greg [SVR4_PSR]);
#else
i = tstate_to_psr(regs->tstate) & ~PSR_EF;
err |= __put_user(regs->tpc, &uc->mcontext.greg[SVR4_PC]);
err |= __put_user(regs->tnpc, &uc->mcontext.greg[SVR4_NPC]);
psr = tstate_to_psr(regs->tstate) & ~PSR_EF;
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
i |= PSR_EF;
err |= __put_user(i, &uc->mcontext.greg [SVR4_PSR]);
#endif
err |= __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
psr |= PSR_EF;
err |= __put_user(psr, &uc->mcontext.greg[SVR4_PSR]);
err |= __put_user(regs->y, &uc->mcontext.greg[SVR4_Y]);
/* Copy g [1..7] and o [0..7] registers */
/* Copy g[1..7] and o[0..7] registers */
for (i = 0; i < 7; i++)
err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
for (i = 0; i < 8; i++)
......@@ -1001,9 +967,9 @@ svr4_getcontext(svr4_ucontext_t *uc, struct pt_regs *regs)
/* Set the context for a svr4 application, this is Solaris way to sigreturn */
asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
asmlinkage int svr4_setcontext(svr4_ucontext_t __user *c, struct pt_regs *regs)
{
svr4_gregset_t *gr;
svr4_gregset_t __user *gr;
mm_segment_t old_fs;
u32 pc, npc, psr;
sigset_t set;
......@@ -1020,7 +986,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
goto sigsegv;
if (((unsigned long) c) & 3){
printk ("Unaligned structure passed\n");
printk("Unaligned structure passed\n");
goto sigsegv;
}
......@@ -1040,7 +1006,7 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
/* note that nPC is ored a 1, this is used to inform entry.S */
/* that we don't want it to mess with our PC and nPC */
err |= copy_from_user (&setv, &c->sigmask, sizeof(svr4_sigset_t));
err |= copy_from_user(&setv, &c->sigmask, sizeof(svr4_sigset_t));
set.sig[0] = setv.sigbits[0] | (((long)setv.sigbits[1]) << 32);
if (_NSIG_WORDS >= 2)
set.sig[1] = setv.sigbits[2] | (((long)setv.sigbits[3]) << 32);
......@@ -1069,14 +1035,11 @@ asmlinkage int svr4_setcontext(svr4_ucontext_t *c, struct pt_regs *regs)
regs->tpc &= 0xffffffff;
regs->tnpc &= 0xffffffff;
}
err |= __get_user(regs->y, &((*gr) [SVR4_Y]));
err |= __get_user(psr, &((*gr) [SVR4_PSR]));
err |= __get_user(regs->y, &((*gr)[SVR4_Y]));
err |= __get_user(psr, &((*gr)[SVR4_PSR]));
regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
regs->tstate |= psr_to_tstate_icc(psr);
#if 0
if (psr & PSR_EF)
regs->tstate |= TSTATE_PEF;
#endif
/* Restore g[1..7] and o[0..7] registers */
for (i = 0; i < 7; i++)
err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
......@@ -1094,7 +1057,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
unsigned long signr, sigset_t *oldset,
siginfo_t *info)
{
struct rt_signal_frame32 *sf;
struct rt_signal_frame32 __user *sf;
int sigframe_size;
u32 psr;
int i, err;
......@@ -1108,9 +1071,10 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
if (!(current_thread_info()->fpsaved[0] & FPRS_FEF))
sigframe_size -= sizeof(__siginfo_fpu_t);
sf = (struct rt_signal_frame32 *)get_sigframe(&ka->sa, regs, sigframe_size);
sf = (struct rt_signal_frame32 __user *)
get_sigframe(&ka->sa, regs, sigframe_size);
if (invalid_frame_pointer (sf, sigframe_size))
if (invalid_frame_pointer(sf, sigframe_size))
goto sigill;
if (get_thread_wsaved() != 0)
......@@ -1124,7 +1088,7 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
err = put_user(regs->tpc, &sf->regs.pc);
err |= __put_user(regs->tnpc, &sf->regs.npc);
err |= __put_user(regs->y, &sf->regs.y);
psr = tstate_to_psr (regs->tstate);
psr = tstate_to_psr(regs->tstate);
if (current_thread_info()->fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
err |= __put_user(psr, &sf->regs.psr);
......@@ -1133,7 +1097,8 @@ static void setup_rt_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]);
if (psr & PSR_EF) {
err |= save_fpu_state32(regs, &sf->fpu_state);
......@@ -1162,8 +1127,8 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
}
err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
err |= copy_in_user((u32 *)sf,
(u32 *)(regs->u_regs[UREG_FP]),
err |= copy_in_user((u32 __user *)sf,
(u32 __user *)(regs->u_regs[UREG_FP]),
sizeof(struct reg_window32));
if (err)
goto sigsegv;
......@@ -1204,7 +1169,8 @@ static void setup_rt_frame32(struct k_sigaction *ka, struct pt_regs *regs,
preempt_disable();
ptep = pte_offset_map(pmdp, address);
if (pte_present(*ptep)) {
unsigned long page = (unsigned long) page_address(pte_page(*ptep));
unsigned long page = (unsigned long)
page_address(pte_page(*ptep));
__asm__ __volatile__(
" membar #StoreStore\n"
......@@ -1229,7 +1195,8 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
int svr4_signal)
{
if (svr4_signal)
setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc, regs, signr, oldset);
setup_svr4_frame32(&ka->sa, regs->tpc, regs->tnpc,
regs, signr, oldset);
else {
if (ka->sa.sa_flags & SA_SIGINFO)
setup_rt_frame32(ka, regs, signr, oldset, info);
......@@ -1322,13 +1289,16 @@ struct sigstack32 {
asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
{
struct sigstack32 *ssptr = (struct sigstack32 *)((unsigned long)(u_ssptr));
struct sigstack32 *ossptr = (struct sigstack32 *)((unsigned long)(u_ossptr));
struct sigstack32 __user *ssptr =
(struct sigstack32 __user *)((unsigned long)(u_ssptr));
struct sigstack32 __user *ossptr =
(struct sigstack32 __user *)((unsigned long)(u_ossptr));
int ret = -EFAULT;
/* First see if old state is wanted. */
if (ossptr) {
if (put_user(current->sas_ss_sp + current->sas_ss_size, &ossptr->the_stack) ||
if (put_user(current->sas_ss_sp + current->sas_ss_size,
&ossptr->the_stack) ||
__put_user(on_sig_stack(sp), &ossptr->cur_status))
goto out;
}
......@@ -1339,15 +1309,18 @@ asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
if (get_user((long)ss_sp, &ssptr->the_stack))
goto out;
/* If the current stack was set with sigaltstack, don't
swap stacks while we are on it. */
* swap stacks while we are on it.
*/
ret = -EPERM;
if (current->sas_ss_sp && on_sig_stack(sp))
goto out;
/* Since we don't know the extent of the stack, and we don't
track onstack-ness, but rather calculate it, we must
presume a size. Ho hum this interface is lossy. */
* track onstack-ness, but rather calculate it, we must
* presume a size. Ho hum this interface is lossy.
*/
current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
current->sas_ss_size = SIGSTKSZ;
}
......@@ -1363,17 +1336,17 @@ asmlinkage int do_sys32_sigaltstack(u32 ussa, u32 uossa, unsigned long sp)
int ret;
mm_segment_t old_fs;
if (ussa && (get_user((long)uss.ss_sp, &((stack_t32 *)(long)ussa)->ss_sp) ||
__get_user(uss.ss_flags, &((stack_t32 *)(long)ussa)->ss_flags) ||
__get_user(uss.ss_size, &((stack_t32 *)(long)ussa)->ss_size)))
if (ussa && (get_user((long)uss.ss_sp, &((stack_t32 __user *)(long)ussa)->ss_sp) ||
__get_user(uss.ss_flags, &((stack_t32 __user *)(long)ussa)->ss_flags) ||
__get_user(uss.ss_size, &((stack_t32 __user *)(long)ussa)->ss_size)))
return -EFAULT;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = do_sigaltstack(ussa ? &uss : NULL, uossa ? &uoss : NULL, sp);
set_fs(old_fs);
if (!ret && uossa && (put_user((long)uoss.ss_sp, &((stack_t32 *)(long)uossa)->ss_sp) ||
__put_user(uoss.ss_flags, &((stack_t32 *)(long)uossa)->ss_flags) ||
__put_user(uoss.ss_size, &((stack_t32 *)(long)uossa)->ss_size)))
if (!ret && uossa && (put_user((long)uoss.ss_sp, &((stack_t32 __user *)(long)uossa)->ss_sp) ||
__put_user(uoss.ss_flags, &((stack_t32 __user *)(long)uossa)->ss_flags) ||
__put_user(uoss.ss_size, &((stack_t32 __user *)(long)uossa)->ss_size)))
return -EFAULT;
return ret;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment