patch-2.1.43 linux/arch/sparc64/kernel/signal32.c
Next file: linux/arch/sparc64/kernel/sys_sparc32.c
Previous file: linux/arch/sparc64/kernel/signal.c
Back to the patch index
Back to the overall index
- Lines: 159
- Date:
Thu Jun 12 16:22:05 1997
- Orig file:
v2.1.42/linux/arch/sparc64/kernel/signal32.c
- Orig date:
Thu May 29 21:53:04 1997
diff -u --recursive --new-file v2.1.42/linux/arch/sparc64/kernel/signal32.c linux/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.10 1997/05/27 06:28:07 davem Exp $
+/* $Id: signal32.c,v 1.13 1997/06/01 05:46:09 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -139,35 +139,51 @@
void do_new_sigreturn32(struct pt_regs *regs)
{
struct new_signal_frame32 *sf;
- unsigned int psr, i;
+ unsigned int psr;
unsigned pc, npc, fpu_save, mask;
sf = (struct new_signal_frame32 *) regs->u_regs [UREG_FP];
+
/* 1. Make sure we are not getting garbage from the user */
- if (verify_area (VERIFY_READ, sf, sizeof (*sf))){
- goto segv;
- }
- if (((unsigned long) sf) & 3){
+ if (verify_area (VERIFY_READ, sf, sizeof (*sf)) ||
+ (((unsigned long) sf) & 3))
goto segv;
- }
+
get_user(pc, &sf->info.si_regs.pc);
__get_user(npc, &sf->info.si_regs.npc);
- if ((pc | npc) & 3){
+
+ if ((pc | npc) & 3)
goto segv;
- }
+
regs->tpc = pc;
regs->tnpc = npc;
/* 2. Restore the state */
__get_user(regs->y, &sf->info.si_regs.y);
__get_user(psr, &sf->info.si_regs.psr);
- for (i = 0; i < 16; i++)
- __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
+
+ __get_user(regs->u_regs[UREG_G1], &sf->info.si_regs.u_regs[UREG_G1]);
+ __get_user(regs->u_regs[UREG_G2], &sf->info.si_regs.u_regs[UREG_G2]);
+ __get_user(regs->u_regs[UREG_G3], &sf->info.si_regs.u_regs[UREG_G3]);
+ __get_user(regs->u_regs[UREG_G4], &sf->info.si_regs.u_regs[UREG_G4]);
+ __get_user(regs->u_regs[UREG_G5], &sf->info.si_regs.u_regs[UREG_G5]);
+ __get_user(regs->u_regs[UREG_G6], &sf->info.si_regs.u_regs[UREG_G6]);
+ __get_user(regs->u_regs[UREG_G7], &sf->info.si_regs.u_regs[UREG_G7]);
+ __get_user(regs->u_regs[UREG_I0], &sf->info.si_regs.u_regs[UREG_I0]);
+ __get_user(regs->u_regs[UREG_I1], &sf->info.si_regs.u_regs[UREG_I1]);
+ __get_user(regs->u_regs[UREG_I2], &sf->info.si_regs.u_regs[UREG_I2]);
+ __get_user(regs->u_regs[UREG_I3], &sf->info.si_regs.u_regs[UREG_I3]);
+ __get_user(regs->u_regs[UREG_I4], &sf->info.si_regs.u_regs[UREG_I4]);
+ __get_user(regs->u_regs[UREG_I5], &sf->info.si_regs.u_regs[UREG_I5]);
+ __get_user(regs->u_regs[UREG_I6], &sf->info.si_regs.u_regs[UREG_I6]);
+ __get_user(regs->u_regs[UREG_I7], &sf->info.si_regs.u_regs[UREG_I7]);
/* User can only change condition codes and FPU enabling in %tstate. */
regs->tstate &= ~(TSTATE_ICC | TSTATE_PEF);
regs->tstate |= psr_to_tstate_icc(psr);
- if (psr & PSR_EF) regs->tstate |= TSTATE_PEF;
+
+ if (psr & PSR_EF)
+ regs->tstate |= TSTATE_PEF;
__get_user(fpu_save, &sf->fpu_save);
if (fpu_save)
@@ -193,11 +209,12 @@
scptr = (struct sigcontext32 *) regs->u_regs[UREG_I0];
/* Check sanity of the user arg. */
if(verify_area(VERIFY_READ, scptr, sizeof(struct sigcontext32)) ||
- (((unsigned long) scptr) & 3)) {
+ (((unsigned long) scptr) & 3))
goto segv;
- }
+
__get_user(pc, &scptr->sigc_pc);
__get_user(npc, &scptr->sigc_npc);
+
if((pc | npc) & 3)
goto segv; /* Nice try. */
@@ -241,7 +258,6 @@
int old_status = current->tss.sstk_info.cur_status;
unsigned psr;
int i;
- u32 temp;
synchronize_user_stack();
sframep = (struct signal_sframe32 *) regs->u_regs[UREG_FP];
@@ -285,7 +301,10 @@
}
else
#endif
+ /* XXX Perhaps we need a copy_in_user()? -DaveM */
for (i = 0; i < 16; i++) {
+ u32 temp;
+
get_user (temp, (((u32 *)(regs->u_regs[UREG_FP]))+i));
put_user (temp, (((u32 *)sframep)+i));
}
@@ -315,13 +334,17 @@
{
#ifdef __SMP__
if (current->flags & PF_USEDFPU) {
- fpsave32(¤t->tss.float_regs[0], ¤t->tss.fsr);
+ fprs_write(FPRS_FEF);
+ fpsave32((unsigned long *)¤t->tss.float_regs[0],
+ ¤t->tss.fsr);
regs->tstate &= ~(TSTATE_PEF);
current->flags &= ~(PF_USEDFPU);
}
#else
if (current == last_task_used_math) {
- fpsave32((unsigned long *)¤t->tss.float_regs[0], ¤t->tss.fsr);
+ fprs_write(FPRS_FEF);
+ fpsave32((unsigned long *)¤t->tss.float_regs[0],
+ ¤t->tss.fsr);
last_task_used_math = 0;
regs->tstate &= ~(TSTATE_PEF);
}
@@ -338,7 +361,7 @@
{
struct new_signal_frame32 *sf;
int sigframe_size;
- u32 psr, tmp;
+ u32 psr;
int i;
/* 1. Make sure everything is clean */
@@ -349,12 +372,12 @@
sf = (struct new_signal_frame32 *)(regs->u_regs[UREG_FP] - sigframe_size);
- if (invalid_frame_pointer (sf, sigframe_size)){
+ if (invalid_frame_pointer (sf, sigframe_size)) {
lock_kernel ();
do_exit(SIGILL);
}
- if (current->tss.w_saved != 0){
+ if (current->tss.w_saved != 0) {
printk ("%s[%d]: Invalid user stack frame for "
"signal delivery.\n", current->comm, current->pid);
lock_kernel ();
@@ -378,7 +401,11 @@
}
__put_user(oldmask, &sf->info.si_mask);
+
+ /* XXX Perhaps we need a copy_in_user()? -DaveM */
for (i = 0; i < sizeof(struct reg_window32)/4; i++) {
+ u32 tmp;
+
__get_user(tmp, (((u32 *)regs->u_regs[UREG_FP])+i));
__put_user(tmp, (((u32 *)sf)+i));
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov