Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Nov 2006 13:34:10 GMT
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 110383 for review
Message-ID:  <200611221334.kAMDYAPu061419@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=110383

Change 110383 by gonzo@gonzo_hq on 2006/11/22 13:33:31

	o Since we provide trapframe using exception_store_registers
	    for every trap call there is no need to check curthread's
	    td_frame.
	o Add syscal "case" in trap function.
	o Replace "XXX send signal" comment with panic call for it's 
	    harder to be ignored unlike comment.
	o Add syscall function.

Affected files ...

.. //depot/projects/mips2/src/sys/mips/mips/trap.c#10 edit

Differences ...

==== //depot/projects/mips2/src/sys/mips/mips/trap.c#10 (text+ko) ====

@@ -25,18 +25,31 @@
  * $FreeBSD$
  */
 
+#include <sys/types.h>
 #include "opt_ddb.h"
 
 #include <sys/param.h>
-#include <sys/kernel.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/syscall.h>
+#include <sys/sysent.h>
+#include <sys/signalvar.h>
+#include <sys/ktr.h>
 #include <sys/kdb.h>
+#ifdef KTRACE
+#include <sys/uio.h>
+#include <sys/ktrace.h>
+#endif
+#include <sys/ptrace.h>
+#include <sys/pioctl.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
+#include <vm/vm_kern.h>
 #include <vm/vm_map.h>
-#include <vm/vm_kern.h>
 #include <vm/vm_param.h>
 #include <vm/vm_extern.h>
 
@@ -47,10 +60,16 @@
 #include <machine/trap.h>
 #include <machine/hwfunc.h>
 
+#include <security/audit/audit.h>
+
 #ifdef DDB
 #include <machine/db_machdep.h>
 #endif
 
+#ifdef KDB
+#include <sys/kdb.h>
+#endif
+
 struct trap_identifier {
 	u_int ExcCode;
 	const char *Mnemonic;
@@ -90,30 +109,27 @@
 	{ 31,	"VCED",		"Virtual coherency (data)" }
 };
 #define	MAXTRAPID	31
+#define MAXARGS		8
+
+void syscall(struct thread *, struct trapframe *);
+extern const char *syscallnames[];
 
 /* Protected by critical sections, for checking for bad addresses.  */
 static volatile char *trap_addr;
 static volatile int trap_error;
 
 void
-trap(struct trapframe *retf, u_int cause, void *badvaddr)
+trap(struct trapframe * tf, u_int cause, void *badvaddr)
 {
 	vm_offset_t va;
 	vm_map_t map;
 	struct thread *td;
-	struct trapframe *tf;
 	struct trap_identifier *tid;
 	int code, kernelmode;
 	int ftype, error;
 
 	platform_trap_enter();
 
-	if (curthread != NULL)
-		tf = curthread->td_frame;
-	else
-		tf = retf;
-	bcopy(retf, tf, sizeof *tf);
-
 	code = (cause & MIPS3_CR_EXC_CODE) >> MIPS_CR_EXC_CODE_SHIFT;
 	kernelmode = (tf->tf_regs[TF_SR] & MIPS_SR_KSU_USER) == 0;
 
@@ -166,7 +182,16 @@
 			goto done;
 		if (kernelmode)
 			break;
-		/* XXX send signal */
+
+		/* TODO: send signal */
+		panic("Send signal to userland here... error=%d, va=0x%08x\n",
+		    error, va);
+
+	case TrSys:
+		syscall(curthread, tf);
+		goto done;
+		break;
+
 	case TrAdEL:
 	case TrDBE:
 		if (trap_error == -1/* && trap_addr == badvaddr*/) {
@@ -237,7 +262,6 @@
 #endif
 done:
 	platform_trap_exit();
-	bcopy(tf, retf, sizeof *tf);
 }
 
 int
@@ -261,3 +285,153 @@
 		return (0);
 	return (error);
 }
