diff options
author | kib <kib@FreeBSD.org> | 2009-11-10 11:43:07 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-11-10 11:43:07 +0000 |
commit | 3cf53f181e7360f48fecc50a925d46029888af1d (patch) | |
tree | bba1aed931ce7ad22617119eb8a0f3b4e1652845 /sys/sparc64 | |
parent | e256ac508b1a8eb7aedb8f720f3e650ecd273b53 (diff) | |
download | FreeBSD-src-3cf53f181e7360f48fecc50a925d46029888af1d.zip FreeBSD-src-3cf53f181e7360f48fecc50a925d46029888af1d.tar.gz |
Extract the code that records syscall results in the frame into MD
function cpu_set_syscall_retval().
Suggested by: marcel
Reviewed by: marcel, davidxu
PowerPC, ARM, ia64 changes: marcel
Sparc64 tested and reviewed by: marius, also sunv reviewed
MIPS tested by: gonzo
MFC after: 1 month
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; |