summaryrefslogtreecommitdiff
path: root/sys/arch/m88k
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-11-10 19:19:51 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-11-10 19:19:51 +0000
commitb32df8f435769c1c1761a730e9305c69fa7f7e19 (patch)
treec6990d437accac3bfbfb0292957055038166c9e3 /sys/arch/m88k
parent6d4f49cc464a262493f291ad7e7794f0563f0b9d (diff)
Fetch syscall arguments beyond r9 with copyin() from the userland stack,
instead of having the userland syscall code put the first three locations from the stack in r10-r12. This will speed-up most of the system calls (but mmap) once these fetches are removed, in a few weeks from now.
Diffstat (limited to 'sys/arch/m88k')
-rw-r--r--sys/arch/m88k/m88k/trap.c69
1 files changed, 38 insertions, 31 deletions
diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c
index 85a9c513fe2..bfa41034793 100644
--- a/sys/arch/m88k/m88k/trap.c
+++ b/sys/arch/m88k/m88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.33 2006/05/08 14:36:09 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.34 2006/11/10 19:19:50 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -1124,7 +1124,7 @@ m88100_syscall(register_t code, struct trapframe *tf)
struct sysent *callp;
struct proc *p;
int error;
- register_t args[11], rval[2], *ap;
+ register_t args[8], rval[2], *ap;
u_quad_t sticks;
uvmexp.syscalls++;
@@ -1138,13 +1138,14 @@ m88100_syscall(register_t code, struct trapframe *tf)
p->p_md.md_tf = tf;
/*
- * For 88k, all the arguments are passed in the registers (r2-r12)
+ * For 88k, all the arguments are passed in the registers (r2-r9),
+ * and further arguments (if any) on stack.
* For syscall (and __syscall), r2 (and r3) has the actual code.
* __syscall takes a quad syscall number, so that other
* arguments are at their natural alignments.
*/
ap = &tf->tf_r[2];
- nap = 11; /* r2-r12 */
+ nap = 8; /* r2-r9 */
switch (code) {
case SYS_syscall:
@@ -1160,22 +1161,26 @@ m88100_syscall(register_t code, struct trapframe *tf)
break;
}
- /* Callp currently points to syscall, which returns ENOSYS. */
if (code < 0 || code >= nsys)
callp += p->p_emul->e_nosys;
- else {
+ else
callp += code;
- i = callp->sy_argsize / sizeof(register_t);
- if (i > nap)
- panic("syscall nargs");
- /*
- * just copy them; syscall stub made sure all the
- * args are moved from user stack to registers.
- */
+
+ i = callp->sy_argsize / sizeof(register_t);
+ if (i > sizeof(args) / sizeof(register_t))
+ panic("syscall nargs");
+ if (i > nap) {
+ bcopy((caddr_t)ap, (caddr_t)args, nap * sizeof(register_t));
+ error = copyin((caddr_t)tf->tf_r[31], (caddr_t)(args + nap),
+ (i - nap) * sizeof(register_t));
+ } else {
bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
+ error = 0;
}
KERNEL_PROC_LOCK(p);
+ if (error != 0)
+ goto bad;
#ifdef SYSCALL_DEBUG
scdebug_call(p, code, args);
#endif
@@ -1193,9 +1198,6 @@ m88100_syscall(register_t code, struct trapframe *tf)
error = (*callp->sy_call)(p, args, rval);
/*
* system call will look like:
- * ld r10, r31, 32; r10,r11,r12 might be garbage.
- * ld r11, r31, 36
- * ld r12, r31, 40
* or r13, r0, <code>
* tb0 0, r0, <128> <- sxip
* br err <- snip
@@ -1241,6 +1243,7 @@ m88100_syscall(register_t code, struct trapframe *tf)
tf->tf_epsr &= ~PSR_C;
break;
default:
+bad:
if (p->p_emul->e_errno)
error = p->p_emul->e_errno[error];
tf->tf_r[2] = error;
@@ -1274,7 +1277,7 @@ m88110_syscall(register_t code, struct trapframe *tf)
struct sysent *callp;
struct proc *p;
int error;
- register_t args[11], rval[2], *ap;
+ register_t args[8], rval[2], *ap;
u_quad_t sticks;
uvmexp.syscalls++;
@@ -1288,13 +1291,14 @@ m88110_syscall(register_t code, struct trapframe *tf)
p->p_md.md_tf = tf;
/*
- * For 88k, all the arguments are passed in the registers (r2-r12)
+ * For 88k, all the arguments are passed in the registers (r2-r9),
+ * and further arguments (if any) on stack.
* For syscall (and __syscall), r2 (and r3) has the actual code.
* __syscall takes a quad syscall number, so that other
* arguments are at their natural alignments.
*/
ap = &tf->tf_r[2];
- nap = 11; /* r2-r12 */
+ nap = 8; /* r2-r9 */
switch (code) {
case SYS_syscall:
@@ -1310,21 +1314,26 @@ m88110_syscall(register_t code, struct trapframe *tf)
break;
}
- /* Callp currently points to syscall, which returns ENOSYS. */
if (code < 0 || code >= nsys)
callp += p->p_emul->e_nosys;
- else {
+ else
callp += code;
- i = callp->sy_argsize / sizeof(register_t);
- if (i > nap)
- panic("syscall nargs");
- /*
- * just copy them; syscall stub made sure all the
- * args are moved from user stack to registers.
- */
+
+ i = callp->sy_argsize / sizeof(register_t);
+ if (i > sizeof(args) > sizeof(register_t))
+ panic("syscall nargs");
+ if (i > nap) {
+ bcopy((caddr_t)ap, (caddr_t)args, nap * sizeof(register_t));
+ error = copyin((caddr_t)tf->tf_r[31], (caddr_t)(args + nap),
+ (i - nap) * sizeof(register_t));
+ } else {
bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
+ error = 0;
}
+
KERNEL_PROC_LOCK(p);
+ if (error != 0)
+ goto bad;
#ifdef SYSCALL_DEBUG
scdebug_call(p, code, args);
#endif
@@ -1342,9 +1351,6 @@ m88110_syscall(register_t code, struct trapframe *tf)
error = (*callp->sy_call)(p, args, rval);
/*
* system call will look like:
- * ld r10, r31, 32; r10,r11,r12 might be garbage.
- * ld r11, r31, 36
- * ld r12, r31, 40
* or r13, r0, <code>
* tb0 0, r0, <128> <- exip
* br err <- enip
@@ -1397,6 +1403,7 @@ m88110_syscall(register_t code, struct trapframe *tf)
tf->tf_exip += 4;
break;
default:
+bad:
if (p->p_emul->e_errno)
error = p->p_emul->e_errno[error];
tf->tf_r[2] = error;