diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2009-12-12 20:06:25 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2009-12-12 20:06:25 +0000 |
| commit | f0087a7a3c1f921606121c0e6435b72492574a1a (patch) | |
| tree | 5a48dbed1f886938743e5605445c76a255c8c372 /sys/sun4v | |
| parent | 9562e7e533674d982b203b3f55a75de351962a05 (diff) | |
Notes
Diffstat (limited to 'sys/sun4v')
| -rw-r--r-- | sys/sun4v/sun4v/trap.c | 38 | ||||
| -rw-r--r-- | sys/sun4v/sun4v/vm_machdep.c | 37 |
2 files changed, 40 insertions, 35 deletions
diff --git a/sys/sun4v/sun4v/trap.c b/sys/sun4v/sun4v/trap.c index ffa0e8ca633c..353462da7c3b 100644 --- a/sys/sun4v/sun4v/trap.c +++ b/sys/sun4v/sun4v/trap.c @@ -81,6 +81,7 @@ #include <machine/cpu.h> #include <machine/frame.h> #include <machine/intr_machdep.h> +#include <machine/pcb.h> #include <machine/smp.h> #include <machine/trap.h> #include <machine/tstate.h> @@ -582,7 +583,6 @@ syscall(struct trapframe *tf) register_t *argp; struct proc *p; u_long code; - u_long tpc; int reg; int regcnt; int narg; @@ -606,7 +606,7 @@ syscall(struct trapframe *tf) * For syscalls, we don't want to retry the faulting instruction * (usually), instead we need to advance one instruction. */ - tpc = tf->tf_tpc; + td->td_pcb->pcb_tpc = tf->tf_tpc; TF_DONE(tf); reg = 0; @@ -673,40 +673,8 @@ syscall(struct trapframe *tf) error, syscallnames[code], td->td_retval[0], td->td_retval[1]); } - - /* - * MP SAFE (we may or may not have the MP lock at this point) - */ - switch (error) { - case 0: - tf->tf_out[0] = td->td_retval[0]; - tf->tf_out[1] = td->td_retval[1]; - tf->tf_tstate &= ~TSTATE_XCC_C; - break; - - case ERESTART: - /* - * Undo the tpc advancement we have done above, we want to - * reexecute the system call. - */ - tf->tf_tpc = tpc; - tf->tf_tnpc -= 4; - break; - - case EJUSTRETURN: - break; - default: - if (p->p_sysent->sv_errsize) { - if (error >= p->p_sysent->sv_errsize) - error = -1; /* XXX */ - else - error = p->p_sysent->sv_errtbl[error]; - } - tf->tf_out[0] = error; - tf->tf_tstate |= TSTATE_XCC_C; - break; - } + cpu_set_syscall_retval(td, error); /* * Handle reschedule and other end-of-syscall issues diff --git a/sys/sun4v/sun4v/vm_machdep.c b/sys/sun4v/sun4v/vm_machdep.c index 63a002f5e50d..5e02aec29d2f 100644 --- a/sys/sun4v/sun4v/vm_machdep.c +++ b/sys/sun4v/sun4v/vm_machdep.c @@ -57,6 +57,7 @@ #include <sys/mutex.h> #include <sys/sf_buf.h> #include <sys/sysctl.h> +#include <sys/sysent.h> #include <sys/unistd.h> #include <sys/vmmeter.h> @@ -142,6 +143,42 @@ cpu_thread_swapout(struct thread *td) } void +cpu_set_syscall_retval(struct thread *td, int error) +{ + + switch (error) { + case 0: + td->td_frame->tf_out[0] = td->td_retval[0]; + td->td_frame->tf_out[1] = td->td_retval[1]; + td->td_frame->tf_tstate &= ~TSTATE_XCC_C; + break; + + case ERESTART: + /* + * Undo the tpc advancement we have done on syscall + * enter, we want to reexecute the system call. + */ + td->td_frame->tf_tpc = td->td_pcb->pcb_tpc; + td->td_frame->tf_tnpc -= 4; + break; + + case EJUSTRETURN: + break; + + default: + if (td->td_proc->p_sysent->sv_errsize) { + if (error >= td->td_proc->p_sysent->sv_errsize) + error = -1; /* XXX */ + else + error = td->td_proc->p_sysent->sv_errtbl[error]; + } + td->td_frame->tf_out[0] = error; + td->td_frame->tf_tstate |= TSTATE_XCC_C; + break; + } +} + +void cpu_set_upcall(struct thread *td, struct thread *td0) { struct trapframe *tf; |
