diff options
-rw-r--r-- | lib/libkse/arch/ia64/include/pthread_md.h | 6 | ||||
-rw-r--r-- | lib/libpthread/arch/ia64/include/pthread_md.h | 6 | ||||
-rw-r--r-- | sys/ia64/ia64/machdep.c | 36 | ||||
-rw-r--r-- | sys/ia64/include/ucontext.h | 49 |
4 files changed, 41 insertions, 56 deletions
diff --git a/lib/libkse/arch/ia64/include/pthread_md.h b/lib/libkse/arch/ia64/include/pthread_md.h index 6598f3d..a72c953 100644 --- a/lib/libkse/arch/ia64/include/pthread_md.h +++ b/lib/libkse/arch/ia64/include/pthread_md.h @@ -232,6 +232,12 @@ _thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) mc->mc_special.isr = (intptr_t)&tcb->tcb_tmbx; } _ia64_break_setcontext(mc); + } else if (mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) { + if (setmbox) + kse_switchin(mc, (long)&tcb->tcb_tmbx, + (long *)&kcb->kcb_kmbx.km_curthread); + else + kse_switchin(mc, 0L, NULL); } else { if (setmbox) _ia64_restore_context(mc, (intptr_t)&tcb->tcb_tmbx, diff --git a/lib/libpthread/arch/ia64/include/pthread_md.h b/lib/libpthread/arch/ia64/include/pthread_md.h index 6598f3d..a72c953 100644 --- a/lib/libpthread/arch/ia64/include/pthread_md.h +++ b/lib/libpthread/arch/ia64/include/pthread_md.h @@ -232,6 +232,12 @@ _thread_switch(struct kcb *kcb, struct tcb *tcb, int setmbox) mc->mc_special.isr = (intptr_t)&tcb->tcb_tmbx; } _ia64_break_setcontext(mc); + } else if (mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) { + if (setmbox) + kse_switchin(mc, (long)&tcb->tcb_tmbx, + (long *)&kcb->kcb_kmbx.km_curthread); + else + kse_switchin(mc, 0L, NULL); } else { if (setmbox) _ia64_restore_context(mc, (intptr_t)&tcb->tcb_tmbx, diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index ddde791..28aa70c 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2003 Marcel Moolenaar * Copyright (c) 2000,2001 Doug Rabson * All rights reserved. * @@ -915,7 +916,7 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code) mtx_unlock(&psp->ps_mtx); PROC_UNLOCK(p); - get_mcontext(td, &sf.sf_uc.uc_mcontext, GET_MC_IA64_SCRATCH); + get_mcontext(td, &sf.sf_uc.uc_mcontext, 0); /* Copy the frame out to userland. */ if (copyout(&sf, sfp, sizeof(sf)) != 0) { @@ -1067,24 +1068,13 @@ get_mcontext(struct thread *td, mcontext_t *mc, int flags) } else mc->mc_special = tf->tf_special; if (tf->tf_flags & FRAME_SYSCALL) { - if (flags & GET_MC_IA64_SCRATCH) { - mc->mc_flags |= _MC_FLAGS_SCRATCH_VALID; - mc->mc_scratch = tf->tf_scratch; - } else { - /* - * Put the syscall return values in the context. We - * need this for swapcontext() to work. Note that we - * don't use gr11 in the kernel, but the runtime - * specification defines it as a return register, - * just like gr8-gr10. - */ - mc->mc_flags |= _MC_FLAGS_RETURN_VALID; - if ((flags & GET_MC_CLEAR_RET) == 0) { - mc->mc_scratch.gr8 = tf->tf_scratch.gr8; - mc->mc_scratch.gr9 = tf->tf_scratch.gr9; - mc->mc_scratch.gr10 = tf->tf_scratch.gr10; - mc->mc_scratch.gr11 = tf->tf_scratch.gr11; - } + mc->mc_flags |= _MC_FLAGS_SYSCALL_CONTEXT; + mc->mc_scratch = tf->tf_scratch; + if (flags & GET_MC_CLEAR_RET) { + mc->mc_scratch.gr8 = 0; + mc->mc_scratch.gr9 = 0; + mc->mc_scratch.gr10 = 0; + mc->mc_scratch.gr11 = 0; } } else { mc->mc_flags |= _MC_FLAGS_ASYNC_CONTEXT; @@ -1141,16 +1131,10 @@ set_mcontext(struct thread *td, const mcontext_t *mc) td->td_pcb->pcb_high_fp = mc->mc_high_fp; } else { KASSERT((tf->tf_flags & FRAME_SYSCALL) != 0, ("foo")); - if ((mc->mc_flags & _MC_FLAGS_SCRATCH_VALID) == 0) { + if ((mc->mc_flags & _MC_FLAGS_SYSCALL_CONTEXT) == 0) { s.cfm = tf->tf_special.cfm; s.iip = tf->tf_special.iip; tf->tf_scratch.gr15 = 0; /* Clear syscall nr. */ - if (mc->mc_flags & _MC_FLAGS_RETURN_VALID) { - tf->tf_scratch.gr8 = mc->mc_scratch.gr8; - tf->tf_scratch.gr9 = mc->mc_scratch.gr9; - tf->tf_scratch.gr10 = mc->mc_scratch.gr10; - tf->tf_scratch.gr11 = mc->mc_scratch.gr11; - } } else tf->tf_scratch = mc->mc_scratch; } diff --git a/sys/ia64/include/ucontext.h b/sys/ia64/include/ucontext.h index 0ff1e29..5619d59 100644 --- a/sys/ia64/include/ucontext.h +++ b/sys/ia64/include/ucontext.h @@ -45,48 +45,42 @@ * call to the function that creates the context. An asynctx needs to have the * scratch registers preserved because it can describe any point in a thread's * (or process') execution. + * The second variation is for synchronous contexts. When the kernel creates + * a synchronous context if needs to preserve the scratch registers, because + * the syscall argument and return values are stored there in the trapframe + * and they need to be preserved in order to restart a syscall or return the + * proper return values. Also, the IIP and CFM fields need to be preserved + * as they point to the syscall stub, which the kernel saves as a favor to + * userland (it keeps the stubs small and simple). * * Below a description of the flags and their meaning: * * _MC_FLAGS_ASYNC_CONTEXT * If set, indicates that mc_scratch and mc_scratch_fp are both - * valid. IFF not set, _MC_FLAGS_RETURN_VALID indicates if the - * return registers are valid or not. + * valid. IFF not set, _MC_FLAGS_SYSCALL_CONTEXT indicates if the + * synchronous context is one corresponding to a syscall or not. + * Only the kernel is expected to create such a context and it's + * probably wise to let the kernel restore it. * _MC_FLAGS_HIGHFP_VALID * If set, indicates that the high FP registers (f32-f127) are * valid. This flag is very likely not going to be set for any * sensible synctx, but is not explicitly disallowed. Any synctx * that has this flag may or may not have the high FP registers * restored. In short: don't do it. - * _MC_FLAGS_KSE_SET_MBOX - * This flag is special to setcontext(2) and swapcontext(2). It - * instructs the kernel to write the value in mc_special.isr to - * the memory address pointed to by mc_special.ifa. This allows - * the kernel to switch to a new context in a KSE based threaded - * program. Note that this is a non-srandard extension to the - * otherwise standard system calls and use of this flag should be - * limited to KSE. - * _MC_FLAGS_RETURN_VALID - * If set and _MC_FLAGS_ASYNC_CONTEXT is not set indicates that - * the ABI defined return registers are valid. Both getcontext(2) - * and swapcontext(2) need to save the system call return values. - * Any synctx that does not have this flag may still have the - * return registers restored from the context. - * _MC_FLAGS_SCRATCH_VALID - * If set and _MC_FLAGS_ASYNC_CONTEXT is not set indicates that - * the scratch registers, but not the FP registers are valid. - * This flag is set in contexts passed to signal handlers. This - * flag is a superset of _MC_FLAGS_RETURN_VALID. If both flags - * are set, this flag takes precedence. + * _MC_FLAGS_SYSCALL_CONTEXT + * If set (hence _MC_FLAGS_ASYNC_CONTEXT is not set) indicates + * that the scratch registers contain syscall arguments and + * return values and that additionally IIP and CFM are valid. + * Only the kernel is expected to create such a context. It's + * probably wise to let the kernel restore it. */ typedef struct __mcontext { unsigned long mc_flags; #define _MC_FLAGS_ASYNC_CONTEXT 0x0001 #define _MC_FLAGS_HIGHFP_VALID 0x0002 -#define _MC_FLAGS_KSE_SET_MBOX 0x0004 -#define _MC_FLAGS_RETURN_VALID 0x0008 -#define _MC_FLAGS_SCRATCH_VALID 0x0010 +#define _MC_FLAGS_KSE_SET_MBOX 0x0004 /* Undocumented. Has to go. */ +#define _MC_FLAGS_SYSCALL_CONTEXT 0x0008 unsigned long _reserved_; struct _special mc_special; struct _callee_saved mc_preserved; @@ -96,9 +90,4 @@ typedef struct __mcontext { struct _high_fp mc_high_fp; } mcontext_t; -#ifdef _KERNEL -/* Flags for get_mcontext(). See also <sys/ucontext.h>. */ -#define GET_MC_IA64_SCRATCH 0x10 -#endif - #endif /* !_MACHINE_UCONTEXT_H_ */ |