svn commit: r199765 - stable/8/sys/sparc64/sparc64
Marius Strobl
marius at FreeBSD.org
Tue Nov 24 20:04:32 UTC 2009
Author: marius
Date: Tue Nov 24 20:04:31 2009
New Revision: 199765
URL: http://svn.freebsd.org/changeset/base/199765
Log:
MFC: r199442
Unroll copying of the registers in {g,s}et_mcontext() and limit it
to the set actually restored by tl0_ret() instead of using the whole
trapframe. Additionally skip %g7 as that register is used as the
userland TLS pointer.
PR: 140523
Modified:
stable/8/sys/sparc64/sparc64/machdep.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/xen/xenpci/ (props changed)
Modified: stable/8/sys/sparc64/sparc64/machdep.c
==============================================================================
--- stable/8/sys/sparc64/sparc64/machdep.c Tue Nov 24 19:57:41 2009 (r199764)
+++ stable/8/sys/sparc64/sparc64/machdep.c Tue Nov 24 20:04:31 2009 (r199765)
@@ -696,12 +696,39 @@ get_mcontext(struct thread *td, mcontext
tf = td->td_frame;
pcb = td->td_pcb;
- bcopy(tf, mc, sizeof(*tf));
+ /*
+ * Copy the registers which will be restored by tl0_ret() from the
+ * trapframe.
+ * Note that we skip %g7 which is used as the userland TLS register
+ * and %wstate.
+ */
+ mc->mc_flags = _MC_VERSION;
+ mc->mc_global[1] = tf->tf_global[1];
+ mc->mc_global[2] = tf->tf_global[2];
+ mc->mc_global[3] = tf->tf_global[3];
+ mc->mc_global[4] = tf->tf_global[4];
+ mc->mc_global[5] = tf->tf_global[5];
+ mc->mc_global[6] = tf->tf_global[6];
if (flags & GET_MC_CLEAR_RET) {
mc->mc_out[0] = 0;
mc->mc_out[1] = 0;
+ } else {
+ mc->mc_out[0] = tf->tf_out[0];
+ mc->mc_out[1] = tf->tf_out[1];
}
- mc->mc_flags = _MC_VERSION;
+ mc->mc_out[2] = tf->tf_out[2];
+ mc->mc_out[3] = tf->tf_out[3];
+ mc->mc_out[4] = tf->tf_out[4];
+ mc->mc_out[5] = tf->tf_out[5];
+ mc->mc_out[6] = tf->tf_out[6];
+ mc->mc_out[7] = tf->tf_out[7];
+ mc->mc_fprs = tf->tf_fprs;
+ mc->mc_fsr = tf->tf_fsr;
+ mc->mc_gsr = tf->tf_gsr;
+ mc->mc_tnpc = tf->tf_tnpc;
+ mc->mc_tpc = tf->tf_tpc;
+ mc->mc_tstate = tf->tf_tstate;
+ mc->mc_y = tf->tf_y;
critical_enter();
if ((tf->tf_fprs & FPRS_FEF) != 0) {
savefpctx(pcb->pcb_ufp);
@@ -721,7 +748,6 @@ set_mcontext(struct thread *td, const mc
{
struct trapframe *tf;
struct pcb *pcb;
- uint64_t wstate;
if (!TSTATE_SECURE(mc->mc_tstate) ||
(mc->mc_flags & ((1L << _MC_VERSION_BITS) - 1)) != _MC_VERSION)
@@ -730,9 +756,33 @@ set_mcontext(struct thread *td, const mc
pcb = td->td_pcb;
/* Make sure the windows are spilled first. */
flushw();
- wstate = tf->tf_wstate;
- bcopy(mc, tf, sizeof(*tf));
- tf->tf_wstate = wstate;
+ /*
+ * Copy the registers which will be restored by tl0_ret() to the
+ * trapframe.
+ * Note that we skip %g7 which is used as the userland TLS register
+ * and %wstate.
+ */
+ tf->tf_global[1] = mc->mc_global[1];
+ tf->tf_global[2] = mc->mc_global[2];
+ tf->tf_global[3] = mc->mc_global[3];
+ tf->tf_global[4] = mc->mc_global[4];
+ tf->tf_global[5] = mc->mc_global[5];
+ tf->tf_global[6] = mc->mc_global[6];
+ tf->tf_out[0] = mc->mc_out[0];
+ tf->tf_out[1] = mc->mc_out[1];
+ tf->tf_out[2] = mc->mc_out[2];
+ tf->tf_out[3] = mc->mc_out[3];
+ tf->tf_out[4] = mc->mc_out[4];
+ tf->tf_out[5] = mc->mc_out[5];
+ tf->tf_out[6] = mc->mc_out[6];
+ tf->tf_out[7] = mc->mc_out[7];
+ tf->tf_fprs = mc->mc_fprs;
+ tf->tf_fsr = mc->mc_fsr;
+ tf->tf_gsr = mc->mc_gsr;
+ tf->tf_tnpc = mc->mc_tnpc;
+ tf->tf_tpc = mc->mc_tpc;
+ tf->tf_tstate = mc->mc_tstate;
+ tf->tf_y = mc->mc_y;
if ((mc->mc_fprs & FPRS_FEF) != 0) {
tf->tf_fprs = 0;
bcopy(mc->mc_fp, pcb->pcb_ufp, sizeof(pcb->pcb_ufp));
More information about the svn-src-stable
mailing list