diff options
author | dchagin <dchagin@FreeBSD.org> | 2011-02-12 15:50:21 +0000 |
---|---|---|
committer | dchagin <dchagin@FreeBSD.org> | 2011-02-12 15:50:21 +0000 |
commit | 8b4a0070062f048a875f2373eabffba8c5633b67 (patch) | |
tree | c280e6394a21001054a9cf32d2a365629b5aab7a /sys/amd64/linux32 | |
parent | 8abe7e237a34dfacdef7b567d8f82f56605d9a98 (diff) | |
download | FreeBSD-src-8b4a0070062f048a875f2373eabffba8c5633b67.zip FreeBSD-src-8b4a0070062f048a875f2373eabffba8c5633b67.tar.gz |
In preparation for moving linux_clone () to a MI path
move the TLS code in a separate function.
Use function parameter instead of direct using register.
Diffstat (limited to 'sys/amd64/linux32')
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 86 |
1 files changed, 46 insertions, 40 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index 986322e..d24b7b6 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -496,6 +496,50 @@ linux_vfork(struct thread *td, struct linux_vfork_args *args) return (0); } +static int +linux_set_cloned_tls(struct thread *td, void *desc) +{ + struct user_segment_descriptor sd; + struct l_user_desc info; + struct pcb *pcb; + int error; + int a[2]; + + error = copyin(desc, &info, sizeof(struct l_user_desc)); + if (error) { + printf(LMSG("copyin failed!")); + } else { + /* We might copy out the entry_number as GUGS32_SEL. */ + info.entry_number = GUGS32_SEL; + error = copyout(&info, desc, sizeof(struct l_user_desc)); + if (error) + printf(LMSG("copyout failed!")); + + a[0] = LINUX_LDT_entry_a(&info); + a[1] = LINUX_LDT_entry_b(&info); + + memcpy(&sd, &a, sizeof(a)); +#ifdef DEBUG + if (ldebug(clone)) + printf("Segment created in clone with " + "CLONE_SETTLS: lobase: %x, hibase: %x, " + "lolimit: %x, hilimit: %x, type: %i, " + "dpl: %i, p: %i, xx: %i, long: %i, " + "def32: %i, gran: %i\n", sd.sd_lobase, + sd.sd_hibase, sd.sd_lolimit, sd.sd_hilimit, + sd.sd_type, sd.sd_dpl, sd.sd_p, sd.sd_xx, + sd.sd_long, sd.sd_def32, sd.sd_gran); +#endif + pcb = td->td_pcb; + pcb->pcb_gsbase = (register_t)info.base_addr; +/* XXXKIB pcb->pcb_gs32sd = sd; */ + td->td_frame->tf_gs = GSEL(GUGS32_SEL, SEL_UPL); + set_pcb_flags(pcb, PCB_GS32BIT | PCB_32BIT); + } + + return (error); +} + int linux_clone(struct thread *td, struct linux_clone_args *args) { @@ -613,46 +657,8 @@ linux_clone(struct thread *td, struct linux_clone_args *args) if (args->stack) td2->td_frame->tf_rsp = PTROUT(args->stack); - if (args->flags & LINUX_CLONE_SETTLS) { - struct user_segment_descriptor sd; - struct l_user_desc info; - struct pcb *pcb; - int a[2]; - - error = copyin((void *)td->td_frame->tf_rsi, &info, - sizeof(struct l_user_desc)); - if (error) { - printf(LMSG("copyin failed!")); - } else { - /* We might copy out the entry_number as GUGS32_SEL. */ - info.entry_number = GUGS32_SEL; - error = copyout(&info, (void *)td->td_frame->tf_rsi, - sizeof(struct l_user_desc)); - if (error) - printf(LMSG("copyout failed!")); - - a[0] = LINUX_LDT_entry_a(&info); - a[1] = LINUX_LDT_entry_b(&info); - - memcpy(&sd, &a, sizeof(a)); -#ifdef DEBUG - if (ldebug(clone)) - printf("Segment created in clone with " - "CLONE_SETTLS: lobase: %x, hibase: %x, " - "lolimit: %x, hilimit: %x, type: %i, " - "dpl: %i, p: %i, xx: %i, long: %i, " - "def32: %i, gran: %i\n", sd.sd_lobase, - sd.sd_hibase, sd.sd_lolimit, sd.sd_hilimit, - sd.sd_type, sd.sd_dpl, sd.sd_p, sd.sd_xx, - sd.sd_long, sd.sd_def32, sd.sd_gran); -#endif - pcb = td2->td_pcb; - pcb->pcb_gsbase = (register_t)info.base_addr; -/* XXXKIB pcb->pcb_gs32sd = sd; */ - td2->td_frame->tf_gs = GSEL(GUGS32_SEL, SEL_UPL); - set_pcb_flags(pcb, PCB_GS32BIT | PCB_32BIT); - } - } + if (args->flags & LINUX_CLONE_SETTLS) + linux_set_cloned_tls(td2, args->tls); #ifdef DEBUG if (ldebug(clone)) |