diff -Naur a/configure b/configure --- a/configure 2013-01-21 21:32:03.309892624 +0000 +++ b/configure 2013-01-21 21:46:47.338914238 +0000 @@ -3693,6 +3693,7 @@ case "$target_arch2" in i386) target_phys_bits=64 + target_nptl="yes" ;; x86_64) TARGET_BASE_ARCH=i386 diff -Naur a/linux-user/syscall.c b/linux-user/syscall.c --- a/linux-user/syscall.c 2013-01-21 21:32:02.279904484 +0000 +++ b/linux-user/syscall.c 2013-01-21 21:55:28.635750789 +0000 @@ -4188,6 +4188,13 @@ unlock_user_struct(target_ldt_info, ptr, 1); return 0; } + +static inline void cpu_set_tls(CPUX86State *env, target_ulong newtls) +{ + do_set_thread_area(env, newtls); + /* reload gs */ + cpu_x86_load_seg(env, R_GS, env->segs[R_GS].selector); +} #endif /* TARGET_I386 && TARGET_ABI32 */ #ifndef TARGET_ABI32 @@ -4313,7 +4320,16 @@ init_task_state(ts); /* we create a new CPU instance. */ new_env = cpu_copy(env); -#if defined(TARGET_I386) || defined(TARGET_SPARC) || defined(TARGET_PPC) +#if defined(TARGET_I386) + new_env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1), + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + memcpy(g2h(new_env->idt.base), g2h(env->idt.base), sizeof(uint64_t) * (env->idt.limit + 1)); + new_env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES, + PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + memcpy(g2h(new_env->gdt.base), g2h(env->gdt.base), sizeof(uint64_t) * TARGET_GDT_ENTRIES); +#elif defined(TARGET_SPARC) || defined(TARGET_PPC) cpu_reset(ENV_GET_CPU(new_env)); #endif /* Init regs that differ from the parent. */