]> git.proxmox.com Git - qemu.git/commitdiff
Fix CPU chaining in linux-user emulation, by Gwenole Beauchesne.
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 28 Feb 2007 20:20:53 +0000 (20:20 +0000)
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 28 Feb 2007 20:20:53 +0000 (20:20 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2459 c046a42c-6fe2-441c-8c8c-71466251a162

cpu-all.h
exec.c
linux-user/syscall.c

index 8a4730d32c1b6c0a4191b9b302500809017b0f05..0ad50e8bf64c9662867058f1f3ee01508951a7cc 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -754,6 +754,8 @@ void page_unprotect_range(target_ulong data, target_ulong data_size);
 
 #endif /* SINGLE_CPU_DEFINES */
 
+CPUState *cpu_copy(CPUState *env);
+
 void cpu_dump_state(CPUState *env, FILE *f, 
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags);
diff --git a/exec.c b/exec.c
index 2e09b4bc3e9a9269f80c708f4b413b643541c8f9..37d58a43ea2ee5f161a57669ec639be6324ad4e3 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1222,6 +1222,18 @@ void cpu_abort(CPUState *env, const char *fmt, ...)
     abort();
 }
 
+CPUState *cpu_copy(CPUState *env)
+{
+    CPUState *new_env = cpu_init();
+    /* preserve chaining and index */
+    CPUState *next_cpu = new_env->next_cpu;
+    int cpu_index = new_env->cpu_index;
+    memcpy(new_env, env, sizeof(CPUState));
+    new_env->next_cpu = next_cpu;
+    new_env->cpu_index = cpu_index;
+    return new_env;
+}
+
 #if !defined(CONFIG_USER_ONLY)
 
 /* NOTE: if flush_global is true, also flush global entries (not
index f3f97b0d574cf62a21f266a0f2da6b3c9c5df96b..76b36524a1ce5c136f93dd17f31ad4354a566e3e 100644 (file)
@@ -1720,8 +1720,7 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
         ts->next = first_task_state;
         first_task_state = ts;
         /* we create a new CPU instance. */
-        new_env = cpu_init();
-        memcpy(new_env, env, sizeof(CPUState));
+        new_env = cpu_copy(env);
 #if defined(TARGET_I386)
         if (!newsp)
             newsp = env->regs[R_ESP];