From owner-freebsd-mips@FreeBSD.ORG Tue Oct 4 21:22:08 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 9AB82106564A for ; Tue, 4 Oct 2011 21:22:08 +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 073C88FC0C for ; Tue, 4 Oct 2011 21:22:07 +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 p94LBjKj068691 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 5 Oct 2011 00:11:45 +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 p94LBjGV090424 for ; Wed, 5 Oct 2011 00:11:45 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by alf.home (8.14.5/8.14.5/Submit) id p94LBj6S090423 for mips@freebsd.org; Wed, 5 Oct 2011 00:11:45 +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:11:44 +0300 From: Kostik Belousov To: mips@freebsd.org Message-ID: <20111004211144.GW1511@deviant.kiev.zoral.com.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="p3Avwa17mFFoJYCa" Content-Disposition: inline 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: 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:22:08 -0000 --p3Avwa17mFFoJYCa Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable 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 section in the ptrace(2). I am asking for you help to debug and test the patch. Please keep me on Cc:, I am not on the list. Thank you. 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 trapframe = *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 --p3Avwa17mFFoJYCa Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (FreeBSD) iEYEARECAAYFAk6LdpAACgkQC3+MBN1Mb4gz3ACgg7idBOErJyvCutgUP0GjySX6 P+kAn1a4yo7UHfgEFwpwXriITO1ZCaTr =/YZW -----END PGP SIGNATURE----- --p3Avwa17mFFoJYCa--