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:
parent
f0d73b6741
commit
5ff92b1d9c
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user