summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-11-10 05:28:05 +0000
committermarcel <marcel@FreeBSD.org>2003-11-10 05:28:05 +0000
commit2322554b505db97ea0be0318e61ed0a8d71c0add (patch)
tree7beeb73a1b8b1848789e19ecd73eeb243cc20976 /sys/ia64
parent382ccc28a4a092322844ecd1fa9e162968e3a12b (diff)
downloadFreeBSD-src-2322554b505db97ea0be0318e61ed0a8d71c0add.zip
FreeBSD-src-2322554b505db97ea0be0318e61ed0a8d71c0add.tar.gz
In get_mcontext(), do not update bspstore and ndirty in the trapframe.
Only update them in the newly created context to reflect the state after copying the dirty registers onto the user stack. If we were to update the trapframe, we lose the state at entry into the kernel. We may need that after we create the context, such as for KSE upcalls. We have to update the trapframe after writing the dirty registers to the user stack for signal delivery to work. But this is best done in sendsig() itself where it applies, not in get_mcontext() where it's done unconditionally.
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/machdep.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index edfd29f..b52abf9f 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -941,6 +941,9 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
*/
tf->tf_special.sp = (u_int64_t)sfp - 16;
tf->tf_special.gp = sbs;
+ tf->tf_special.bspstore = sf.sf_uc.uc_mcontext.mc_special.bspstore;
+ tf->tf_special.ndirty = 0;
+ tf->tf_special.rnat = sf.sf_uc.uc_mcontext.mc_special.rnat;
tf->tf_scratch.gr8 = sig;
tf->tf_scratch.gr9 = code;
tf->tf_scratch.gr10 = (u_int64_t)catcher;
@@ -1049,12 +1052,14 @@ get_mcontext(struct thread *td, mcontext_t *mc, int flags)
copyout((void*)kstk, (void*)tf->tf_special.bspstore,
tf->tf_special.ndirty);
kstk += tf->tf_special.ndirty;
- tf->tf_special.bspstore += tf->tf_special.ndirty;
- tf->tf_special.ndirty = 0;
- tf->tf_special.rnat =
+ mc->mc_special = tf->tf_special;
+ mc->mc_special.rnat =
(bspst > kstk && (bspst & 0x1ffUL) < (kstk & 0x1ffUL))
? *(uint64_t*)(kstk | 0x1f8UL) : rnat;
- }
+ mc->mc_special.bspstore += mc->mc_special.ndirty;
+ mc->mc_special.ndirty = 0;
+ } 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;
@@ -1081,7 +1086,6 @@ get_mcontext(struct thread *td, mcontext_t *mc, int flags)
mc->mc_scratch_fp = tf->tf_scratch_fp;
/* XXX High FP */
}
- mc->mc_special = tf->tf_special;
save_callee_saved(&mc->mc_preserved);
save_callee_saved_fp(&mc->mc_preserved_fp);
return (0);
OpenPOWER on IntegriCloud