diff --git a/configure b/configure index 8789324..5c48942 100755 --- a/configure +++ b/configure @@ -3891,6 +3891,7 @@ TARGET_ABI_DIR=""
case "$target_arch2" in i386) + target_nptl="yes" ;; x86_64) TARGET_BASE_ARCH=i386 diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9e31ea7..86ecfbc 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4253,6 +4253,13 @@ static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) 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); +}
@@ -4378,7 +4385,16 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp, 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)); /* Init regs that differ from the parent. */
|