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
43faa6b266
commit
88fe385600
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234115
@ -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