|
From: Kenn H. <ke...@us...> - 2003-08-23 00:20:50
|
Update of /cvsroot/linux-vax/kernel-2.5/arch/vax/kernel
In directory sc8-pr-cvs1:/tmp/cvs-serv13334/arch/vax/kernel
Modified Files:
entry.S process.c syscall.c
Log Message:
Scheduler changes in 2.5.63 mean that we need to return the 'prev'
pointer properly after context switching. We also need a separate
path for newly-created processes (ret_from_fork, rather than
ret_from_syscall, and we've probably needed this for a long time).
Also NR_syscalls disappears in 2.5.63
Index: entry.S
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.5/arch/vax/kernel/entry.S,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- entry.S 26 Jun 2003 23:27:41 -0000 1.11
+++ entry.S 23 Aug 2003 00:20:46 -0000 1.12
@@ -193,6 +193,15 @@
mtpr $31, $PR_IPL
rei
+.globl ret_from_fork
+ret_from_fork:
+ /* A newly-created thread starts here when it is first
+ scheduled. R0 will contain the previous task (the one
+ that we just scheduled away from on this CPU). */
+ pushl %r0
+ calls $1, schedule_tail
+ brb ret_from_syscall
+
/* irqvec_stray is the generic handler for all exceptions and interrupts
for which there is no registered handler. We just save all registers,
and call unhandled_exception(), passing it the return address saved
@@ -253,6 +262,8 @@
.data
.globl sys_call_table
sys_call_table:
+.globl first_syscall
+first_syscall:
.long sys_ni_syscall /* 0 - old "setup()" system call*/
.long sys_exit
.long sys_fork
@@ -476,14 +487,5 @@
.long sys_getdents64 /* 220 */
.long sys_fcntl64
.long sys_tkill
- /*
-
- * NOTE!! This doesn't have to be exact - we just have
- * to make sure we have _enough_ of the "sys_ni_syscall"
- * entries. Don't panic if you notice that this hasn't
- * been shrunk every time we add a new system call.
- */
- .rept NR_syscalls-221
- .long sys_ni_syscall
- .endr
-
+.globl last_syscall
+last_syscall:
Index: process.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.5/arch/vax/kernel/process.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- process.c 26 Jun 2003 22:15:06 -0000 1.17
+++ process.c 23 Aug 2003 00:20:47 -0000 1.18
@@ -46,13 +46,13 @@
/* nothing */
}
-void __switch_to(struct task_struct* prev, struct task_struct* next)
+struct task_struct *__switch_to(struct task_struct* prev, struct task_struct* next)
{
unsigned long pcbb; /* physical address of new pcb */
#ifdef VAX_PROCESS_DEBUG
- printk("vax_switch_to: switching %p, pid %d, state %ld -> %p, pid %d, state %ld\n",
- prev, prev->pid, prev->state, next, next->pid, next->state);
+ printk("vax_switch_to: switching %p, pid %d, state %ld -> %p, pid %d, state %ld, pc %08lx\n",
+ prev, prev->pid, prev->state, next, next->pid, next->state, next->thread.pcb.pc);
#endif
/* We should check that __pa((prev)->thread.pcb) == PR_PCBB */
@@ -60,22 +60,34 @@
/* Get phys address of next process pcb */
pcbb = virt_to_phys(&next->thread.pcb);
+ /* When 'next' starts running, R0 will hold the task pointer
+ for the process we just switched away from. This will end
+ up in R0 at ret_from_fork, for new processes and will be
+ the return value from this function for existing processes */
+ next->thread.pcb.r0 = (unsigned long) prev;
+
/* svpctx should deal with writing the stuff into *prev */
- asm(" movpsl -(%%sp) \n
- pushab 1f \n
- mtpr %3, %4 \n
- svpctx \n
- mtpr %1, %2 \n
- ldpctx \n
- rei \n
- 1: "
+ asm(" movpsl -(%%sp)
+ pushab 1f
+ mtpr %2, %3 /* Raise IPL to 31 */
+ svpctx /* Causes switch to interrupt stack */
+ mtpr %0, %1 /* Load pcbb into PR_PCCB */
+ ldpctx /* Loads registers and switches back to
+ kernel stack. Also leaves PC/PSL of
+ new process on kernel stack for an
+ immediate REI */
+ rei
+ 1:
+ ret /* return now before anything munges R0 */ "
: /* no outputs */
- : "g"(prev),
- "r"(pcbb), "g"(PR_PCBB),
+ : "r"(pcbb), "g"(PR_PCBB),
"g"(31), "g"(PR_IPL)
/* no clobbers */
);
+
+ /* Never get to here because of the RET instruction above */
+ return NULL;
}
/* This _must_ match the stack layout in effect at ret_from_syscall
@@ -99,7 +111,7 @@
};
/* Defined in entry.S */
-extern void ret_from_syscall(void);
+extern void ret_from_fork(void);
int copy_thread(int unused1, unsigned long clone_flags, unsigned long usp,
unsigned long unused2,
@@ -129,9 +141,16 @@
p->thread.pcb.ksp = (unsigned long)child_stack;
p->thread.pcb.usp = usp;
- p->thread.pcb.pc = (unsigned long)ret_from_syscall;
+ p->thread.pcb.pc = (unsigned long)ret_from_fork;
p->thread.pcb.psl = __psl;
-
+
+ /* New thread must start with IPL 31 to prevent any interrupts
+ from occuring between the time it is first scheduled (in __switch_to
+ above) and when ret_from_fork calls schedule_tail(). If an
+ interrupt comes in during this time, schedule() might get called
+ from do_irq_excep() before schedule_tail() has released the
+ runqueue lock (in finish_task_switch) */
+ p->thread.pcb.psl.ipl = 31;
/* We could speed this up by loading the register values into
the PCB and start the new thread just before the REI in
Index: syscall.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.5/arch/vax/kernel/syscall.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- syscall.c 15 Jun 2003 22:33:56 -0000 1.6
+++ syscall.c 23 Aug 2003 00:20:47 -0000 1.7
@@ -31,6 +31,8 @@
Later we'll probably re-write this in asm. */
extern unsigned long *sys_call_table[256];
+extern unsigned long first_syscall;
+extern unsigned long last_syscall;
void syscall_handler(struct pt_regs *regs, void *excep_info)
{
@@ -40,7 +42,7 @@
chmk_arg = *(unsigned int *)(excep_info);
- if (chmk_arg >= NR_syscalls) {
+ if (chmk_arg >= (&last_syscall - &first_syscall)) {
regs->r0 = -ENOSYS;
return;
}
|