Patchwork add usermode NPTL support for i386

login
register
mail settings
Submitter matthieu castet
Date Feb. 12, 2010, 6:31 p.m.
Message ID <4B759E65.6050605@free.fr>
Download mbox | patch
Permalink /patch/45206/
State New
Headers show

Comments

matthieu castet - Feb. 12, 2010, 6:31 p.m.
Hi,

this patch try to add usermode NPTL support for i386.

Note that this patch need review because I don't know if I did the right thing removing the cpu_reset in the clone path.

Matthieu

Patch

diff --git a/configure b/configure
index 0a84b0e..69ccb13 100755
--- a/configure
+++ b/configure
@@ -2342,6 +2342,7 @@  TARGET_ABI_DIR=""
 case "$target_arch2" in
   i386)
     target_phys_bits=32
+    target_nptl="yes"
   ;;
   x86_64)
     TARGET_BASE_ARCH=i386
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9fb493f..38f2067 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -3426,6 +3426,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(CPUState *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
@@ -3554,7 +3561,16 @@  static int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp,
         new_stack = ts->stack;
         /* 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(new_env);
 #endif
         /* Init regs that differ from the parent.  */