patch-2.1.40 linux/arch/sparc64/kernel/process.c
Next file: linux/arch/sparc64/kernel/rtrap.S
Previous file: linux/arch/sparc64/kernel/head.S
Back to the patch index
Back to the overall index
- Lines: 96
- Date:
Sun May 18 17:10:37 1997
- Orig file:
v2.1.39/linux/arch/sparc64/kernel/process.c
- Orig date:
Thu May 15 16:48:02 1997
diff -u --recursive --new-file v2.1.39/linux/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.8 1997/05/14 20:45:06 davem Exp $
+/* $Id: process.c,v 1.11 1997/05/18 22:52:19 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -37,8 +37,6 @@
#include <asm/elf.h>
#include <asm/fpumacro.h>
-struct task_struct *current_set[NR_CPUS] = {&init_task, };
-
#ifndef __SMP__
/*
@@ -348,7 +346,14 @@
}
/* Now, this task is no longer a kernel thread. */
- current->tss.flags &= ~SPARC_FLAG_KTHREAD;
+ if(current->tss.flags & SPARC_FLAG_KTHREAD) {
+ current->tss.flags &= ~SPARC_FLAG_KTHREAD;
+
+ /* exec_mmap() set context to NO_CONTEXT, here is
+ * where we grab a new one.
+ */
+ get_mmu_context(current);
+ }
current->tss.current_ds = USER_DS;
}
@@ -418,6 +423,64 @@
return sp;
}
+/* Standard stuff. */
+static inline void shift_window_buffer(int first_win, int last_win,
+ struct thread_struct *tp)
+{
+ int i;
+
+ for(i = first_win; i < last_win; i++) {
+ tp->rwbuf_stkptrs[i] = tp->rwbuf_stkptrs[i+1];
+ memcpy(&tp->reg_window[i], &tp->reg_window[i+1],
+ sizeof(struct reg_window));
+ }
+}
+
+void synchronize_user_stack(void)
+{
+ struct thread_struct *tp = ¤t->tss;
+ unsigned long window = tp->w_saved;
+
+ flush_user_windows();
+ if(window) {
+ int winsize = REGWIN_SZ;
+
+ if(tp->flags & SPARC_FLAG_32BIT)
+ winsize = REGWIN32_SZ;
+
+ window -= 1;
+ do {
+ unsigned long sp = tp->rwbuf_stkptrs[window];
+ struct reg_window *rwin = &tp->reg_window[window];
+
+ if(!copy_to_user((char *)sp, rwin, winsize)) {
+ shift_window_buffer(window, tp->w_saved - 1, tp);
+ tp->w_saved--;
+ }
+ } while(window--);
+ }
+}
+
+void fault_in_user_windows(struct pt_regs *regs)
+{
+ struct thread_struct *tp = ¤t->tss;
+ unsigned long window = tp->w_saved;
+ int winsize = REGWIN_SZ;
+
+ if(tp->flags & SPARC_FLAG_32BIT)
+ winsize = REGWIN32_SZ;
+ if(window) {
+ window -= 1;
+ do {
+ unsigned long sp = tp->rwbuf_stkptrs[window];
+ struct reg_window *rwin = &tp->reg_window[window];
+
+ if(copy_to_user((char *)sp, rwin, winsize))
+ do_exit(SIGILL);
+ } while(window--);
+ }
+ current->tss.w_saved = 0;
+}
/* Copy a Sparc thread. The fork() return value conventions
* under SunOS are nothing short of bletcherous:
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov