Do not restore the register holding the TLS pointer when doing various

usermode context switches (long jumps and ucontext operations). If these
are used across threads, multiple threads can end up with the same TLS base.
Madness will then result.

This makes behavior on PPC match that on x86 systems and on Linux.

MFC after:	10 days
This commit is contained in:
Nathan Whitehorn 2012-04-11 00:00:40 +00:00
parent 43faa6b266
commit 88fe385600
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234115
7 changed files with 12 additions and 8 deletions

View File

@ -63,7 +63,6 @@ ENTRY(_longjmp)
lmw %r9,20(%r3)
mtlr %r11
mtcr %r12
mr %r2,%r9
mr %r1,%r10
or. %r3,%r4,%r4
bnelr

View File

@ -75,7 +75,6 @@ ENTRY(__longjmp)
mr %r6,%r4 /* save val param */
mtlr %r11 /* r11 -> link reg */
mtcr %r12 /* r12 -> condition reg */
mr %r2,%r9 /* r9 -> global ptr */
mr %r1,%r10 /* r10 -> stackptr */
mr %r4,%r3
li %r3,3 /* SIG_SETMASK */

View File

@ -80,7 +80,6 @@ ENTRY(siglongjmp)
mr %r6,%r4
mtlr %r11
mtcr %r12
mr %r2,%r9
mr %r1,%r10
or. %r7,%r7,%r7
beq 1f

View File

@ -86,7 +86,6 @@ ENTRY(_longjmp)
ld %r10,40 + 1*8(%r3)
ld %r11,40 + 2*8(%r3)
ld %r12,40 + 3*8(%r3)
ld %r13,40 + 4*8(%r3)
ld %r14,40 + 5*8(%r3)
ld %r15,40 + 6*8(%r3)
ld %r16,40 + 7*8(%r3)

View File

@ -99,7 +99,6 @@ ENTRY(__longjmp)
ld %r10,40 + 1*8(%r3)
ld %r11,40 + 2*8(%r3)
ld %r12,40 + 3*8(%r3)
ld %r13,40 + 4*8(%r3)
ld %r14,40 + 5*8(%r3)
ld %r15,40 + 6*8(%r3)
ld %r16,40 + 7*8(%r3)

View File

@ -103,7 +103,6 @@ ENTRY(siglongjmp)
ld %r10,40 + 1*8(%r3)
ld %r11,40 + 2*8(%r3)
ld %r12,40 + 3*8(%r3)
ld %r13,40 + 4*8(%r3)
ld %r14,40 + 5*8(%r3)
ld %r15,40 + 6*8(%r3)
ld %r16,40 + 7*8(%r3)

View File

@ -441,6 +441,7 @@ set_mcontext(struct thread *td, const mcontext_t *mcp)
{
struct pcb *pcb;
struct trapframe *tf;
register_t tls;
pcb = td->td_pcb;
tf = td->td_frame;
@ -448,16 +449,25 @@ set_mcontext(struct thread *td, const mcontext_t *mcp)
if (mcp->mc_vers != _MC_VERSION || mcp->mc_len != sizeof(*mcp))
return (EINVAL);
#ifdef AIM
#ifdef AIM
/*
* Don't let the user set privileged MSR bits
*/
if ((mcp->mc_srr1 & PSL_USERSTATIC) != (tf->srr1 & PSL_USERSTATIC)) {
return (EINVAL);
}
#endif
#endif
/* Copy trapframe, preserving TLS pointer across context change */
if (SV_PROC_FLAG(td->td_proc, SV_LP64))
tls = tf->fixreg[13];
else
tls = tf->fixreg[2];
memcpy(tf, mcp->mc_frame, sizeof(mcp->mc_frame));
if (SV_PROC_FLAG(td->td_proc, SV_LP64))
tf->fixreg[13] = tls;
else
tf->fixreg[2] = tls;
#ifdef AIM
if (mcp->mc_flags & _MC_FP_VALID) {