aboutsummaryrefslogtreecommitdiff
path: root/sys/sparc64/sparc64/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/sparc64/sparc64/trap.c')
-rw-r--r--sys/sparc64/sparc64/trap.c123
1 files changed, 14 insertions, 109 deletions
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index c0772a188697..8ce6970d65d3 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -94,18 +94,9 @@ __FBSDID("$FreeBSD$");
#include <machine/tsb.h>
#include <machine/watch.h>
-struct syscall_args {
- u_long code;
- struct sysent *callp;
- register_t args[8];
- register_t *argp;
- int narg;
-};
-
void trap(struct trapframe *tf);
void syscall(struct trapframe *tf);
-static int fetch_syscall_args(struct thread *td, struct syscall_args *sa);
static int trap_cecc(void);
static int trap_pfault(struct thread *td, struct trapframe *tf);
@@ -123,8 +114,6 @@ extern char fas_fault[];
extern char fas_nofault_begin[];
extern char fas_nofault_end[];
-extern char *syscallnames[];
-
const char *const trap_msg[] = {
"reserved",
"instruction access exception",
@@ -579,11 +568,12 @@ trap_pfault(struct thread *td, struct trapframe *tf)
/* Maximum number of arguments that can be passed via the out registers. */
#define REG_MAXARGS 6
-static int
-fetch_syscall_args(struct thread *td, struct syscall_args *sa)
+int
+cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
{
struct trapframe *tf;
struct proc *p;
+ register_t *argp;
int reg;
int regcnt;
int error;
@@ -595,19 +585,13 @@ fetch_syscall_args(struct thread *td, struct syscall_args *sa)
sa->code = tf->tf_global[1];
- if (p->p_sysent->sv_prepsyscall) {
-#if 0
- (*p->p_sysent->sv_prepsyscall)(tf, sa->args, &sa->code,
- &params);
-#endif
- } else if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
+ if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
sa->code = tf->tf_out[reg++];
regcnt--;
}
if (p->p_sysent->sv_mask)
sa->code &= p->p_sysent->sv_mask;
-
if (sa->code >= p->p_sysent->sv_size)
sa->callp = &p->p_sysent->sv_table[0];
else
@@ -617,21 +601,17 @@ fetch_syscall_args(struct thread *td, struct syscall_args *sa)
KASSERT(sa->narg <= sizeof(sa->args) / sizeof(sa->args[0]),
("Too many syscall arguments!"));
error = 0;
- sa->argp = sa->args;
+ argp = sa->args;
bcopy(&tf->tf_out[reg], sa->args, sizeof(sa->args[0]) * regcnt);
if (sa->narg > regcnt)
error = copyin((void *)(tf->tf_out[6] + SPOFF +
offsetof(struct frame, fr_pad[6])), &sa->args[regcnt],
(sa->narg - regcnt) * sizeof(sa->args[0]));
+ if (error == 0) {
+ td->td_retval[0] = 0;
+ td->td_retval[1] = 0;
+ }
- /*
- * This may result in two records if debugger modified
- * registers or memory during sleep at stop/ptrace point.
- */
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSCALL))
- ktrsyscall(sa->code, sa->narg, sa->argp);
-#endif
return (error);
}
@@ -644,29 +624,16 @@ fetch_syscall_args(struct thread *td, struct syscall_args *sa)
void
syscall(struct trapframe *tf)
{
- struct syscall_args sa;
struct thread *td;
- struct proc *p;
+ struct syscall_args sa;
int error;
td = curthread;
+ td->td_frame = tf;
+
KASSERT(td != NULL, ("trap: curthread NULL"));
KASSERT(td->td_proc != NULL, ("trap: curproc NULL"));
- PCPU_INC(cnt.v_syscall);
- p = td->td_proc;
- td->td_syscalls++;
-
- td->td_pticks = 0;
- td->td_frame = tf;
- if (td->td_ucred != p->p_ucred)
- cred_update_thread(td);
- if ((p->p_flag & P_TRACED) != 0) {
- PROC_LOCK(p);
- td->td_dbgflags &= ~TDB_USERWR;
- PROC_UNLOCK(p);
- }
-
/*
* For syscalls, we don't want to retry the faulting instruction
* (usually), instead we need to advance one instruction.
@@ -674,68 +641,6 @@ syscall(struct trapframe *tf)
td->td_pcb->pcb_tpc = tf->tf_tpc;
TF_DONE(tf);
- error = fetch_syscall_args(td, &sa);
- CTR5(KTR_SYSC, "syscall: td=%p %s(%#lx, %#lx, %#lx)", td,
- syscallnames[sa.code], sa.argp[0], sa.argp[1], sa.argp[2]);
-
- if (error == 0) {
- td->td_retval[0] = 0;
- td->td_retval[1] = 0;
-
- STOPEVENT(p, S_SCE, sa.narg);
- PTRACESTOP_SC(p, td, S_PT_SCE);
- if ((td->td_dbgflags & TDB_USERWR) != 0) {
- /*
- * Reread syscall number and arguments if
- * debugger modified registers or memory.
- */
- error = fetch_syscall_args(td, &sa);
- if (error != 0)
- goto retval;
- td->td_retval[1] = 0;
- }
-
- AUDIT_SYSCALL_ENTER(sa.code, td);
- error = (*sa.callp->sy_call)(td, sa.argp);
- AUDIT_SYSCALL_EXIT(error, td);
-
- CTR5(KTR_SYSC, "syscall: p=%p error=%d %s return %#lx %#lx",
- p, error, syscallnames[sa.code], td->td_retval[0],
- td->td_retval[1]);
- }
- retval:
- cpu_set_syscall_retval(td, error);
-
- /*
- * Check for misbehavior.
- */
- WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning",
- (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
- syscallnames[sa.code] : "???");
- KASSERT(td->td_critnest == 0,
- ("System call %s returning in a critical section",
- (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
- syscallnames[sa.code] : "???"));
- KASSERT(td->td_locks == 0,
- ("System call %s returning with %d locks held",
- (sa.code >= 0 && sa.code < SYS_MAXSYSCALL) ?
- syscallnames[sa.code] : "???", td->td_locks));
-
- /*
- * Handle reschedule and other end-of-syscall issues.
- */
- userret(td, tf);
-
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_SYSRET))
- ktrsysret(sa.code, error, 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, sa.code);
-
- PTRACESTOP_SC(p, td, S_PT_SCX);
+ error = syscallenter(td, &sa);
+ syscallret(td, error, &sa);
}