From owner-freebsd-mips@FreeBSD.ORG Tue Oct 4 21:52:24 2011 Return-Path: Delivered-To: mips@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8295E106566B for ; Tue, 4 Oct 2011 21:52:24 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 9867C8FC0C for ; Tue, 4 Oct 2011 21:52:23 +0000 (UTC) Received: from alf.home (alf.kiev.zoral.com.ua [10.1.1.177]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id p94LqImg088904 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 5 Oct 2011 00:52:18 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from alf.home (kostik@localhost [127.0.0.1]) by alf.home (8.14.5/8.14.5) with ESMTP id p94LqI5K090635 for ; Wed, 5 Oct 2011 00:52:18 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by alf.home (8.14.5/8.14.5/Submit) id p94LqIEk090634 for mips@freebsd.org; Wed, 5 Oct 2011 00:52:18 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: alf.home: kostik set sender to kostikbel@gmail.com using -f Date: Wed, 5 Oct 2011 00:52:18 +0300 From: Kostik Belousov To: mips@freebsd.org Message-ID: <20111004215218.GY1511@deviant.kiev.zoral.com.ua> References: <20111004211144.GW1511@deviant.kiev.zoral.com.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="GKxt9isuFuuOF2/C" Content-Disposition: inline In-Reply-To: <20111004211144.GW1511@deviant.kiev.zoral.com.ua> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-3.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: Subject: Re: Mips syscall entry point X-BeenThere: freebsd-mips@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to MIPS List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Oct 2011 21:52:24 -0000 --GKxt9isuFuuOF2/C Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Oct 05, 2011 at 12:11:44AM +0300, Kostik Belousov wrote: > Hi, > below is the patch, test-compiled for XLP64 only, which converts the > only remaining architecture MIPS to the new syscall entry sequence. > The advantage of the conversion is sharing most of the code with all > other architectures and avoiding duplication. Also, the implementation > automatically feels the missed features for the MIPS, see the BUGS s/feels/fills/, sorry > section in the ptrace(2). For the same reason, capsicum shall not work on MIPS. >=20 > I am asking for you help to debug and test the patch. Please keep me > on Cc:, I am not on the list. >=20 > Thank you. >=20 > diff --git a/sys/mips/include/proc.h b/sys/mips/include/proc.h > index 11a1f8e..4c0b0b6 100644 > --- a/sys/mips/include/proc.h > +++ b/sys/mips/include/proc.h > @@ -67,11 +67,22 @@ struct mdproc { > /* empty */ > }; > =20 > +#ifdef _KERNEL > struct thread; > =20 > void mips_cpu_switch(struct thread *, struct thread *, struct mtx *); > void mips_cpu_throw(struct thread *, struct thread *); > =20 > +struct syscall_args { > + u_int code; > + struct sysent *callp; > + register_t args[8]; > + int narg; > + struct trapframe *trapframe; > +}; > +#define HAVE_SYSCALL_ARGS_DEF 1 > +#endif > + > #ifdef __mips_n64 > #define KINFO_PROC_SIZE 1088 > #else > diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c > index c800e71..9755c70 100644 > --- a/sys/mips/mips/trap.c > +++ b/sys/mips/mips/trap.c > @@ -261,6 +261,133 @@ static int emulate_unaligned_access(struct trapfram= e *frame, int mode); > =20 > extern void fswintrberr(void); /* XXX */ > =20 > +int > +cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) > +{ > + struct trapframe *locr0 =3D td->td_frame; > + struct sysentvec *se; > + int error, nsaved; > + > + bzero(sa->args, sizeof(sa->args)); > + > + /* compute next PC after syscall instruction */ > + td->td_pcb->pcb_tpc =3D sa->trapframe->pc; /* Remember if restart */ > + if (DELAYBRANCH(sa->trapframe->cause)) /* Check BD bit */ > + locr0->pc =3D MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0); > + else > + locr0->pc +=3D sizeof(int); > + sa->code =3D locr0->v0; > + > + switch (sa->code) { > +#if defined(__mips_n32) || defined(__mips_n64) > + case SYS___syscall: > + /* > + * Quads fit in a single register in > + * new ABIs. > + * > + * XXX o64? > + */ > +#endif > + case SYS_syscall: > + /* > + * Code is first argument, followed by > + * actual args. > + */ > + sa->code =3D locr0->a0; > + sa->args[0] =3D locr0->a1; > + sa->args[1] =3D locr0->a2; > + sa->args[2] =3D locr0->a3; > + nsaved =3D 3; > +#if defined(__mips_n32) || defined(__mips_n64) > + sa->args[3] =3D locr0->t4; > + sa->args[4] =3D locr0->t5; > + sa->args[5] =3D locr0->t6; > + sa->args[6] =3D locr0->t7; > + nsaved +=3D 4; > +#endif > + break; > + > +#if defined(__mips_o32) > + case SYS___syscall: > + /* > + * Like syscall, but code is a quad, so as > + * to maintain quad alignment for the rest > + * of the arguments. > + */ > + if (_QUAD_LOWWORD =3D=3D 0) > + sa->code =3D locr0->a0; > + else > + sa->code =3D locr0->a1; > + sa->args[0] =3D locr0->a2; > + sa->args[1] =3D locr0->a3; > + nsaved =3D 2; > + break; > +#endif > + > + default: > + sa->args[0] =3D locr0->a0; > + sa->args[1] =3D locr0->a1; > + sa->args[2] =3D locr0->a2; > + sa->args[3] =3D locr0->a3; > + nsaved =3D 4; > +#if defined (__mips_n32) || defined(__mips_n64) > + sa->args[4] =3D locr0->t4; > + sa->args[5] =3D locr0->t5; > + sa->args[6] =3D locr0->t6; > + sa->args[7] =3D locr0->t7; > + nsaved +=3D 4; > +#endif > + break; > + } > +#ifdef TRAP_DEBUG > + if (trap_debug) > + printf("SYSCALL #%d pid:%u\n", code, p->p_pid); > +#endif > + > + se =3D td->td_proc->p_sysent; > + if (se->sv_mask) > + sa->code &=3D se->sv_mask; > + > + if (sa->code >=3D se->sv_size) > + sa->callp =3D &se->sv_table[0]; > + else > + sa->callp =3D &se->sv_table[sa->code]; > + > + sa->narg =3D sa->callp->sy_narg; > + > + if (sa->narg > nsaved) { > +#if defined(__mips_n32) || defined(__mips_n64) > + /* > + * XXX > + * Is this right for new ABIs? I think the 4 there > + * should be 8, size there are 8 registers to skip, > + * not 4, but I'm not certain. > + */ > + printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", sa->code, > + td->td_proc->p_pid); > +#endif > + error =3D copyin((caddr_t)(intptr_t)(locr0->sp + > + 4 * sizeof(register_t)), (caddr_t)&sa->args[nsaved], > + (u_int)(sa->narg - nsaved) * sizeof(register_t)); > + if (error !=3D 0) { > + locr0->v0 =3D error; > + locr0->a3 =3D 1; > + } > + } else > + error =3D 0; > + > + if (error =3D=3D 0) { > + td->td_retval[0] =3D 0; > + td->td_retval[1] =3D locr0->v1; > + } > + > + return (error); > +} > + > +#undef __FBSDID > +#define __FBSDID(x) > +#include "../../kern/subr_syscall.c" > + > /* > * Handle an exception. > * Called from MipsKernGenException() or MipsUserGenException() > @@ -527,155 +654,11 @@ dofault: > =20 > case T_SYSCALL + T_USER: > { > - struct trapframe *locr0 =3D td->td_frame; > - struct sysent *callp; > - unsigned int code; > - int nargs, nsaved; > - register_t args[8]; > - > - bzero(args, sizeof args); > - > - /* > - * note: PCPU_LAZY_INC() can only be used if we can > - * afford occassional inaccuracy in the count. > - */ > - PCPU_LAZY_INC(cnt.v_syscall); > - if (td->td_ucred !=3D p->p_ucred) > - cred_update_thread(td); > -#ifdef KSE > - if (p->p_flag & P_SA) > - thread_user_enter(td); > -#endif > - /* compute next PC after syscall instruction */ > - td->td_pcb->pcb_tpc =3D trapframe->pc; /* Remember if restart */ > - if (DELAYBRANCH(trapframe->cause)) { /* Check BD bit */ > - locr0->pc =3D MipsEmulateBranch(locr0, trapframe->pc, 0, > - 0); > - } else { > - locr0->pc +=3D sizeof(int); > - } > - code =3D locr0->v0; > + struct syscall_args sa; > + int error; > =20 > - switch (code) { > -#if defined(__mips_n32) || defined(__mips_n64) > - case SYS___syscall: > - /* > - * Quads fit in a single register in > - * new ABIs. > - * > - * XXX o64? > - */ > -#endif > - case SYS_syscall: > - /* > - * Code is first argument, followed by > - * actual args. > - */ > - code =3D locr0->a0; > - args[0] =3D locr0->a1; > - args[1] =3D locr0->a2; > - args[2] =3D locr0->a3; > - nsaved =3D 3; > -#if defined(__mips_n32) || defined(__mips_n64) > - args[3] =3D locr0->t4; > - args[4] =3D locr0->t5; > - args[5] =3D locr0->t6; > - args[6] =3D locr0->t7; > - nsaved +=3D 4; > -#endif > - break; > - > -#if defined(__mips_o32) > - case SYS___syscall: > - /* > - * Like syscall, but code is a quad, so as > - * to maintain quad alignment for the rest > - * of the arguments. > - */ > - if (_QUAD_LOWWORD =3D=3D 0) { > - code =3D locr0->a0; > - } else { > - code =3D locr0->a1; > - } > - args[0] =3D locr0->a2; > - args[1] =3D locr0->a3; > - nsaved =3D 2; > - break; > -#endif > - > - default: > - args[0] =3D locr0->a0; > - args[1] =3D locr0->a1; > - args[2] =3D locr0->a2; > - args[3] =3D locr0->a3; > - nsaved =3D 4; > -#if defined (__mips_n32) || defined(__mips_n64) > - args[4] =3D locr0->t4; > - args[5] =3D locr0->t5; > - args[6] =3D locr0->t6; > - args[7] =3D locr0->t7; > - nsaved +=3D 4; > -#endif > - } > -#ifdef TRAP_DEBUG > - if (trap_debug) { > - printf("SYSCALL #%d pid:%u\n", code, p->p_pid); > - } > -#endif > - > - if (p->p_sysent->sv_mask) > - code &=3D p->p_sysent->sv_mask; > - > - if (code >=3D p->p_sysent->sv_size) > - callp =3D &p->p_sysent->sv_table[0]; > - else > - callp =3D &p->p_sysent->sv_table[code]; > - > - nargs =3D callp->sy_narg; > - > - if (nargs > nsaved) { > -#if defined(__mips_n32) || defined(__mips_n64) > - /* > - * XXX > - * Is this right for new ABIs? I think the 4 there > - * should be 8, size there are 8 registers to skip, > - * not 4, but I'm not certain. > - */ > - printf("SYSCALL #%u pid:%u, nargs > nsaved.\n", code, p->p_pid); > -#endif > - i =3D copyin((caddr_t)(intptr_t)(locr0->sp + > - 4 * sizeof(register_t)), (caddr_t)&args[nsaved], > - (u_int)(nargs - nsaved) * sizeof(register_t)); > - if (i) { > - locr0->v0 =3D i; > - locr0->a3 =3D 1; > -#ifdef KTRACE > - if (KTRPOINT(td, KTR_SYSCALL)) > - ktrsyscall(code, nargs, args); > -#endif > - goto done; > - } > - } > -#ifdef TRAP_DEBUG > - if (trap_debug) { > - for (i =3D 0; i < nargs; i++) { > - printf("args[%d] =3D %#jx\n", i, (intmax_t)args[i]); > - } > - } > -#endif > -#ifdef SYSCALL_TRACING > - printf("%s(", syscallnames[code]); > - for (i =3D 0; i < nargs; i++) { > - printf("%s%#jx", i =3D=3D 0 ? "" : ", ", (intmax_t)args[i]); > - } > - printf(")\n"); > -#endif > -#ifdef KTRACE > - if (KTRPOINT(td, KTR_SYSCALL)) > - ktrsyscall(code, nargs, args); > -#endif > - td->td_retval[0] =3D 0; > - td->td_retval[1] =3D locr0->v1; > + sa.trapframe =3D trapframe; > + error =3D syscallenter(td, &sa); > =20 > #if !defined(SMP) && (defined(DDB) || defined(DEBUG)) > if (trp =3D=3D trapdebug) > @@ -683,21 +666,7 @@ dofault: > else > trp[-1].code =3D code; > #endif > - STOPEVENT(p, S_SCE, nargs); > - > - PTRACESTOP_SC(p, td, S_PT_SCE); > - i =3D (*callp->sy_call) (td, args); > -#if 0 > - /* > - * Reinitialize proc pointer `p' as it may be > - * different if this is a child returning from fork > - * syscall. > - */ > - td =3D curthread; > - locr0 =3D td->td_frame; > -#endif > trapdebug_enter(locr0, -code); > - cpu_set_syscall_retval(td, i); > =20 > /* > * The sync'ing of I & D caches for SYS_ptrace() is > @@ -705,38 +674,7 @@ dofault: > * instead of being done here under a special check > * for SYS_ptrace(). > */ > - done: > - /* > - * Check for misbehavior. > - */ > - WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", > - (code >=3D 0 && code < SYS_MAXSYSCALL) ? > - syscallnames[code] : "???"); > - KASSERT(td->td_critnest =3D=3D 0, > - ("System call %s returning in a critical section", > - (code >=3D 0 && code < SYS_MAXSYSCALL) ? > - syscallnames[code] : "???")); > - KASSERT(td->td_locks =3D=3D 0, > - ("System call %s returning with %d locks held", > - (code >=3D 0 && code < SYS_MAXSYSCALL) ? > - syscallnames[code] : "???", > - td->td_locks)); > - userret(td, trapframe); > -#ifdef KTRACE > - if (KTRPOINT(td, KTR_SYSRET)) > - ktrsysret(code, i, td->td_retval[0]); > -#endif > - /* > - * This works because errno is findable through the > - * register set. If we ever support an emulation > - * where this is not the case, this code will need > - * to be revisited. > - */ > - STOPEVENT(p, S_SCX, code); > - > - PTRACESTOP_SC(p, td, S_PT_SCX); > - > - mtx_assert(&Giant, MA_NOTOWNED); > + syscallret(td, error, &sa); > return (trapframe->pc); > } > =20 --GKxt9isuFuuOF2/C Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (FreeBSD) iEYEARECAAYFAk6LgBIACgkQC3+MBN1Mb4iM7wCgkpuaW287HeD0JK5UeQwfLzvh WG0AoIGtxYkCeoLN1suM6VmhEgUtPIMA =qTZU -----END PGP SIGNATURE----- --GKxt9isuFuuOF2/C--