Module Name: src Committed By: rmind Date: Thu Apr 16 15:34:23 UTC 2009
Modified Files: src/sys/arch/amd64/conf: files.amd64 src/sys/arch/i386/conf: files.i386 src/sys/arch/x86/conf: files.x86 src/sys/arch/x86/include: cpu.h Added Files: src/sys/arch/x86/x86: syscall.c Removed Files: src/sys/arch/amd64/amd64: syscall.c src/sys/arch/i386/i386: syscall.c Log Message: - Add macros to handle (some) trapframe registers for common x86 code. - Merge i386 and amd64 syscall.c into x86. No functional changes intended. Proposed on (port-i386 & port-amd64). Unfortunately, I cannot merge these lists into the single port-x86. :( To generate a diff of this commit: cvs rdiff -u -r1.45 -r0 src/sys/arch/amd64/amd64/syscall.c cvs rdiff -u -r1.65 -r1.66 src/sys/arch/amd64/conf/files.amd64 cvs rdiff -u -r1.347 -r1.348 src/sys/arch/i386/conf/files.i386 cvs rdiff -u -r1.59 -r0 src/sys/arch/i386/i386/syscall.c cvs rdiff -u -r1.49 -r1.50 src/sys/arch/x86/conf/files.x86 cvs rdiff -u -r1.14 -r1.15 src/sys/arch/x86/include/cpu.h cvs rdiff -u -r0 -r1.1 src/sys/arch/x86/x86/syscall.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/conf/files.amd64 diff -u src/sys/arch/amd64/conf/files.amd64:1.65 src/sys/arch/amd64/conf/files.amd64:1.66 --- src/sys/arch/amd64/conf/files.amd64:1.65 Mon Mar 30 22:28:39 2009 +++ src/sys/arch/amd64/conf/files.amd64 Thu Apr 16 15:34:23 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.amd64,v 1.65 2009/03/30 22:28:39 rmind Exp $ +# $NetBSD: files.amd64,v 1.66 2009/04/16 15:34:23 rmind Exp $ # # new style config file for amd64 architecture # @@ -45,7 +45,6 @@ file arch/amd64/amd64/mem.c file arch/amd64/amd64/process_machdep.c file arch/amd64/amd64/procfs_machdep.c procfs -file arch/amd64/amd64/syscall.c file arch/amd64/amd64/trap.c file arch/amd64/amd64/fpu.c file arch/amd64/amd64/lock_stubs.S Index: src/sys/arch/i386/conf/files.i386 diff -u src/sys/arch/i386/conf/files.i386:1.347 src/sys/arch/i386/conf/files.i386:1.348 --- src/sys/arch/i386/conf/files.i386:1.347 Mon Mar 30 22:28:39 2009 +++ src/sys/arch/i386/conf/files.i386 Thu Apr 16 15:34:23 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.i386,v 1.347 2009/03/30 22:28:39 rmind Exp $ +# $NetBSD: files.i386,v 1.348 2009/04/16 15:34:23 rmind Exp $ # # new style config file for i386 architecture # @@ -82,7 +82,6 @@ file arch/i386/i386/mtrr_k6.c mtrr file arch/i386/i386/process_machdep.c file arch/i386/i386/procfs_machdep.c procfs -file arch/i386/i386/syscall.c file arch/i386/i386/trap.c file dev/cons.c Index: src/sys/arch/x86/conf/files.x86 diff -u src/sys/arch/x86/conf/files.x86:1.49 src/sys/arch/x86/conf/files.x86:1.50 --- src/sys/arch/x86/conf/files.x86:1.49 Tue Apr 7 18:24:23 2009 +++ src/sys/arch/x86/conf/files.x86 Thu Apr 16 15:34:23 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.x86,v 1.49 2009/04/07 18:24:23 dyoung Exp $ +# $NetBSD: files.x86,v 1.50 2009/04/16 15:34:23 rmind Exp $ # options for MP configuration through the MP spec defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI @@ -63,6 +63,7 @@ file arch/x86/x86/platform.c file arch/x86/x86/pmap.c file arch/x86/x86/sys_machdep.c +file arch/x86/x86/syscall.c file arch/x86/x86/vm_machdep.c file arch/x86/x86/x86_autoconf.c file arch/x86/x86/x86_machdep.c Index: src/sys/arch/x86/include/cpu.h diff -u src/sys/arch/x86/include/cpu.h:1.14 src/sys/arch/x86/include/cpu.h:1.15 --- src/sys/arch/x86/include/cpu.h:1.14 Mon Mar 30 09:51:37 2009 +++ src/sys/arch/x86/include/cpu.h Thu Apr 16 15:34:23 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.14 2009/03/30 09:51:37 tsutsui Exp $ */ +/* $NetBSD: cpu.h,v 1.15 2009/04/16 15:34:23 rmind Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -199,6 +199,23 @@ }; /* + * Macros to handle (some) trapframe registers for common x86 code. + */ +#ifdef __x86_64__ +#define X86_TF_RAX(tf) tf->tf_rax +#define X86_TF_RDX(tf) tf->tf_rdx +#define X86_TF_RSP(tf) tf->tf_rsp +#define X86_TF_RIP(tf) tf->tf_rip +#define X86_TF_RFLAGS(tf) tf->tf_rflags +#else +#define X86_TF_RAX(tf) tf->tf_eax +#define X86_TF_RDX(tf) tf->tf_edx +#define X86_TF_RSP(tf) tf->tf_esp +#define X86_TF_RIP(tf) tf->tf_eip +#define X86_TF_RFLAGS(tf) tf->tf_eflags +#endif + +/* * Processor flag notes: The "primary" CPU has certain MI-defined * roles (mostly relating to hardclock handling); we distinguish * betwen the processor which booted us, and the processor currently Added files: Index: src/sys/arch/x86/x86/syscall.c diff -u /dev/null src/sys/arch/x86/x86/syscall.c:1.1 --- /dev/null Thu Apr 16 15:34:24 2009 +++ src/sys/arch/x86/x86/syscall.c Thu Apr 16 15:34:23 2009 @@ -0,0 +1,220 @@ +/* $NetBSD: syscall.c,v 1.1 2009/04/16 15:34:23 rmind Exp $ */ + +/*- + * Copyright (c) 1998, 2000, 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Charles M. Hannum. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.1 2009/04/16 15:34:23 rmind Exp $"); + +#include "opt_sa.h" + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/proc.h> +#include <sys/user.h> +#include <sys/signal.h> +#include <sys/sa.h> +#include <sys/savar.h> +#include <sys/ktrace.h> +#include <sys/syscall.h> +#include <sys/syscallvar.h> +#include <sys/syscall_stats.h> + +#include <uvm/uvm_extern.h> + +#include <machine/cpu.h> +#include <machine/psl.h> +#include <machine/userret.h> + +#ifndef __x86_64__ +#include "opt_vm86.h" +#ifdef VM86 +void syscall_vm86(struct trapframe *); +#endif +int x86_copyargs(void *, void *, size_t); +#endif + +void syscall_intern(struct proc *); +static void syscall(struct trapframe *); + +void +child_return(void *arg) +{ + struct lwp *l = arg; + struct trapframe *tf = l->l_md.md_regs; + + X86_TF_RAX(tf) = 0; + X86_TF_RFLAGS(tf) &= ~PSL_C; + + userret(l); + ktrsysret(SYS_fork, 0, 0); +} + +void +syscall_intern(struct proc *p) +{ + + p->p_md.md_syscall = syscall; +} + +/* + * syscall(frame): + * System call request from POSIX system call gate interface to kernel. + * Like trap(), argument is call by reference. + */ +static void +syscall(struct trapframe *frame) +{ + const struct sysent *callp; + struct proc *p; + struct lwp *l; + int error; + register_t code, rval[2]; +#ifdef __x86_64__ + /* Verify that the syscall args will fit in the trapframe space */ + CTASSERT(offsetof(struct trapframe, tf_arg9) >= + sizeof(register_t) * (2 + SYS_MAXSYSARGS - 1)); +#define args (&frame->tf_rdi) +#else + register_t args[2 + SYS_MAXSYSARGS]; +#endif + + l = curlwp; + p = l->l_proc; + LWP_CACHE_CREDS(l, p); + + code = X86_TF_RAX(frame) & (SYS_NSYSENT - 1); + callp = p->p_emul->e_sysent + code; + + SYSCALL_COUNT(syscall_counts, code); + SYSCALL_TIME_SYS_ENTRY(l, syscall_times, code); + +#ifdef KERN_SA + if (__predict_false((l->l_savp) + && (l->l_savp->savp_pflags & SAVP_FLAG_DELIVERING))) + l->l_savp->savp_pflags &= ~SAVP_FLAG_DELIVERING; +#endif + +#ifdef __x86_64__ + /* + * The first 6 syscall args are passed in rdi, rsi, rdx, r10, r8 and r9 + * (rcx gets copied to r10 in the libc stub because the syscall + * instruction overwrites %cx) and are together in the trap frame + * with space following for 4 more entries. + */ + if (__predict_false(callp->sy_argsize > 6 * 8)) { + error = copyin((register_t *)frame->tf_rsp + 1, + &frame->tf_arg6, callp->sy_argsize - 6 * 8); + if (error != 0) + goto bad; + /* Refetch to avoid register spill to stack */ + code = frame->tf_rax & (SYS_NSYSENT - 1); + } +#else + if (callp->sy_argsize) { + error = x86_copyargs((char *)frame->tf_esp + sizeof(int), args, + callp->sy_argsize); + if (__predict_false(error != 0)) + goto bad; + } +#endif + if (!__predict_false(p->p_trace_enabled) + || __predict_false(callp->sy_flags & SYCALL_INDIRECT) + || (error = trace_enter(code, args, callp->sy_narg)) == 0) { + rval[0] = 0; + rval[1] = 0; + KASSERT(l->l_holdcnt == 0); + error = sy_call(callp, l, args, rval); + } + + if (__predict_false(p->p_trace_enabled) + && !__predict_false(callp->sy_flags & SYCALL_INDIRECT)) { + code = X86_TF_RAX(frame) & (SYS_NSYSENT - 1); + trace_exit(code, rval, error); + } + + if (__predict_true(error == 0)) { + X86_TF_RAX(frame) = rval[0]; + X86_TF_RDX(frame) = rval[1]; + X86_TF_RFLAGS(frame) &= ~PSL_C; /* carry bit */ + } else { + switch (error) { + case ERESTART: + /* + * The offset to adjust the PC by depends on whether we + * entered the kernel through the trap or call gate. + * We saved the instruction size in tf_err on entry. + */ + X86_TF_RIP(frame) -= frame->tf_err; + break; + case EJUSTRETURN: + /* nothing to do */ + break; + default: + bad: + X86_TF_RAX(frame) = error; + X86_TF_RFLAGS(frame) |= PSL_C; /* carry bit */ + break; + } + } + + SYSCALL_TIME_SYS_EXIT(l); + userret(l); +} + +#ifdef VM86 + +void +syscall_vm86(struct trapframe *frame) +{ + struct lwp *l; + struct proc *p; + ksiginfo_t ksi; + + KSI_INIT_TRAP(&ksi); + ksi.ksi_signo = SIGBUS; + ksi.ksi_code = BUS_OBJERR; + ksi.ksi_trap = T_PROTFLT; + ksi.ksi_addr = (void *)frame->tf_eip; + + l = curlwp; + p = l->l_proc; + +#ifdef KERN_SA + /* While this is probably not needed, it's probably better to include than not */ + if (__predict_false((l->l_savp) + && (l->l_savp->savp_pflags & SAVP_FLAG_DELIVERING))) + l->l_savp->savp_pflags &= ~SAVP_FLAG_DELIVERING; +#endif + + (*p->p_emul->e_trapsignal)(l, &ksi); + userret(l); +} + +#endif