Commit 3fc2f9e5 authored by Richard Henderson's avatar Richard Henderson

[ALPHA] Fix SETTLS -- read TLS value to install before clobbering it.

parent 788fbf37
......@@ -270,7 +270,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct thread_info *childti = p->thread_info;
struct pt_regs * childregs;
struct switch_stack * childstack, *stack;
unsigned long stack_offset;
unsigned long stack_offset, settls;
stack_offset = PAGE_SIZE - sizeof(struct pt_regs);
if (!(regs->ps & 8))
......@@ -279,6 +279,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
(stack_offset + PAGE_SIZE + (long) childti);
*childregs = *regs;
settls = regs->r20;
childregs->r0 = 0;
childregs->r19 = 0;
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
......@@ -292,14 +293,16 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childti->pcb.flags = 1; /* set FEN, clear everything else */
/* Set a new TLS for the child thread? Peek back into the
syscall arguments that we saved on syscall entry. */
syscall arguments that we saved on syscall entry. Oops,
except we'd have clobbered it with the parent/child set
of r20. Read the saved copy. */
/* Note: if CLONE_SETTLS is not set, then we must inherit the
value from the parent, which will have been set by the block
copy in dup_task_struct. This is non-intuitive, but is
required for proper operation in the case of a threaded
application calling fork. */
if (clone_flags & CLONE_SETTLS)
childti->pcb.unique = regs->r20;
childti->pcb.unique = settls;
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment