diff options
Diffstat (limited to 'sys/sparc64')
-rw-r--r-- | sys/sparc64/include/pcb.h | 3 | ||||
-rw-r--r-- | sys/sparc64/sparc64/trap.c | 37 | ||||
-rw-r--r-- | sys/sparc64/sparc64/vm_machdep.c | 37 |
3 files changed, 41 insertions, 36 deletions
diff --git a/sys/sparc64/include/pcb.h b/sys/sparc64/include/pcb.h index 7e8294a..f23c1f2 100644 --- a/sys/sparc64/include/pcb.h +++ b/sys/sparc64/include/pcb.h @@ -49,7 +49,8 @@ struct pcb { uint64_t pcb_nsaved; uint64_t pcb_pc; uint64_t pcb_sp; - uint64_t pcb_pad[4]; + uint64_t pcb_tpc; + uint64_t pcb_pad[3]; } __aligned(64); #ifdef _KERNEL diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c index 702e4f1..0c07eaf 100644 --- a/sys/sparc64/sparc64/trap.c +++ b/sys/sparc64/sparc64/trap.c @@ -538,7 +538,6 @@ syscall(struct trapframe *tf) register_t *argp; struct proc *p; u_long code; - u_long tpc; int reg; int regcnt; int narg; @@ -562,7 +561,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; @@ -626,39 +625,7 @@ syscall(struct trapframe *tf) 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); /* * Check for misbehavior. diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index 76521a6..009f45d 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mbuf.h> #include <sys/mutex.h> #include <sys/proc.h> +#include <sys/sysent.h> #include <sys/sf_buf.h> #include <sys/sched.h> #include <sys/sysctl.h> @@ -166,6 +167,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; |