patch-2.1.45 linux/arch/sparc64/kernel/process.c
Next file: linux/arch/sparc64/kernel/ptrace.c
Previous file: linux/arch/sparc64/kernel/irq.c
Back to the patch index
Back to the overall index
- Lines: 186
- Date:
Wed Jul 16 20:37:21 1997
- Orig file:
v2.1.44/linux/arch/sparc64/kernel/process.c
- Orig date:
Mon Jul 7 08:18:54 1997
diff -u --recursive --new-file v2.1.44/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.26 1997/07/01 21:15:07 jj Exp $
+/* $Id: process.c,v 1.29 1997/07/17 02:20:40 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -17,6 +17,8 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
@@ -263,9 +265,6 @@
void show_regs(struct pt_regs * regs)
{
-#if __MPP__
- printk("CID: %d\n",mpp_cid());
-#endif
printk("TSTATE: %016lx TPC: %016lx TNPC: %016lx Y: %08x\n", regs->tstate,
regs->tpc, regs->tnpc, regs->y);
printk("g0: %016lx g1: %016lx g2: %016lx g3: %016lx\n",
@@ -285,9 +284,6 @@
void show_regs32(struct pt_regs32 *regs)
{
-#if __MPP__
- printk("CID: %d\n",mpp_cid());
-#endif
printk("PSR: %08x PC: %08x NPC: %08x Y: %08x\n", regs->psr,
regs->pc, regs->npc, regs->y);
printk("g0: %08x g1: %08x g2: %08x g3: %08x\n",
@@ -365,26 +361,33 @@
__asm__ __volatile__("flush %g6");
}
-static __inline__ struct sparc_stackf *
-clone_stackframe(struct sparc_stackf *dst, struct sparc_stackf *src)
+/* It's a bit more tricky when 64-bit tasks are involved... */
+static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
{
- struct sparc_stackf *sp;
-
-#if 0
- unsigned long size;
- size = ((unsigned long)src->fp) - ((unsigned long)src);
- sp = (struct sparc_stackf *)(((unsigned long)dst) - size);
+ unsigned long fp, distance, rval;
- if (copy_to_user(sp, src, size))
+ if(!(current->tss.flags & SPARC_FLAG_32BIT)) {
+ csp += STACK_BIAS;
+ psp += STACK_BIAS;
+ __get_user(fp, &(((struct reg_window *)psp)->ins[6]));
+ } else
+ __get_user(fp, &(((struct reg_window32 *)psp)->ins[6]));
+ distance = fp - psp;
+ rval = (csp - distance);
+ if(copy_in_user(rval, psp, distance))
return 0;
- if (put_user(dst, &sp->fp))
- return 0;
-#endif
- return sp;
+ if(current->tss.flags & SPARC_FLAG_32BIT) {
+ if(put_user(((u32)csp), &(((struct reg_window32 *)rval)->ins[6])))
+ return 0;
+ return rval;
+ } else {
+ if(put_user(((u64)csp - STACK_BIAS),
+ &(((struct reg_window *)rval)->ins[6])))
+ return 0;
+ return rval - STACK_BIAS;
+ }
}
-/* #define DEBUG_WINFIXUPS */
-
/* Standard stuff. */
static inline void shift_window_buffer(int first_win, int last_win,
struct thread_struct *tp)
@@ -408,9 +411,6 @@
int winsize = REGWIN_SZ;
int bias = 0;
-#ifdef DEBUG_WINFIXUPS
- printk("sus(%d", (int)window);
-#endif
if(tp->flags & SPARC_FLAG_32BIT)
winsize = REGWIN32_SZ;
else
@@ -426,9 +426,6 @@
tp->w_saved--;
}
} while(window--);
-#ifdef DEBUG_WINFIXUPS
- printk(")");
-#endif
}
}
@@ -445,9 +442,6 @@
bias = STACK_BIAS;
flush_user_windows();
window = tp->w_saved;
-#ifdef DEBUG_WINFIXUPS
- printk("fiuw(%d", (int)window);
-#endif
if(window != 0) {
window -= 1;
do {
@@ -459,9 +453,6 @@
} while(window--);
}
current->tss.w_saved = 0;
-#ifdef DEBUG_WINFIXUPS
- printk(")");
-#endif
}
/* Copy a Sparc thread. The fork() return value conventions
@@ -485,10 +476,6 @@
char *child_trap_frame;
int tframe_size;
-#if 0 /* Now all syscall entries flip off the fpu. */
- if(regs->tstate & TSTATE_PRIV)
- regs->fprs = 0;
-#endif
/* Calculate offset to stack_frame & pt_regs */
stack_offset = (((PAGE_SIZE << 1) -
((sizeof(unsigned int)*64) + (2*sizeof(unsigned long)))) &
@@ -512,23 +499,14 @@
p->tss.flags &= ~SPARC_FLAG_KTHREAD;
p->tss.current_ds = USER_DS;
p->tss.ctx = (p->mm->context & 0x1fff);
-#if 0
if (sp != regs->u_regs[UREG_FP]) {
- struct sparc_stackf *childstack;
- struct sparc_stackf *parentstack;
+ unsigned long csp;
- /*
- * This is a clone() call with supplied user stack.
- * Set some valid stack frames to give to the child.
- */
- childstack = (struct sparc_stackf *)sp;
- parentstack = (struct sparc_stackf *)regs->u_regs[UREG_FP];
- childstack = clone_stackframe(childstack, parentstack);
- if (!childstack)
+ csp = clone_stackframe(sp, regs->u_regs[UREG_FP]);
+ if(!csp)
return -EFAULT;
- childregs->u_regs[UREG_FP] = (unsigned long)childstack;
+ p->tss.kregs->u_regs[UREG_FP] = csp;
}
-#endif
}
/* Set the return value for the child. */
@@ -592,9 +570,11 @@
if(regs->u_regs[UREG_G1] == 0)
base = 1;
- error = getname((char *) regs->u_regs[base + UREG_I0], &filename);
- if(error)
- return error;
+ lock_kernel();
+ filename = getname((char *)regs->u_regs[base + UREG_I0]);
+ error = PTR_ERR(filename);
+ if(IS_ERR(filename))
+ goto out;
error = do_execve(filename, (char **) regs->u_regs[base + UREG_I1],
(char **) regs->u_regs[base + UREG_I2], regs);
putname(filename);
@@ -602,5 +582,7 @@
fprs_write(0);
regs->fprs = 0;
}
+out:
+ unlock_kernel();
return error;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov