From c5be9f0898b92d0d6bfb458fd50fc170f4300361 Mon Sep 17 00:00:00 2001 From: ths Date: Wed, 28 Feb 2007 20:20:53 +0000 Subject: [PATCH] Fix CPU chaining in linux-user emulation, by Gwenole Beauchesne. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2459 c046a42c-6fe2-441c-8c8c-71466251a162 --- cpu-all.h | 2 ++ exec.c | 12 ++++++++++++ linux-user/syscall.c | 3 +-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 8a4730d32c..0ad50e8bf6 100644 --- 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 2e09b4bc3e..37d58a43ea 100644 --- 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 diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f3f97b0d57..76b36524a1 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -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];