diff options
author | marcel <marcel@FreeBSD.org> | 2003-11-10 05:28:05 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2003-11-10 05:28:05 +0000 |
commit | 2322554b505db97ea0be0318e61ed0a8d71c0add (patch) | |
tree | 7beeb73a1b8b1848789e19ecd73eeb243cc20976 /sys/ia64 | |
parent | 382ccc28a4a092322844ecd1fa9e162968e3a12b (diff) | |
download | FreeBSD-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.c | 14 |
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); |