From 8958999012aa6304efd2a95fc05c6d59ade00bb7 Mon Sep 17 00:00:00 2001 From: christos Date: Sun, 12 Mar 2006 02:04:26 +0000 Subject: [PATCH] welcome to syscall_intern. --- sys/arch/vax/conf/files.vax | 3 +- sys/arch/vax/include/ibcs2_machdep.h | 6 +- sys/arch/vax/include/proc.h | 6 +- sys/arch/vax/include/types.h | 3 +- sys/arch/vax/include/userret.h | 81 +++++++++ sys/arch/vax/vax/genassym.cf | 4 +- sys/arch/vax/vax/intvec.S | 7 +- sys/arch/vax/vax/syscall.c | 256 +++++++++++++++++++++++++++ sys/arch/vax/vax/trap.c | 162 +---------------- 9 files changed, 362 insertions(+), 166 deletions(-) create mode 100644 sys/arch/vax/include/userret.h create mode 100644 sys/arch/vax/vax/syscall.c diff --git a/sys/arch/vax/conf/files.vax b/sys/arch/vax/conf/files.vax index 4c0207a96eeb..4cd20aa6bf74 100644 --- a/sys/arch/vax/conf/files.vax +++ b/sys/arch/vax/conf/files.vax @@ -1,4 +1,4 @@ -# $NetBSD: files.vax,v 1.102 2005/12/11 12:19:34 christos Exp $ +# $NetBSD: files.vax,v 1.103 2006/03/12 02:04:26 christos Exp $ # # new style config file for vax architecture # @@ -343,6 +343,7 @@ file arch/vax/vax/bus_mem.c file arch/vax/vax/procfs_machdep.c procfs file arch/vax/vax/sgmap.c file arch/vax/vax/sig_machdep.c +file arch/vax/vax/syscall.c file arch/vax/vax/vm_machdep.c file arch/vax/vax/findcpu.c file arch/vax/vax/autoconf.c diff --git a/sys/arch/vax/include/ibcs2_machdep.h b/sys/arch/vax/include/ibcs2_machdep.h index ef19aedaa070..fb6e7f9ba6a9 100644 --- a/sys/arch/vax/include/ibcs2_machdep.h +++ b/sys/arch/vax/include/ibcs2_machdep.h @@ -1,4 +1,4 @@ -/* $NetBSD: ibcs2_machdep.h,v 1.8 2005/12/11 12:19:34 christos Exp $ */ +/* $NetBSD: ibcs2_machdep.h,v 1.9 2006/03/12 02:04:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -43,7 +43,11 @@ #define COFF_BADMAG(ex) (ex->f_magic != COFF_MAGIC_VAX) #define COFF_LDPGSZ 512 + #ifdef _KERNEL + +#define ibcs2_syscall_intern syscall_intern + struct exec_package; struct exec_vmcmd; diff --git a/sys/arch/vax/include/proc.h b/sys/arch/vax/include/proc.h index 852bb1fb8926..8ce021c73fe4 100644 --- a/sys/arch/vax/include/proc.h +++ b/sys/arch/vax/include/proc.h @@ -1,4 +1,4 @@ -/* $NetBSD: proc.h,v 1.7 2005/12/11 12:19:34 christos Exp $ */ +/* $NetBSD: proc.h,v 1.8 2006/03/12 02:04:26 christos Exp $ */ /* * Copyright (c) 1991 Regents of the University of California. @@ -45,7 +45,9 @@ struct mdlwp { * Machine-dependent part of the proc structure for vax. */ struct mdproc { - int md_dummy; /* Must be at least one field */ + /* Syscall handling function */ + void (*md_syscall)(struct trapframe *); + }; /* md_flags */ diff --git a/sys/arch/vax/include/types.h b/sys/arch/vax/include/types.h index 7311f98fabc9..656ac0f520c6 100644 --- a/sys/arch/vax/include/types.h +++ b/sys/arch/vax/include/types.h @@ -1,4 +1,4 @@ -/* $NetBSD: types.h,v 1.30 2005/12/24 20:07:41 perry Exp $ */ +/* $NetBSD: types.h,v 1.31 2006/03/12 02:04:26 christos Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -65,5 +65,6 @@ typedef volatile int __cpu_simple_lock_t; #define __HAVE_DEVICE_REGISTER #define __HAVE_GENERIC_SOFT_INTERRUPTS #define __HAVE_MD_RUNQUEUE +#define __HAVE_SYSCALL_INTERN #endif /* _MACHTYPES_H_ */ diff --git a/sys/arch/vax/include/userret.h b/sys/arch/vax/include/userret.h new file mode 100644 index 000000000000..cb3a467abdd3 --- /dev/null +++ b/sys/arch/vax/include/userret.h @@ -0,0 +1,81 @@ +/* $NetBSD: userret.h,v 1.1 2006/03/12 02:04:26 christos Exp $ */ + +/* + * Copyright (c) 1994 Ludd, University of Lule}, Sweden. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed at Ludd, University of Lule}. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +static __inline void +userret(struct lwp *, struct trapframe *, u_quad_t); + +/* + * Common code used by various execption handlers to + * return to usermode. + */ +static __inline void +userret(struct lwp *l, struct trapframe *frame, u_quad_t oticks) +{ + int sig; + struct proc *p = l->l_proc; + + /* Generate UNBLOCKED upcall. */ + if (l->l_flag & L_SA_BLOCKING) + sa_unblock_userret(l); + + /* Take pending signals. */ + while ((sig = CURSIG(l)) != 0) + postsig(sig); + l->l_priority = l->l_usrpri; + if (curcpu()->ci_want_resched) { + /* + * We are being preempted. + */ + preempt(0); + while ((sig = CURSIG(l)) != 0) + postsig(sig); + } + + /* Invoke per-process kernel-exit handling, if any */ + if (p->p_userret) + (p->p_userret)(l, p->p_userret_arg); + + /* + * If profiling, charge system time to the trapped pc. + */ + if (p->p_flag & P_PROFIL) { + extern int psratio; + + addupc_task(p, frame->pc, + (int)(p->p_sticks - oticks) * psratio); + } + /* Invoke any pending upcalls. */ + if (l->l_flag & L_SA_UPCALL) + sa_upcall_userret(l); + + curcpu()->ci_schedstate.spc_curpriority = l->l_priority; +} diff --git a/sys/arch/vax/vax/genassym.cf b/sys/arch/vax/vax/genassym.cf index ec6d1ef6d25b..5caea1a4d882 100644 --- a/sys/arch/vax/vax/genassym.cf +++ b/sys/arch/vax/vax/genassym.cf @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.28 2005/12/11 12:19:36 christos Exp $ +# $NetBSD: genassym.cf,v 1.29 2006/03/12 02:04:26 christos Exp $ # # Copyright (c) 1997 Ludd, University of Lule}, Sweden. # All rights reserved. @@ -53,8 +53,10 @@ define L_ADDR offsetof(struct lwp, l_addr) define L_BACK offsetof(struct lwp, l_back) define L_CPU offsetof(struct lwp, l_cpu) define L_STAT offsetof(struct lwp, l_stat) +define L_PROC offsetof(struct lwp, l_proc) define P_VMSPACE offsetof(struct proc, p_vmspace) +define P_MD_SYSCALL offsetof(struct proc, p_md.md_syscall) define PH_RLINK offsetof(struct prochd, ph_rlink) diff --git a/sys/arch/vax/vax/intvec.S b/sys/arch/vax/vax/intvec.S index a0018b02d792..f94fd62e61de 100644 --- a/sys/arch/vax/vax/intvec.S +++ b/sys/arch/vax/vax/intvec.S @@ -1,4 +1,4 @@ -/* $NetBSD: intvec.S,v 1.9 2005/12/11 12:19:36 christos Exp $ */ +/* $NetBSD: intvec.S,v 1.10 2006/03/12 02:04:26 christos Exp $ */ /* * Copyright (c) 1994, 1997 Ludd, University of Lule}, Sweden. @@ -268,10 +268,13 @@ SCBENTRY(syscall) # Main system call pushl $T_SYSCALL pushr $0xfff mfpr $PR_USP, -(%sp) + mfpr $PR_SSP, %r0 + movl CI_CURLWP(%r0), %r0 + movl L_PROC(%r0), %r0 pushl %ap pushl %fp pushl %sp # pointer to syscall frame; defined in trap.h - calls $1, _C_LABEL(syscall) + calls $1, *P_MD_SYSCALL(%r0) movl (%sp)+, %fp movl (%sp)+, %ap mtpr (%sp)+, $PR_USP diff --git a/sys/arch/vax/vax/syscall.c b/sys/arch/vax/vax/syscall.c new file mode 100644 index 000000000000..72a6fa7ec052 --- /dev/null +++ b/sys/arch/vax/vax/syscall.c @@ -0,0 +1,256 @@ +/* $NetBSD: syscall.c,v 1.1 2006/03/12 02:04:26 christos Exp $ */ + +/* + * Copyright (c) 1994 Ludd, University of Lule}, Sweden. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed at Ludd, University of Lule}. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + /* All bugs are subject to removal without further notice */ + +#include +__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.1 2006/03/12 02:04:26 christos Exp $"); + +#include "opt_multiprocessor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KTRACE +#include +#endif +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef TRAPDEBUG +volatile 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_intern(struct proc *p) +{ + if (trace_is_enabled(p)) + p->p_md.md_syscall = syscall_fancy; + else + p->p_md.md_syscall = syscall_plain; +} + +void +syscall_plain(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++; + + 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; + KERNEL_PROC_LOCK(l); + if (callp->sy_narg) { + err = copyin((char*)frame->ap + 4, args, callp->sy_argsize); + if (err) { + KERNEL_PROC_UNLOCK(l); + goto bad; + } + } + + err = (*callp->sy_call)(curlwp, args, rval); + KERNEL_PROC_UNLOCK(l); + 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; + } + + 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++; + + 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; + KERNEL_PROC_LOCK(l); + if (callp->sy_narg) { + err = copyin((char*)frame->ap + 4, args, callp->sy_argsize); + if (err) { + KERNEL_PROC_UNLOCK(l); + goto bad; + } + } + + if ((err = trace_enter(l, frame->code, frame->code, NULL, args)) != 0) + goto out; + + err = (*callp->sy_call)(curlwp, args, rval); +out: + KERNEL_PROC_UNLOCK(l); + 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(l, frame->code, args, rval, err); + + userret(l, frame, oticks); +} + +void +child_return(void *arg) +{ + struct lwp *l = arg; + + KERNEL_PROC_UNLOCK(l); + userret(l, l->l_addr->u_pcb.framep, 0); + +#ifdef KTRACE + if (KTRPOINT(l->l_proc, KTR_SYSRET)) { + KERNEL_PROC_LOCK(l); + ktrsysret(l, SYS_fork, 0, 0); + KERNEL_PROC_UNLOCK(l); + } +#endif +} diff --git a/sys/arch/vax/vax/trap.c b/sys/arch/vax/vax/trap.c index c1ca2eca04d7..a89ba00a1979 100644 --- a/sys/arch/vax/vax/trap.c +++ b/sys/arch/vax/vax/trap.c @@ -1,4 +1,4 @@ -/* $NetBSD: trap.c,v 1.99 2006/03/07 03:32:06 thorpej Exp $ */ +/* $NetBSD: trap.c,v 1.100 2006/03/12 02:04:26 christos Exp $ */ /* * Copyright (c) 1994 Ludd, University of Lule}, Sweden. @@ -33,7 +33,7 @@ /* All bugs are subject to removal without further notice */ #include -__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.99 2006/03/07 03:32:06 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.100 2006/03/12 02:04:26 christos Exp $"); #include "opt_ddb.h" #include "opt_ktrace.h" @@ -59,6 +59,7 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.99 2006/03/07 03:32:06 thorpej Exp $"); #include #include #include +#include #ifdef DDB #include @@ -69,15 +70,12 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.99 2006/03/07 03:32:06 thorpej Exp $"); #endif #ifdef TRAPDEBUG -volatile int startsysc = 0, faultdebug = 0; +volatile int faultdebug = 0; #endif int cpu_printfataltraps = 0; -static inline void userret (struct lwp *, struct trapframe *, u_quad_t); - void trap (struct trapframe *); -void syscall (struct trapframe *); const char * const traptypes[]={ "reserved addressing", @@ -111,54 +109,6 @@ int no_traps = 18; return; \ } -/* - * userret: - * - * Common code used by various execption handlers to - * return to usermode. - */ -static inline void -userret(struct lwp *l, struct trapframe *frame, u_quad_t oticks) -{ - int sig; - struct proc *p = l->l_proc; - - /* Generate UNBLOCKED upcall. */ - if (l->l_flag & L_SA_BLOCKING) - sa_unblock_userret(l); - - /* Take pending signals. */ - while ((sig = CURSIG(l)) != 0) - postsig(sig); - l->l_priority = l->l_usrpri; - if (curcpu()->ci_want_resched) { - /* - * We are being preempted. - */ - preempt(0); - while ((sig = CURSIG(l)) != 0) - postsig(sig); - } - - /* Invoke per-process kernel-exit handling, if any */ - if (p->p_userret) - (p->p_userret)(l, p->p_userret_arg); - - /* - * If profiling, charge system time to the trapped pc. - */ - if (p->p_flag & P_PROFIL) { - extern int psratio; - - addupc_task(p, frame->pc, - (int)(p->p_sticks - oticks) * psratio); - } - /* Invoke any pending upcalls. */ - if (l->l_flag & L_SA_UPCALL) - sa_upcall_userret(l); - - curcpu()->ci_schedstate.spc_curpriority = l->l_priority; -} void trap(struct trapframe *frame) @@ -386,110 +336,6 @@ setregs(struct lwp *l, struct exec_package *pack, u_long stack) exptr->r9 = (u_long) l->l_proc->p_psstr; /* for ELF */ } -void -syscall(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; - -#ifdef TRAPDEBUG -if(startsysc)printf("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); -#endif - uvmexp.syscalls++; - - 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; - KERNEL_PROC_LOCK(l); - if (callp->sy_narg) { - err = copyin((char*)frame->ap + 4, args, callp->sy_argsize); - if (err) { - KERNEL_PROC_UNLOCK(l); - goto bad; - } - } - - if ((err = trace_enter(l, frame->code, frame->code, NULL, args)) != 0) - goto out; - - err = (*callp->sy_call)(curlwp, args, rval); -out: - KERNEL_PROC_UNLOCK(l); - exptr = l->l_addr->u_pcb.framep; - -#ifdef TRAPDEBUG -if(startsysc) - printf("retur %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); /* } */ -#endif - -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(l, frame->code, args, rval, err); - - userret(l, frame, oticks); -} - -void -child_return(void *arg) -{ - struct lwp *l = arg; - - KERNEL_PROC_UNLOCK(l); - userret(l, l->l_addr->u_pcb.framep, 0); - -#ifdef KTRACE - if (KTRPOINT(l->l_proc, KTR_SYSRET)) { - KERNEL_PROC_LOCK(l); - ktrsysret(l, SYS_fork, 0, 0); - KERNEL_PROC_UNLOCK(l); - } -#endif -} /* * Start a new LWP