patch-2.1.124 linux/arch/sparc64/kernel/signal32.c
Next file: linux/arch/sparc64/kernel/smp.c
Previous file: linux/arch/sparc64/kernel/signal.c
Back to the patch index
Back to the overall index
- Lines: 589
- Date:
Sun Oct 4 10:22:43 1998
- Orig file:
v2.1.123/linux/arch/sparc64/kernel/signal32.c
- Orig date:
Thu Aug 6 14:06:31 1998
diff -u --recursive --new-file v2.1.123/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.41 1998/07/30 11:29:32 davem Exp $
+/* $Id: signal32.c,v 1.44 1998/09/25 01:09:17 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -39,6 +39,7 @@
/* #define DEBUG_SIGNALS 1 */
/* #define DEBUG_SIGNALS_TRACE 1 */
/* #define DEBUG_SIGNALS_MAPS 1 */
+/* #define DEBUG_SIGNALS_TLB 1 */
/* Signal frames: the original one (compatible with SunOS):
*
@@ -270,8 +271,10 @@
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
return;
+
segv:
- send_sig(SIGSEGV, current, 1);
+ lock_kernel();
+ do_exit(SIGSEGV);
}
asmlinkage void do_sigreturn32(struct pt_regs *regs)
@@ -329,8 +332,10 @@
regs->tstate &= ~(TSTATE_ICC);
regs->tstate |= psr_to_tstate_icc(psr);
return;
+
segv:
- send_sig(SIGSEGV, current, 1);
+ lock_kernel();
+ do_exit(SIGSEGV);
}
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
@@ -412,7 +417,8 @@
spin_unlock_irq(¤t->sigmask_lock);
return;
segv:
- send_sig(SIGSEGV, current, 1);
+ lock_kernel();
+ do_exit(SIGSEGV);
}
/* Checks if the fp is valid */
@@ -445,6 +451,7 @@
struct signal_sframe32 *sframep;
struct sigcontext32 *sc;
unsigned seta[_NSIG_WORDS32];
+ int err = 0;
#if 0
int window = 0;
@@ -472,7 +479,8 @@
sc = &sframep->sig_context;
/* We've already made sure frame pointer isn't in kernel space... */
- __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK), &sc->sigc_onstack);
+ err = __put_user((sas_ss_flags(regs->u_regs[UREG_FP]) == SS_ONSTACK),
+ &sc->sigc_onstack);
switch (_NSIG_WORDS) {
case 4: seta[7] = (oldset->sig[3] >> 32);
@@ -484,67 +492,81 @@
case 1: seta[1] = (oldset->sig[0] >> 32);
seta[0] = oldset->sig[0];
}
- __put_user(seta[0], &sc->sigc_mask);
- __copy_to_user(sframep->extramask, seta + 1, (_NSIG_WORDS32 - 1) * sizeof(unsigned));
- __put_user(regs->u_regs[UREG_FP], &sc->sigc_sp);
- __put_user(pc, &sc->sigc_pc);
- __put_user(npc, &sc->sigc_npc);
+ err |= __put_user(seta[0], &sc->sigc_mask);
+ err |= __copy_to_user(sframep->extramask, seta + 1,
+ (_NSIG_WORDS32 - 1) * sizeof(unsigned));
+ 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);
if(current->tss.fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
- __put_user(psr, &sc->sigc_psr);
- __put_user(regs->u_regs[UREG_G1], &sc->sigc_g1);
- __put_user(regs->u_regs[UREG_I0], &sc->sigc_o0);
- __put_user(current->tss.w_saved, &sc->sigc_oswins);
+ 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(current->tss.w_saved, &sc->sigc_oswins);
#if 0
/* w_saved is not currently used... */
if(current->tss.w_saved)
for(window = 0; window < current->tss.w_saved; window++) {
sc->sigc_spbuf[window] =
(char *)current->tss.rwbuf_stkptrs[window];
- copy_to_user(&sc->sigc_wbuf[window],
- ¤t->tss.reg_window[window],
- sizeof(struct reg_window));
+ err |= copy_to_user(&sc->sigc_wbuf[window],
+ ¤t->tss.reg_window[window],
+ sizeof(struct reg_window));
}
else
#endif
- copy_in_user((u32 *)sframep,
- (u32 *)(regs->u_regs[UREG_FP]),
- sizeof(struct reg_window32));
+ err |= copy_in_user((u32 *)sframep,
+ (u32 *)(regs->u_regs[UREG_FP]),
+ sizeof(struct reg_window32));
current->tss.w_saved = 0; /* So process is allowed to execute. */
- __put_user(signr, &sframep->sig_num);
+ err |= __put_user(signr, &sframep->sig_num);
if(signr == SIGSEGV ||
signr == SIGILL ||
signr == SIGFPE ||
signr == SIGBUS ||
signr == SIGEMT) {
- __put_user(current->tss.sig_desc, &sframep->sig_code);
- __put_user(current->tss.sig_address, &sframep->sig_address);
+ err |= __put_user(current->tss.sig_desc, &sframep->sig_code);
+ err |= __put_user(current->tss.sig_address, &sframep->sig_address);
} else {
- __put_user(0, &sframep->sig_code);
- __put_user(0, &sframep->sig_address);
+ err |= __put_user(0, &sframep->sig_code);
+ err |= __put_user(0, &sframep->sig_address);
}
- __put_user((u64)sc, &sframep->sig_scptr);
+ err |= __put_user((u64)sc, &sframep->sig_scptr);
+ if (err)
+ goto sigsegv;
+
regs->u_regs[UREG_FP] = (unsigned long) sframep;
regs->tpc = (unsigned long) sa->sa_handler;
regs->tnpc = (regs->tpc + 4);
+ return;
+
+sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
}
-static inline void save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
+static inline int save_fpu_state32(struct pt_regs *regs, __siginfo_fpu_t *fpu)
{
unsigned long *fpregs = (unsigned long *)(((char *)current) + AOFF_task_fpregs);
unsigned long fprs;
+ int err = 0;
fprs = current->tss.fpsaved[0];
if (fprs & FPRS_DL)
- copy_to_user(&fpu->si_float_regs[0], fpregs, (sizeof(unsigned int) * 32));
+ err |= copy_to_user(&fpu->si_float_regs[0], fpregs,
+ (sizeof(unsigned int) * 32));
if (fprs & FPRS_DU)
- copy_to_user(&fpu->si_float_regs[32], fpregs+16, (sizeof(unsigned int) * 32));
- __put_user(current->tss.xfsr[0], &fpu->si_fsr);
- __put_user(current->tss.gsr[0], &fpu->si_gsr);
- __put_user(fprs, &fpu->si_fprs);
+ err |= copy_to_user(&fpu->si_float_regs[32], fpregs+16,
+ (sizeof(unsigned int) * 32));
+ err |= __put_user(current->tss.xfsr[0], &fpu->si_fsr);
+ err |= __put_user(current->tss.gsr[0], &fpu->si_gsr);
+ err |= __put_user(fprs, &fpu->si_fprs);
+
+ return err;
}
static inline void new_setup_frame32(struct k_sigaction *ka, struct pt_regs *regs,
@@ -553,7 +575,7 @@
struct new_signal_frame32 *sf;
int sigframe_size;
u32 psr;
- int i;
+ int i, err;
unsigned seta[_NSIG_WORDS32];
/* 1. Make sure everything is clean */
@@ -583,21 +605,21 @@
}
/* 2. Save the current process state */
- put_user(regs->tpc, &sf->info.si_regs.pc);
- __put_user(regs->tnpc, &sf->info.si_regs.npc);
- __put_user(regs->y, &sf->info.si_regs.y);
+ 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);
if(current->tss.fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
- __put_user(psr, &sf->info.si_regs.psr);
+ err |= __put_user(psr, &sf->info.si_regs.psr);
for (i = 0; i < 16; i++)
- __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
+ err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
if (psr & PSR_EF) {
- save_fpu_state32(regs, &sf->fpu_state);
- __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+ err |= save_fpu_state32(regs, &sf->fpu_state);
+ err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
} else {
- __put_user(0, &sf->fpu_save);
+ err |= __put_user(0, &sf->fpu_save);
}
switch (_NSIG_WORDS) {
@@ -610,13 +632,17 @@
case 1: seta[1] = (oldset->sig[0] >> 32);
seta[0] = oldset->sig[0];
}
- __put_user(seta[0], &sf->info.si_mask);
- __copy_to_user(sf->extramask, seta + 1, (_NSIG_WORDS32 - 1) * sizeof(unsigned));
-
- copy_in_user((u32 *)sf,
- (u32 *)(regs->u_regs[UREG_FP]),
- sizeof(struct reg_window32));
+ err |= __put_user(seta[0], &sf->info.si_mask);
+ err |= __copy_to_user(sf->extramask, seta + 1,
+ (_NSIG_WORDS32 - 1) * sizeof(unsigned));
+
+ err |= copy_in_user((u32 *)sf,
+ (u32 *)(regs->u_regs[UREG_FP]),
+ sizeof(struct reg_window32));
+ if (err)
+ goto sigsegv;
+
/* 3. signal handler back-trampoline and parameters */
regs->u_regs[UREG_FP] = (unsigned long) sf;
regs->u_regs[UREG_I0] = signo;
@@ -638,8 +664,10 @@
regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
- __put_user(0x821020d8, &sf->insns[0]); /* mov __NR_sigreturn, %g1 */
- __put_user(0x91d02010, &sf->insns[1]); /* t 0x10 */
+ err = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
+ err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
+ if(err)
+ goto sigsegv;
if(pte_present(*ptep)) {
unsigned long page = pte_page(*ptep);
@@ -656,6 +684,9 @@
sigill:
lock_kernel();
do_exit(SIGILL);
+sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
}
/* Setup a Solaris stack frame */
@@ -674,7 +705,7 @@
int window = 0;
#endif
unsigned psr;
- int i;
+ int i, err;
synchronize_user_stack();
save_and_clear_fpu();
@@ -691,7 +722,7 @@
}
/* Start with a clean frame pointer and fill it */
- clear_user(sfp, sizeof (*sfp));
+ err = clear_user(sfp, sizeof (*sfp));
/* Setup convenience variables */
si = &sfp->si;
@@ -709,37 +740,37 @@
if (_NSIG_WORDS >= 2) {
setv.sigbits[2] = oldset->sig[1];
setv.sigbits[3] = (oldset->sig[1] >> 32);
- __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
+ err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
} else
- __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
+ err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
/* Store registers */
- __put_user(regs->tpc, &((*gr) [SVR4_PC]));
- __put_user(regs->tnpc, &((*gr) [SVR4_NPC]));
+ err |= __put_user(regs->tpc, &((*gr) [SVR4_PC]));
+ err |= __put_user(regs->tnpc, &((*gr) [SVR4_NPC]));
psr = tstate_to_psr (regs->tstate);
if(current->tss.fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
- __put_user(psr, &((*gr) [SVR4_PSR]));
- __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 */
for (i = 0; i < 7; i++)
- __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
+ err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
for (i = 0; i < 8; i++)
- __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
+ err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
/* Setup sigaltstack */
- __put_user(current->sas_ss_sp, &uc->stack.sp);
- __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
- __put_user(current->sas_ss_size, &uc->stack.size);
+ err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
+ err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
+ err |= __put_user(current->sas_ss_size, &uc->stack.size);
/* Save the currently window file: */
/* 1. Link sfp->uc->gwins to our windows */
- __put_user((u32)(long)gw, &mc->gwin);
+ err |= __put_user((u32)(long)gw, &mc->gwin);
/* 2. Number of windows to restore at setcontext (): */
- __put_user(current->tss.w_saved, &gw->count);
+ err |= __put_user(current->tss.w_saved, &gw->count);
/* 3. Save each valid window
* Currently, it makes a copy of the windows from the kernel copy.
@@ -754,9 +785,12 @@
*/
#if 0
for(window = 0; window < current->tss.w_saved; window++) {
- __put_user((int *) &(gw->win [window]), (int **)gw->winptr +window );
- copy_to_user(&gw->win [window], ¤t->tss.reg_window [window], sizeof (svr4_rwindow_t));
- __put_user(0, (int *)gw->winptr + window);
+ err |= __put_user((int *) &(gw->win [window]),
+ (int **)gw->winptr +window );
+ err |= copy_to_user(&gw->win [window],
+ ¤t->tss.reg_window [window],
+ sizeof (svr4_rwindow_t));
+ err |= __put_user(0, (int *)gw->winptr + window);
}
#endif
@@ -768,8 +802,10 @@
* that much currently, should use those that David already
* is providing with tss.sig_desc
*/
- __put_user(signr, &si->siginfo.signo);
- __put_user(SVR4_SINOINFO, &si->siginfo.code);
+ err |= __put_user(signr, &si->siginfo.signo);
+ err |= __put_user(SVR4_SINOINFO, &si->siginfo.code);
+ if (err)
+ goto sigsegv;
regs->u_regs[UREG_FP] = (unsigned long) sfp;
regs->tpc = (unsigned long) sa->sa_handler;
@@ -783,14 +819,22 @@
struct reg_window32 *rw = (struct reg_window32 *)
(regs->u_regs [14] & 0x00000000ffffffffUL);
- __put_user(signr, &rw->ins [0]);
- __put_user((u64)si, &rw->ins [1]);
- __put_user((u64)uc, &rw->ins [2]);
- __put_user((u64)sfp, &rw->ins [6]); /* frame pointer */
+ 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;
+
regs->u_regs[UREG_I0] = signr;
regs->u_regs[UREG_I1] = (u32)(u64) si;
regs->u_regs[UREG_I2] = (u32)(u64) uc;
}
+ return;
+
+sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
}
asmlinkage int
@@ -799,7 +843,7 @@
svr4_gregset_t *gr;
svr4_mcontext_t *mc;
svr4_sigset_t setv;
- int i;
+ int i, err;
synchronize_user_stack();
save_and_clear_fpu();
@@ -809,8 +853,7 @@
lock_kernel();
do_exit (SIGSEGV);
}
- if(clear_user(uc, sizeof (*uc)))
- return -EFAULT;
+ err = clear_user(uc, sizeof (*uc));
/* Setup convenience variables */
mc = &uc->mcontext;
@@ -821,38 +864,38 @@
if (_NSIG_WORDS >= 2) {
setv.sigbits[2] = current->blocked.sig[1];
setv.sigbits[3] = (current->blocked.sig[1] >> 32);
- __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
+ err |= __copy_to_user(&uc->sigmask, &setv, sizeof(svr4_sigset_t));
} else
- __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
+ err |= __copy_to_user(&uc->sigmask, &setv, 2 * sizeof(unsigned));
/* Store registers */
- __put_user(regs->tpc, &uc->mcontext.greg [SVR4_PC]);
- __put_user(regs->tnpc, &uc->mcontext.greg [SVR4_NPC]);
+ err |= __put_user(regs->tpc, &uc->mcontext.greg [SVR4_PC]);
+ err |= __put_user(regs->tnpc, &uc->mcontext.greg [SVR4_NPC]);
#if 1
- __put_user(0, &uc->mcontext.greg [SVR4_PSR]);
+ err |= __put_user(0, &uc->mcontext.greg [SVR4_PSR]);
#else
i = tstate_to_psr(regs->tstate) & ~PSR_EF;
if (current->tss.fpsaved[0] & FPRS_FEF)
i |= PSR_EF;
- __put_user(i, &uc->mcontext.greg [SVR4_PSR]);
+ err |= __put_user(i, &uc->mcontext.greg [SVR4_PSR]);
#endif
- __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
+ err |= __put_user(regs->y, &uc->mcontext.greg [SVR4_Y]);
/* Copy g [1..7] and o [0..7] registers */
for (i = 0; i < 7; i++)
- __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
+ err |= __put_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
for (i = 0; i < 8; i++)
- __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
+ err |= __put_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
/* Setup sigaltstack */
- __put_user(current->sas_ss_sp, &uc->stack.sp);
- __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
- __put_user(current->sas_ss_size, &uc->stack.size);
+ err |= __put_user(current->sas_ss_sp, &uc->stack.sp);
+ err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &uc->stack.flags);
+ err |= __put_user(current->sas_ss_size, &uc->stack.size);
/* The register file is not saved
* we have already stuffed all of it with sync_user_stack
*/
- return 0;
+ return (err ? -EFAULT : 0);
}
@@ -923,8 +966,8 @@
spin_unlock_irq(¤t->sigmask_lock);
regs->tpc = pc;
regs->tnpc = npc | 1;
- __get_user(regs->y, &((*gr) [SVR4_Y]));
- __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);
regs->tstate |= psr_to_tstate_icc(psr);
#if 0
@@ -933,9 +976,11 @@
#endif
/* Restore g[1..7] and o[0..7] registers */
for (i = 0; i < 7; i++)
- __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
+ err |= __get_user(regs->u_regs[UREG_G1+i], (&(*gr)[SVR4_G1])+i);
for (i = 0; i < 8; i++)
- __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
+ err |= __get_user(regs->u_regs[UREG_I0+i], (&(*gr)[SVR4_O0])+i);
+ if(err)
+ goto sigsegv;
return -EINTR;
sigsegv:
@@ -950,7 +995,7 @@
struct rt_signal_frame32 *sf;
int sigframe_size;
u32 psr;
- int i;
+ int i, err;
sigset_t32 seta;
/* 1. Make sure everything is clean */
@@ -980,27 +1025,27 @@
}
/* 2. Save the current process state */
- put_user(regs->tpc, &sf->regs.pc);
- __put_user(regs->tnpc, &sf->regs.npc);
- __put_user(regs->y, &sf->regs.y);
+ 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);
if(current->tss.fpsaved[0] & FPRS_FEF)
psr |= PSR_EF;
- __put_user(psr, &sf->regs.psr);
+ err |= __put_user(psr, &sf->regs.psr);
for (i = 0; i < 16; i++)
- __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
+ err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
if (psr & PSR_EF) {
- save_fpu_state32(regs, &sf->fpu_state);
- __put_user((u64)&sf->fpu_state, &sf->fpu_save);
+ err |= save_fpu_state32(regs, &sf->fpu_state);
+ err |= __put_user((u64)&sf->fpu_state, &sf->fpu_save);
} else {
- __put_user(0, &sf->fpu_save);
+ err |= __put_user(0, &sf->fpu_save);
}
/* Setup sigaltstack */
- __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
- __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
- __put_user(current->sas_ss_size, &sf->stack.ss_size);
+ err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
+ 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);
switch (_NSIG_WORDS) {
case 4: seta.sig[7] = (oldset->sig[3] >> 32);
@@ -1012,11 +1057,13 @@
case 1: seta.sig[1] = (oldset->sig[0] >> 32);
seta.sig[0] = oldset->sig[0];
}
- __copy_to_user(&sf->mask, &seta, sizeof(sigset_t));
+ err |= __copy_to_user(&sf->mask, &seta, sizeof(sigset_t));
- copy_in_user((u32 *)sf,
- (u32 *)(regs->u_regs[UREG_FP]),
- sizeof(struct reg_window32));
+ err |= copy_in_user((u32 *)sf,
+ (u32 *)(regs->u_regs[UREG_FP]),
+ sizeof(struct reg_window32));
+ if (err)
+ goto sigsegv;
/* 3. signal handler back-trampoline and parameters */
regs->u_regs[UREG_FP] = (unsigned long) sf;
@@ -1039,8 +1086,13 @@
regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
- __put_user(0x821020d8, &sf->insns[0]); /* mov __NR_sigreturn, %g1 */
- __put_user(0x91d02010, &sf->insns[1]); /* t 0x10 */
+ /* mov __NR_rt_sigreturn, %g1 */
+ err |= __put_user(0x82102065, &sf->insns[0]);
+
+ /* t 0x10 */
+ err |= __put_user(0x91d02010, &sf->insns[1]);
+ if (err)
+ goto sigsegv;
if(pte_present(*ptep)) {
unsigned long page = pte_page(*ptep);
@@ -1057,6 +1109,9 @@
sigill:
lock_kernel();
do_exit(SIGILL);
+sigsegv:
+ lock_kernel();
+ do_exit(SIGSEGV);
}
static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka,
@@ -1257,6 +1312,14 @@
/* Very useful to debug dynamic linker problems */
printk ("Sig %ld going for %s[%d]...\n", signr, current->comm, current->pid);
show_regs (regs);
+#ifdef DEBUG_SIGNALS_TLB
+ do {
+ extern void sparc_ultra_dump_itlb(void);
+ extern void sparc_ultra_dump_dtlb(void);
+ sparc_ultra_dump_dtlb();
+ sparc_ultra_dump_itlb();
+ } while(0);
+#endif
#ifdef DEBUG_SIGNALS_TRACE
{
struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov