summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2024-01-11 19:16:28 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2024-01-11 19:16:28 +0000
commitc936d21ceee5b01f5dbfec8ddf338ec38ce8077c (patch)
tree6d5db37081183ab50596ba2d8c91f48a8583c307
parented471b32aaab139bce13d84ff87af6b3a00c2a5c (diff)
Since no system call takes more than 6 arguments, and no more than one
off_t argument, there is no need to process more than 6 arguments on 64-bit platforms and 8 on 32-bit platforms. Make the syscall argument gathering code simpler by removing never-used code to fetch more arguments from the stack, and local argument arrays when pointing to the trap frame does the job. ok guenther@ jsing@
-rw-r--r--sys/arch/alpha/alpha/trap.c19
-rw-r--r--sys/arch/amd64/amd64/trap.c45
-rw-r--r--sys/arch/arm64/arm64/syscall.c24
-rw-r--r--sys/arch/m88k/m88k/trap.c52
-rw-r--r--sys/arch/mips64/mips64/trap.c26
-rw-r--r--sys/arch/powerpc/powerpc/trap.c34
-rw-r--r--sys/arch/powerpc64/powerpc64/syscall.c30
-rw-r--r--sys/arch/riscv64/riscv64/syscall.c30
-rw-r--r--sys/arch/sparc64/sparc64/trap.c36
9 files changed, 81 insertions, 215 deletions
diff --git a/sys/arch/alpha/alpha/trap.c b/sys/arch/alpha/alpha/trap.c
index c5d57de02ab..899b3edccf2 100644
--- a/sys/arch/alpha/alpha/trap.c
+++ b/sys/arch/alpha/alpha/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.110 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.111 2024/01/11 19:16:26 miod Exp $ */
/* $NetBSD: trap.c,v 1.52 2000/05/24 16:48:33 thorpej Exp $ */
/*-
@@ -501,10 +501,10 @@ syscall(u_int64_t code, struct trapframe *framep)
{
const struct sysent *callp = sysent;
struct proc *p;
- int error;
+ int error = ENOSYS;
u_int64_t opc;
u_long rval[2];
- u_long args[10]; /* XXX */
+ u_long args[6];
u_int nargs;
atomic_add_int(&uvmexp.syscalls, 1);
@@ -513,18 +513,13 @@ syscall(u_int64_t code, struct trapframe *framep)
framep->tf_regs[FRAME_SP] = alpha_pal_rdusp();
opc = framep->tf_regs[FRAME_PC] - 4;
- // XXX out of range stays on syscall0, which we assume is enosys
- if (code > 0 && code < SYS_MAXSYSCALL)
- callp += code;
+ if (code <= 0 || code >= SYS_MAXSYSCALL)
+ goto bad;
+
+ callp += code;
nargs = callp->sy_narg;
switch (nargs) {
- default:
- if (nargs > 10) /* XXX */
- panic("syscall: too many args (%d)", nargs);
- if ((error = copyin((caddr_t)(framep->tf_regs[FRAME_SP]), &args[6],
- (nargs - 6) * sizeof(u_long))))
- goto bad;
case 6:
args[5] = framep->tf_regs[FRAME_A5];
case 5:
diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c
index bccc016f790..d64f7c1af08 100644
--- a/sys/arch/amd64/amd64/trap.c
+++ b/sys/arch/amd64/amd64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.102 2023/12/12 15:30:55 deraadt Exp $ */
+/* $OpenBSD: trap.c,v 1.103 2024/01/11 19:16:26 miod Exp $ */
/* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */
/*-
@@ -550,12 +550,10 @@ ast(struct trapframe *frame)
void
syscall(struct trapframe *frame)
{
- caddr_t params;
const struct sysent *callp;
struct proc *p;
int error = ENOSYS;
- size_t argsize, argoff;
- register_t code, args[9], rval[2], *argp;
+ register_t code, args[6], rval[2], *argp;
verify_smap(__func__);
uvmexp.syscalls++;
@@ -568,36 +566,23 @@ syscall(struct trapframe *frame)
code = frame->tf_rax;
argp = &args[0];
- argoff = 0;
if (code <= 0 || code >= SYS_MAXSYSCALL)
goto bad;
callp = sysent + code;
- argsize = (callp->sy_argsize >> 3) + argoff;
- if (argsize) {
- switch (MIN(argsize, 6)) {
- case 6:
- args[5] = frame->tf_r9;
- case 5:
- args[4] = frame->tf_r8;
- case 4:
- args[3] = frame->tf_r10;
- case 3:
- args[2] = frame->tf_rdx;
- case 2:
- args[1] = frame->tf_rsi;
- case 1:
- args[0] = frame->tf_rdi;
- break;
- default:
- panic("impossible syscall argsize");
- }
- if (argsize > 6) {
- argsize -= 6;
- params = (caddr_t)frame->tf_rsp + sizeof(register_t);
- if ((error = copyin(params, &args[6], argsize << 3)))
- goto bad;
- }
+ switch (callp->sy_narg) {
+ case 6:
+ args[5] = frame->tf_r9;
+ case 5:
+ args[4] = frame->tf_r8;
+ case 4:
+ args[3] = frame->tf_r10;
+ case 3:
+ args[2] = frame->tf_rdx;
+ case 2:
+ args[1] = frame->tf_rsi;
+ case 1:
+ args[0] = frame->tf_rdi;
}
rval[0] = 0;
diff --git a/sys/arch/arm64/arm64/syscall.c b/sys/arch/arm64/arm64/syscall.c
index 675423d1cc2..21a77a019a6 100644
--- a/sys/arch/arm64/arm64/syscall.c
+++ b/sys/arch/arm64/arm64/syscall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.c,v 1.17 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: syscall.c,v 1.18 2024/01/11 19:16:26 miod Exp $ */
/*
* Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com>
*
@@ -26,16 +26,14 @@
#include <uvm/uvm_extern.h>
-#define MAXARGS 8
-
void
svc_handler(trapframe_t *frame)
{
struct proc *p = curproc;
const struct sysent *callp;
int code, error = ENOSYS;
- u_int nap = 8, nargs;
- register_t *ap, *args, copyargs[MAXARGS], rval[2];
+ u_int nargs;
+ register_t *args, rval[2];
uvmexp.syscalls++;
@@ -47,24 +45,12 @@ svc_handler(trapframe_t *frame)
frame->tf_elr += 8;
code = frame->tf_x[8];
-
- ap = &frame->tf_x[0];
-
if (code <= 0 || code >= SYS_MAXSYSCALL)
goto bad;
callp = sysent + code;
- nargs = callp->sy_argsize / sizeof(register_t);
- if (nargs <= nap) {
- args = ap;
- } else {
- KASSERT(nargs <= MAXARGS);
- memcpy(copyargs, ap, nap * sizeof(register_t));
- if ((error = copyin((void *)frame->tf_sp, copyargs + nap,
- (nargs - nap) * sizeof(register_t))))
- goto bad;
- args = copyargs;
- }
+ nargs = callp->sy_narg;
+ args = &frame->tf_x[0];
rval[0] = 0;
rval[1] = 0;
diff --git a/sys/arch/m88k/m88k/trap.c b/sys/arch/m88k/m88k/trap.c
index bc99e8cd15b..7b8211e8525 100644
--- a/sys/arch/m88k/m88k/trap.c
+++ b/sys/arch/m88k/m88k/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.131 2023/12/15 15:20:16 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.132 2024/01/11 19:16:26 miod Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* Copyright (c) 1998 Steve Murphree, Jr.
@@ -1152,39 +1152,24 @@ error_fatal(struct trapframe *frame)
void
m88100_syscall(register_t code, struct trapframe *tf)
{
- int i, nap;
const struct sysent *callp = sysent;
struct proc *p = curproc;
int error;
- register_t args[8] __aligned(8);
+ register_t *args;
register_t rval[2] __aligned(8);
- register_t *ap;
uvmexp.syscalls++;
p->p_md.md_tf = tf;
- /*
- * For 88k, all the arguments are passed in the registers (r2-r9),
- * and further arguments (if any) on stack.
- */
- ap = &tf->tf_r[2];
- nap = 8; /* r2-r9 */
-
// XXX out of range stays on syscall0, which we assume is enosys
if (code > 0 && code < SYS_MAXSYSCALL)
callp += code;
- 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));
- if ((error = copyin((caddr_t)tf->tf_r[31], args + nap,
- (i - nap) * sizeof(register_t))))
- goto bad;
- } else
- bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
+ /*
+ * For 88k, all the arguments are passed in the registers (r2-r9).
+ */
+ args = &tf->tf_r[2];
rval[0] = 0;
rval[1] = tf->tf_r[3];
@@ -1254,39 +1239,24 @@ m88100_syscall(register_t code, struct trapframe *tf)
void
m88110_syscall(register_t code, struct trapframe *tf)
{
- int i, nap;
const struct sysent *callp = sysent;
struct proc *p = curproc;
int error;
- register_t args[8] __aligned(8);
register_t rval[2] __aligned(8);
- register_t *ap;
+ register_t *args;
uvmexp.syscalls++;
p->p_md.md_tf = tf;
- /*
- * For 88k, all the arguments are passed in the registers (r2-r9),
- * and further arguments (if any) on stack.
- */
- ap = &tf->tf_r[2];
- nap = 8; /* r2-r9 */
-
// XXX out of range stays on syscall0, which we assume is enosys
if (code > 0 && code < SYS_MAXSYSCALL)
callp += code;
- 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));
- if ((error = copyin((caddr_t)tf->tf_r[31], args + nap,
- (i - nap) * sizeof(register_t))))
- goto bad;
- } else
- bcopy((caddr_t)ap, (caddr_t)args, i * sizeof(register_t));
+ /*
+ * For 88k, all the arguments are passed in the registers (r2-r9).
+ */
+ ap = &tf->tf_r[2];
rval[0] = 0;
rval[1] = tf->tf_r[3];
diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c
index 5fa9c7ef830..c4751488c23 100644
--- a/sys/arch/mips64/mips64/trap.c
+++ b/sys/arch/mips64/mips64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.170 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.171 2024/01/11 19:16:26 miod Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -400,11 +400,8 @@ fault_common_no_miss:
unsigned int code;
register_t tpc;
uint32_t branch = 0;
- int error, numarg;
- struct args {
- register_t i[8];
- } args;
- register_t rval[2];
+ int error;
+ register_t *args, rval[2];
atomic_inc_int(&uvmexp.syscalls);
@@ -428,17 +425,10 @@ fault_common_no_miss:
if (code > 0 && code < SYS_MAXSYSCALL)
callp += code;
- numarg = callp->sy_narg;
- args.i[0] = locr0->a0;
- args.i[1] = locr0->a1;
- args.i[2] = locr0->a2;
- args.i[3] = locr0->a3;
- if (numarg > 4) {
- args.i[4] = locr0->a4;
- args.i[5] = locr0->a5;
- args.i[6] = locr0->a6;
- args.i[7] = locr0->a7;
- }
+ /*
+ * This relies upon a0-a5 being contiguous in struct trapframe.
+ */
+ args = &locr0->a0;
rval[0] = 0;
rval[1] = 0;
@@ -448,7 +438,7 @@ fault_common_no_miss:
TRAPSIZE : trppos[ci->ci_cpuid]) - 1].code = code;
#endif
- error = mi_syscall(p, code, callp, args.i, rval);
+ error = mi_syscall(p, code, callp, args, rval);
switch (error) {
case 0:
diff --git a/sys/arch/powerpc/powerpc/trap.c b/sys/arch/powerpc/powerpc/trap.c
index 80931f9b0ff..85b0747b347 100644
--- a/sys/arch/powerpc/powerpc/trap.c
+++ b/sys/arch/powerpc/powerpc/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.133 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.134 2024/01/11 19:16:27 miod Exp $ */
/* $NetBSD: trap.c,v 1.3 1996/10/13 03:31:37 christos Exp $ */
/*
@@ -61,10 +61,8 @@ static int fix_unaligned(struct proc *p, struct trapframe *frame);
int badaddr(char *addr, u_int32_t len);
void trap(struct trapframe *frame);
-/* These definitions should probably be somewhere else XXX */
-#define FIRSTARG 3 /* first argument is in reg 3 */
-#define NARGREG 8 /* 8 args are in registers */
-#define MOREARGS(sp) ((caddr_t)((int)(sp) + 8)) /* more args go here */
+/* XXX This definition should probably be somewhere else */
+#define FIRSTARG 3 /* first syscall argument is in reg 3 */
#ifdef ALTIVEC
static int altivec_assist(struct proc *p, vaddr_t);
@@ -240,10 +238,8 @@ trap(struct trapframe *frame)
vaddr_t va;
int access_type;
const struct sysent *callp = sysent;
- size_t argsize;
register_t code, error;
- register_t *params, rval[2], args[10];
- int n;
+ register_t *params, rval[2];
if (frame->srr1 & PSL_PR) {
type |= EXC_USER;
@@ -360,24 +356,16 @@ trap(struct trapframe *frame)
case EXC_SC|EXC_USER:
uvmexp.syscalls++;
- params = frame->fixreg + FIRSTARG;
-
code = frame->fixreg[0];
- // XXX out of range stays on syscall0, which we assume is enosys
- if (code > 0 && code < SYS_MAXSYSCALL)
- callp += code;
-
- argsize = callp->sy_argsize;
- n = NARGREG - (params - (frame->fixreg + FIRSTARG));
- if (argsize > n * sizeof(register_t)) {
- bcopy(params, args, n * sizeof(register_t));
-
- if ((error = copyin(MOREARGS(frame->fixreg[1]),
- args + n, argsize - n * sizeof(register_t))))
- goto bad;
- params = args;
+ if (code <= 0 || code >= SYS_MAXSYSCALL) {
+ error = ENOSYS;
+ goto bad;
}
+ callp += code;
+
+ params = frame->fixreg + FIRSTARG;
+
rval[0] = 0;
rval[1] = frame->fixreg[FIRSTARG + 1];
diff --git a/sys/arch/powerpc64/powerpc64/syscall.c b/sys/arch/powerpc64/powerpc64/syscall.c
index 3d60de8616a..b7681f0489f 100644
--- a/sys/arch/powerpc64/powerpc64/syscall.c
+++ b/sys/arch/powerpc64/powerpc64/syscall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.c,v 1.13 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: syscall.c,v 1.14 2024/01/11 19:16:27 miod Exp $ */
/*
* Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com>
@@ -24,35 +24,21 @@
#include <sys/syscall.h>
#include <sys/syscall_mi.h>
-#define MAXARGS 8
-
void
syscall(struct trapframe *frame)
{
struct proc *p = curproc;
const struct sysent *callp = sysent;
- int code, error;
- int nap = 8, nargs;
- register_t *ap, *args, copyargs[MAXARGS], rval[2];
-
- ap = &frame->fixreg[3];
+ int code, error = ENOSYS;
+ register_t *args, rval[2];
code = frame->fixreg[0];
- // XXX out of range stays on syscall0, which we assume is enosys
- if (code > 0 && code < SYS_MAXSYSCALL)
- callp += code;
+ if (code <= 0 || code >= SYS_MAXSYSCALL)
+ goto bad;
- nargs = callp->sy_argsize / sizeof(register_t);
- if (nargs <= nap) {
- args = ap;
- } else {
- KASSERT(nargs <= MAXARGS);
- memcpy(copyargs, ap, nap * sizeof(register_t));
- if ((error = copyin((register_t *)frame->fixreg[1] + 8,
- copyargs + nap, (nargs - nap) * sizeof(register_t))))
- goto bad;
- args = copyargs;
- }
+ callp += code;
+
+ args = &frame->fixreg[3];
rval[0] = 0;
rval[1] = 0;
diff --git a/sys/arch/riscv64/riscv64/syscall.c b/sys/arch/riscv64/riscv64/syscall.c
index 2c02730664d..2a4e604c9f4 100644
--- a/sys/arch/riscv64/riscv64/syscall.c
+++ b/sys/arch/riscv64/riscv64/syscall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: syscall.c,v 1.18 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: syscall.c,v 1.19 2024/01/11 19:16:27 miod Exp $ */
/*
* Copyright (c) 2020 Brian Bamsch <bbamsch@google.com>
@@ -27,8 +27,6 @@
#include <machine/syscall.h>
-#define MAXARGS 8
-
static __inline struct trapframe *
process_frame(struct proc *p)
{
@@ -40,30 +38,18 @@ svc_handler(trapframe_t *frame)
{
struct proc *p = curproc;
const struct sysent *callp = sysent;
- int code, error;
- u_int nap = 8, nargs;
- register_t *ap, *args, copyargs[MAXARGS], rval[2];
+ int code, error = ENOSYS;
+ register_t *args, rval[2];
uvmexp.syscalls++;
- ap = &frame->tf_a[0];
code = frame->tf_t[0];
+ if (code <= 0 || code >= SYS_MAXSYSCALL)
+ goto bad;
- // XXX out of range stays on syscall0, which we assume is enosys
- if (code > 0 && code < SYS_MAXSYSCALL)
- callp += code;
-
- nargs = callp->sy_argsize / sizeof(register_t);
- if (nargs <= nap) {
- args = ap;
- } else {
- KASSERT(nargs <= MAXARGS);
- memcpy(copyargs, ap, nap * sizeof(register_t));
- if ((error = copyin((void *)frame->tf_sp, copyargs + nap,
- (nargs - nap) * sizeof(register_t))))
- goto bad;
- args = copyargs;
- }
+ callp += code;
+
+ args = &frame->tf_a[0];
rval[0] = 0;
rval[1] = 0;
diff --git a/sys/arch/sparc64/sparc64/trap.c b/sys/arch/sparc64/sparc64/trap.c
index deb4c527191..a2116f085a9 100644
--- a/sys/arch/sparc64/sparc64/trap.c
+++ b/sys/arch/sparc64/sparc64/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.118 2023/12/13 15:57:22 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.119 2024/01/11 19:16:27 miod Exp $ */
/* $NetBSD: trap.c,v 1.73 2001/08/09 01:03:01 eeh Exp $ */
/*
@@ -1105,14 +1105,11 @@ out:
void
syscall(struct trapframe *tf, register_t code, register_t pc)
{
- int i, nap;
- int64_t *ap;
const struct sysent *callp;
struct proc *p = curproc;
int error = ENOSYS, new;
- register_t args[8];
register_t rval[2];
- register_t *argp;
+ register_t *args;
if ((tf->tf_out[6] & 1) == 0)
sigexit(p, SIGILL);
@@ -1130,34 +1127,17 @@ syscall(struct trapframe *tf, register_t code, register_t pc)
new = code & SYSCALL_G2RFLAG;
code &= ~SYSCALL_G2RFLAG;
- /*
- * The first six system call arguments are in the six %o registers.
- * Any arguments beyond that are in the `argument extension' area
- * of the user's stack frame (see <machine/frame.h>).
- */
- ap = &tf->tf_out[0];
- nap = 6;
-
if (code <= 0 || code >= SYS_MAXSYSCALL)
goto bad;
callp = sysent + code;
- i = callp->sy_narg; /* Why divide? */
- if (i > nap) { /* usually false */
- if (i > 8)
- panic("syscall nargs");
- /* Read the whole block in */
- if ((error = copyin((caddr_t)tf->tf_out[6]
- + BIAS + offsetof(struct frame, fr_argx),
- &args[nap], (i - nap) * sizeof(register_t))))
- goto bad;
- i = nap;
- }
+
/*
- * It should be faster to do <= 6 longword copies than
- * to call bcopy
+ * The first six system call arguments are in the six %o registers.
+ * Any arguments beyond that are in the `argument extension' area
+ * of the user's stack frame (see <machine/frame.h>), but no system
+ * call currently uses more than six arguments.
*/
- for (argp = args; i--;)
- *argp++ = *ap++;
+ args = (register_t *)&tf->tf_out[0];
rval[0] = 0;
rval[1] = 0;