+
+/*
+ * Following conventions are used for syscall implementation:
+ *   - Syscall number is passed in v0
+ *   - Arguments in a0,a1,...,stack..
+ *   - Error flag is returned in a3 (a3 != 0 ergo there was an error)
+ *   - v0 (possibly v1) contains return value
+ */ 
+void
+syscall(struct thread *td, struct trapframe *frame)
+{
+
+	struct proc *p = td->td_proc;
+	int code, error;
+	u_int nargs, i;
+	register_t *args, copyargs[MAXARGS];
+	struct sysent *callp;
+	int locked = 0;
+	int args_shift = 0;
+
+	PCPU_LAZY_INC(cnt.v_syscall);
+	td->td_pticks = 0;
+	if (td->td_ucred != td->td_proc->p_ucred)
+		cred_update_thread(td);
+
+	code = frame->tf_regs[TF_V0] & 0x000fffff;                
+
+	/*
+	 * For SYS_syscall first argument is an actual syscall number
+	 * and following are arguments
+	 */ 	 
+	if(code == SYS_syscall)
+	{
+		code = frame->tf_regs[TF_A0];
+		args_shift = 1;
+	}
+
+	/* TODO: implement */
+	if(code == SYS___syscall)
+		panic("SYS___syscall: to implement");
+
+	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 & SYF_ARGMASK;
+
+	printf("syscall enter thread %p pid %d proc " \
+		"%s code %d(%s) nargs: %d\n", td,
+		td->td_proc->p_pid, td->td_proc->p_comm, code, 
+		syscallnames[code], nargs);
+
+	/* Copy arguments from a0..a4 */
+	for(i = 0; i < MIN(nargs, 4 - args_shift); i++)
+		copyargs[i] = frame->tf_regs[TF_A0 + i + args_shift];
+
+	/* Copy arguments from stack (if any) */
+	if(i < nargs)
+	{
+		error = copyin((void *)frame->tf_regs[TF_SP], copyargs + i,
+		    (nargs - i) * sizeof(register_t));
+
+		if (error)
+			goto bad;
+	}
+
+	args = copyargs;
+	error = 0;
+
+#ifdef KTRACE
+	if (KTRPOINT(td, KTR_SYSCALL))
+		ktrsyscall(code, nargs, args);
+#endif
+		
+	CTR4(KTR_SYSC, "syscall enter thread %p pid %d proc %s code %d", td,
+	    td->td_proc->p_pid, td->td_proc->p_comm, code);
+
+	if ((callp->sy_narg & SYF_MPSAFE) == 0)
+		mtx_lock(&Giant);
+	locked = 1;
+	if (error == 0) {
+		td->td_retval[0] = 0;
+		td->td_retval[1] = 0;
+		STOPEVENT(p, S_SCE, (callp->sy_narg & SYF_ARGMASK));
+		PTRACESTOP_SC(p, td, S_PT_SCE);
+		AUDIT_SYSCALL_ENTER(code, td);
+		error = (*callp->sy_call)(td, args);
+		AUDIT_SYSCALL_EXIT(error, td);
+		KASSERT(td->td_ar == NULL, 
+		    ("returning from syscall with td_ar set!"));
+	}
+	switch (error) {
+	case 0: 
+		frame->tf_regs[TF_V0] = td->td_retval[0];
+		/* 
+		 * XXXMIPS: should we consider this case for 32-bit or
+		 * only for 64bits?
+		 */ 
+		/* frame->tf_regs[TF_V1] = td->td_retval[1]; */
+		frame->tf_regs[TF_A3] = 0;
+		break;
+		
+	case ERESTART:
+		/*
+		 * Reconstruct the pc to point at the swi.
+		 */
+		panic("TODO: implement ERESTART in syscall");
+		/* frame->tf_pc -= INSN_SIZE; */
+		break;
+
+	case EJUSTRETURN:                                       
+		/* nothing to do */  
+		break;
+
+	default:
+bad:
+		frame->tf_regs[TF_V0] = error;
+		frame->tf_regs[TF_A3] = 1;
+		break;
+	}
+
+	if (locked && (callp->sy_narg & SYF_MPSAFE) == 0)
+		mtx_unlock(&Giant);
+
+	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));
+
+	/* XXXMIPS: Check for branch delay? */
+	frame->tf_regs[TF_EPC] += 4;
+	userret(td, frame);
+
+	CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
+	    td->td_proc->p_pid, td->td_proc->p_comm, code);
+	
+	STOPEVENT(p, S_SCX, code);
+	PTRACESTOP_SC(p, td, S_PT_SCX);
+#ifdef KTRACE
+	if (KTRPOINT(td, KTR_SYSRET))
+		ktrsysret(code, error, td->td_retval[0]);
+#endif
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611221334.kAMDYAPu061419>