Model this syscall.c on the i386 syscall.c. Don't have separate
syscall_fancy and syscall_plain. Use p->p_trace_enabled.
This commit is contained in:
parent
c84d2ae11b
commit
ba7104fdd4
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: syscall.c,v 1.10 2008/02/24 08:38:39 matt Exp $ */
|
||||
/* $NetBSD: syscall.c,v 1.11 2008/02/24 12:57:39 matt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1994 Ludd, University of Lule}, Sweden.
|
||||
@ -33,7 +33,7 @@
|
||||
/* All bugs are subject to removal without further notice */
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.10 2008/02/24 08:38:39 matt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.11 2008/02/24 12:57:39 matt Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
@ -59,82 +59,80 @@ __KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.10 2008/02/24 08:38:39 matt Exp $");
|
||||
#include <machine/userret.h>
|
||||
|
||||
#ifdef TRAPDEBUG
|
||||
volatile int startsysc = 0;
|
||||
int startsysc = 0;
|
||||
#define TDB(a) if (startsysc) printf a
|
||||
#else
|
||||
#define TDB(a)
|
||||
#endif
|
||||
|
||||
void syscall_plain(struct trapframe *);
|
||||
void syscall_fancy(struct trapframe *);
|
||||
void syscall(struct trapframe *);
|
||||
|
||||
void
|
||||
syscall_intern(struct proc *p)
|
||||
{
|
||||
if (trace_is_enabled(p))
|
||||
p->p_md.md_syscall = syscall_fancy;
|
||||
else
|
||||
p->p_md.md_syscall = syscall_plain;
|
||||
p->p_trace_enabled = trace_is_enabled(p);
|
||||
p->p_md.md_syscall = syscall;
|
||||
}
|
||||
|
||||
void
|
||||
syscall_plain(struct trapframe *frame)
|
||||
syscall(struct trapframe *frame)
|
||||
{
|
||||
const struct sysent *callp;
|
||||
u_quad_t oticks;
|
||||
int nsys;
|
||||
int err, rval[2], args[8];
|
||||
struct trapframe *exptr;
|
||||
int error;
|
||||
int rval[2];
|
||||
int args[2+SYS_MAXSYSARGS]; /* add two for SYS___syscall + padding */
|
||||
struct trapframe * const exptr = frame;
|
||||
struct lwp * const l = curlwp;
|
||||
struct proc * const p = l->l_proc;
|
||||
const struct emul * const emul = p->p_emul;
|
||||
const struct sysent *callp = emul->e_sysent;
|
||||
const u_quad_t oticks = p->p_sticks;
|
||||
|
||||
TDB(("trap syscall %s pc %lx, psl %lx, sp %lx, pid %d, frame %p\n",
|
||||
syscallnames[frame->code], frame->pc, frame->psl,frame->sp,
|
||||
p->p_pid,frame));
|
||||
|
||||
uvmexp.syscalls++;
|
||||
|
||||
LWP_CACHE_CREDS(l, p);
|
||||
|
||||
exptr = l->l_addr->u_pcb.framep = frame;
|
||||
callp = p->p_emul->e_sysent;
|
||||
nsys = p->p_emul->e_nsysent;
|
||||
oticks = p->p_sticks;
|
||||
l->l_addr->u_pcb.framep = frame;
|
||||
|
||||
if (frame->code == SYS___syscall) {
|
||||
err = copyin((char*)frame->ap + 4, &frame->code, sizeof(int));
|
||||
if (err)
|
||||
goto bad;
|
||||
frame->ap += 8;
|
||||
}
|
||||
|
||||
if ((unsigned long) frame->code >= nsys)
|
||||
callp += p->p_emul->e_nosys;
|
||||
if ((unsigned long) frame->code >= emul->e_nsysent)
|
||||
callp += emul->e_nosys;
|
||||
else
|
||||
callp += frame->code;
|
||||
|
||||
rval[0] = 0;
|
||||
rval[1] = frame->r1;
|
||||
|
||||
if (callp->sy_narg) {
|
||||
err = copyin((char*)frame->ap + 4, args, callp->sy_argsize);
|
||||
if (err)
|
||||
error = copyin((char*)frame->ap + 4, args, callp->sy_argsize);
|
||||
if (error)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if ((callp->sy_flags & SYCALL_MPSAFE) != 0) {
|
||||
err = (*callp->sy_call)(curlwp, args, rval);
|
||||
} else {
|
||||
KERNEL_LOCK(1, l);
|
||||
err = (*callp->sy_call)(curlwp, args, rval);
|
||||
KERNEL_UNLOCK_LAST(l);
|
||||
/*
|
||||
* Only trace if tracing is enabled and the syscall isn't indirect
|
||||
* (SYS_syscall or SYS___syscall)
|
||||
*/
|
||||
if (__predict_true(!p->p_trace_enabled)
|
||||
|| __predict_false(callp->sy_flags & SYCALL_INDIRECT)
|
||||
|| (error = trace_enter(frame->code, args, callp->sy_narg)) == 0) {
|
||||
if (__predict_true(callp->sy_flags & SYCALL_MPSAFE)) {
|
||||
error = (*callp->sy_call)(curlwp, args, rval);
|
||||
} else {
|
||||
KERNEL_LOCK(1, l);
|
||||
error = (*callp->sy_call)(curlwp, args, rval);
|
||||
KERNEL_UNLOCK_LAST(l);
|
||||
}
|
||||
}
|
||||
|
||||
exptr = l->l_addr->u_pcb.framep;
|
||||
|
||||
KASSERT(exptr == l->l_addr->u_pcb.framep);
|
||||
TDB(("return %s pc %lx, psl %lx, sp %lx, pid %d, err %d r0 %d, r1 %d, "
|
||||
"frame %p\n", syscallnames[exptr->code], exptr->pc, exptr->psl,
|
||||
exptr->sp, p->p_pid, err, rval[0], rval[1], exptr));
|
||||
exptr->sp, p->p_pid, error, rval[0], rval[1], exptr));
|
||||
bad:
|
||||
switch (err) {
|
||||
switch (error) {
|
||||
case 0:
|
||||
exptr->r1 = rval[1];
|
||||
exptr->r0 = rval[0];
|
||||
@ -145,100 +143,19 @@ bad:
|
||||
break;
|
||||
|
||||
case ERESTART:
|
||||
/* assumes CHMK $n was used */
|
||||
exptr->pc -= (exptr->code > 63 ? 4 : 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
exptr->r0 = err;
|
||||
exptr->r0 = error;
|
||||
exptr->psl |= PSL_C;
|
||||
break;
|
||||
}
|
||||
|
||||
userret(l, frame, oticks);
|
||||
}
|
||||
|
||||
void
|
||||
syscall_fancy(struct trapframe *frame)
|
||||
{
|
||||
const struct sysent *callp;
|
||||
u_quad_t oticks;
|
||||
int nsys;
|
||||
int err, rval[2], args[8];
|
||||
struct trapframe *exptr;
|
||||
struct lwp *l = curlwp;
|
||||
struct proc *p = l->l_proc;
|
||||
|
||||
TDB(("trap syscall %s pc %lx, psl %lx, sp %lx, pid %d, frame %p\n",
|
||||
syscallnames[frame->code], frame->pc, frame->psl,frame->sp,
|
||||
p->p_pid,frame));
|
||||
uvmexp.syscalls++;
|
||||
|
||||
LWP_CACHE_CREDS(l, p);
|
||||
|
||||
exptr = l->l_addr->u_pcb.framep = frame;
|
||||
callp = p->p_emul->e_sysent;
|
||||
nsys = p->p_emul->e_nsysent;
|
||||
oticks = p->p_sticks;
|
||||
|
||||
if (frame->code == SYS___syscall) {
|
||||
int g = *(int *)(frame->ap);
|
||||
|
||||
frame->code = *(int *)(frame->ap + 4);
|
||||
frame->ap += 8;
|
||||
*(int *)(frame->ap) = g - 2;
|
||||
}
|
||||
|
||||
if ((unsigned long) frame->code >= nsys)
|
||||
callp += p->p_emul->e_nosys;
|
||||
else
|
||||
callp += frame->code;
|
||||
|
||||
rval[0] = 0;
|
||||
rval[1] = frame->r1;
|
||||
if (callp->sy_narg) {
|
||||
err = copyin((char*)frame->ap + 4, args, callp->sy_argsize);
|
||||
if (err)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
KERNEL_LOCK(1, l);
|
||||
if ((err = trace_enter(frame->code, args, callp->sy_narg)) != 0)
|
||||
goto out;
|
||||
|
||||
if ((callp->sy_flags & SYCALL_MPSAFE) == 0) {
|
||||
err = (*callp->sy_call)(curlwp, args, rval);
|
||||
out:
|
||||
KERNEL_UNLOCK_LAST(l);
|
||||
} else {
|
||||
KERNEL_UNLOCK_LAST(l);
|
||||
err = (*callp->sy_call)(curlwp, args, rval);
|
||||
}
|
||||
exptr = l->l_addr->u_pcb.framep;
|
||||
TDB(("return %s pc %lx, psl %lx, sp %lx, pid %d, err %d r0 %d, r1 %d, "
|
||||
"frame %p\n", syscallnames[exptr->code], exptr->pc, exptr->psl,
|
||||
exptr->sp, p->p_pid, err, rval[0], rval[1], exptr));
|
||||
bad:
|
||||
switch (err) {
|
||||
case 0:
|
||||
exptr->r1 = rval[1];
|
||||
exptr->r0 = rval[0];
|
||||
exptr->psl &= ~PSL_C;
|
||||
break;
|
||||
|
||||
case EJUSTRETURN:
|
||||
break;
|
||||
|
||||
case ERESTART:
|
||||
exptr->pc -= (exptr->code > 63 ? 4 : 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
exptr->r0 = err;
|
||||
exptr->psl |= PSL_C;
|
||||
break;
|
||||
}
|
||||
|
||||
trace_exit(frame->code, rval, err);
|
||||
if (__predict_false(p->p_trace_enabled)
|
||||
&& __predict_true(!(callp->sy_flags & SYCALL_INDIRECT)))
|
||||
trace_exit(frame->code, rval, error);
|
||||
|
||||
userret(l, frame, oticks);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user