From owner-svn-src-all@FreeBSD.ORG Tue Jan 3 09:42:09 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0BC481065670; Tue, 3 Jan 2012 09:42:09 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id ECC7C8FC0C; Tue, 3 Jan 2012 09:42:08 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q039g8VY015210; Tue, 3 Jan 2012 09:42:08 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q039g8kH015205; Tue, 3 Jan 2012 09:42:08 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201201030942.q039g8kH015205@svn.freebsd.org> From: Konstantin Belousov Date: Tue, 3 Jan 2012 09:42:08 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r229374 - in stable/9/sys/mips: include mips X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Jan 2012 09:42:09 -0000 Author: kib Date: Tue Jan 3 09:42:08 2012 New Revision: 229374 URL: http://svn.freebsd.org/changeset/base/229374 Log: MFC r226065: Convert MIPS to the syscallenter/syscallret system call sequence handlers. Modified: stable/9/sys/mips/include/proc.h stable/9/sys/mips/mips/elf64_machdep.c stable/9/sys/mips/mips/elf_machdep.c stable/9/sys/mips/mips/trap.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/mips/include/proc.h ============================================================================== --- stable/9/sys/mips/include/proc.h Tue Jan 3 09:40:31 2012 (r229373) +++ stable/9/sys/mips/include/proc.h Tue Jan 3 09:42:08 2012 (r229374) @@ -67,11 +67,22 @@ struct mdproc { /* empty */ }; +#ifdef _KERNEL struct thread; void mips_cpu_switch(struct thread *, struct thread *, struct mtx *); void mips_cpu_throw(struct thread *, struct thread *); +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 Modified: stable/9/sys/mips/mips/elf64_machdep.c ============================================================================== --- stable/9/sys/mips/mips/elf64_machdep.c Tue Jan 3 09:40:31 2012 (r229373) +++ stable/9/sys/mips/mips/elf64_machdep.c Tue Jan 3 09:42:08 2012 (r229374) @@ -80,8 +80,8 @@ struct sysentvec elf64_freebsd_sysvec = .sv_maxssiz = NULL, .sv_flags = SV_ABI_FREEBSD | SV_LP64, .sv_set_syscall_retval = cpu_set_syscall_retval, - .sv_fetch_syscall_args = NULL, /* XXXKIB */ - .sv_syscallnames = NULL, + .sv_fetch_syscall_args = cpu_fetch_syscall_args, + .sv_syscallnames = syscallnames, .sv_schedtail = NULL, }; Modified: stable/9/sys/mips/mips/elf_machdep.c ============================================================================== --- stable/9/sys/mips/mips/elf_machdep.c Tue Jan 3 09:40:31 2012 (r229373) +++ stable/9/sys/mips/mips/elf_machdep.c Tue Jan 3 09:42:08 2012 (r229374) @@ -80,7 +80,7 @@ struct sysentvec elf64_freebsd_sysvec = .sv_maxssiz = NULL, .sv_flags = SV_ABI_FREEBSD | SV_LP64, .sv_set_syscall_retval = cpu_set_syscall_retval, - .sv_fetch_syscall_args = NULL, /* XXXKIB */ + .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, }; @@ -136,7 +136,7 @@ struct sysentvec elf32_freebsd_sysvec = .sv_maxssiz = NULL, .sv_flags = SV_ABI_FREEBSD | SV_ILP32, .sv_set_syscall_retval = cpu_set_syscall_retval, - .sv_fetch_syscall_args = NULL, /* XXXKIB */ + .sv_fetch_syscall_args = cpu_fetch_syscall_args, .sv_syscallnames = syscallnames, .sv_schedtail = NULL, }; Modified: stable/9/sys/mips/mips/trap.c ============================================================================== --- stable/9/sys/mips/mips/trap.c Tue Jan 3 09:40:31 2012 (r229373) +++ stable/9/sys/mips/mips/trap.c Tue Jan 3 09:42:08 2012 (r229374) @@ -261,6 +261,133 @@ static int emulate_unaligned_access(stru extern void fswintrberr(void); /* XXX */ +int +cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) +{ + struct trapframe *locr0 = 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 = sa->trapframe->pc; /* Remember if restart */ + if (DELAYBRANCH(sa->trapframe->cause)) /* Check BD bit */ + locr0->pc = MipsEmulateBranch(locr0, sa->trapframe->pc, 0, 0); + else + locr0->pc += sizeof(int); + sa->code = 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 = locr0->a0; + sa->args[0] = locr0->a1; + sa->args[1] = locr0->a2; + sa->args[2] = locr0->a3; + nsaved = 3; +#if defined(__mips_n32) || defined(__mips_n64) + sa->args[3] = locr0->t4; + sa->args[4] = locr0->t5; + sa->args[5] = locr0->t6; + sa->args[6] = locr0->t7; + nsaved += 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 == 0) + sa->code = locr0->a0; + else + sa->code = locr0->a1; + sa->args[0] = locr0->a2; + sa->args[1] = locr0->a3; + nsaved = 2; + break; +#endif + + default: + sa->args[0] = locr0->a0; + sa->args[1] = locr0->a1; + sa->args[2] = locr0->a2; + sa->args[3] = locr0->a3; + nsaved = 4; +#if defined (__mips_n32) || defined(__mips_n64) + sa->args[4] = locr0->t4; + sa->args[5] = locr0->t5; + sa->args[6] = locr0->t6; + sa->args[7] = locr0->t7; + nsaved += 4; +#endif + break; + } +#ifdef TRAP_DEBUG + if (trap_debug) + printf("SYSCALL #%d pid:%u\n", code, p->p_pid); +#endif + + se = td->td_proc->p_sysent; + if (se->sv_mask) + sa->code &= se->sv_mask; + + if (sa->code >= se->sv_size) + sa->callp = &se->sv_table[0]; + else + sa->callp = &se->sv_table[sa->code]; + + sa->narg = 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 = 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 != 0) { + locr0->v0 = error; + locr0->a3 = 1; + } + } else + error = 0; + + if (error == 0) { + td->td_retval[0] = 0; + td->td_retval[1] = locr0->v1; + } + + return (error); +} + +#undef __FBSDID +#define __FBSDID(x) +#include "../../kern/subr_syscall.c" + /* * Handle an exception. * Called from MipsKernGenException() or MipsUserGenException() @@ -527,177 +654,19 @@ dofault: case T_SYSCALL + T_USER: { - struct trapframe *locr0 = td->td_frame; - struct sysent *callp; - unsigned int code; - int nargs, nsaved; - register_t args[8]; + struct syscall_args sa; + int error; - 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 != 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 = trapframe->pc; /* Remember if restart */ - if (DELAYBRANCH(trapframe->cause)) { /* Check BD bit */ - locr0->pc = MipsEmulateBranch(locr0, trapframe->pc, 0, - 0); - } else { - locr0->pc += sizeof(int); - } - code = locr0->v0; - - 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 = locr0->a0; - args[0] = locr0->a1; - args[1] = locr0->a2; - args[2] = locr0->a3; - nsaved = 3; -#if defined(__mips_n32) || defined(__mips_n64) - args[3] = locr0->t4; - args[4] = locr0->t5; - args[5] = locr0->t6; - args[6] = locr0->t7; - nsaved += 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 == 0) { - code = locr0->a0; - } else { - code = locr0->a1; - } - args[0] = locr0->a2; - args[1] = locr0->a3; - nsaved = 2; - break; -#endif - - default: - args[0] = locr0->a0; - args[1] = locr0->a1; - args[2] = locr0->a2; - args[3] = locr0->a3; - nsaved = 4; -#if defined (__mips_n32) || defined(__mips_n64) - args[4] = locr0->t4; - args[5] = locr0->t5; - args[6] = locr0->t6; - args[7] = locr0->t7; - nsaved += 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 &= p->p_sysent->sv_mask; - - if (code >= p->p_sysent->sv_size) - callp = &p->p_sysent->sv_table[0]; - else - callp = &p->p_sysent->sv_table[code]; - - nargs = 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 = 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 = i; - locr0->a3 = 1; -#ifdef KTRACE - if (KTRPOINT(td, KTR_SYSCALL)) - ktrsyscall(code, nargs, args); -#endif - goto done; - } - } -#ifdef TRAP_DEBUG - if (trap_debug) { - for (i = 0; i < nargs; i++) { - printf("args[%d] = %#jx\n", i, (intmax_t)args[i]); - } - } -#endif -#ifdef SYSCALL_TRACING - printf("%s(", syscallnames[code]); - for (i = 0; i < nargs; i++) { - printf("%s%#jx", i == 0 ? "" : ", ", (intmax_t)args[i]); - } - printf(")\n"); -#endif -#ifdef KTRACE - if (KTRPOINT(td, KTR_SYSCALL)) - ktrsyscall(code, nargs, args); -#endif - td->td_retval[0] = 0; - td->td_retval[1] = locr0->v1; + sa.trapframe = trapframe; + error = syscallenter(td, &sa); #if !defined(SMP) && (defined(DDB) || defined(DEBUG)) if (trp == trapdebug) - trapdebug[TRAPSIZE - 1].code = code; + trapdebug[TRAPSIZE - 1].code = sa.code; else - trp[-1].code = code; + trp[-1].code = sa.code; #endif - STOPEVENT(p, S_SCE, nargs); - - PTRACESTOP_SC(p, td, S_PT_SCE); - i = (*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 = curthread; - locr0 = td->td_frame; -#endif - trapdebug_enter(locr0, -code); - cpu_set_syscall_retval(td, i); + trapdebug_enter(td->td_frame, -sa.code); /* * 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 >= 0 && code < SYS_MAXSYSCALL) ? - syscallnames[code] : "???"); - KASSERT(td->td_critnest == 0, - ("System call %s returning in a critical section", - (code >= 0 && code < SYS_MAXSYSCALL) ? - syscallnames[code] : "???")); - KASSERT(td->td_locks == 0, - ("System call %s returning with %d locks held", - (code >= 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); }