Commit c5be9f0898b92d0d6bfb458fd50fc170f4300361
1 parent
130751ee
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
Showing
3 changed files
with
15 additions
and
2 deletions
cpu-all.h
| @@ -754,6 +754,8 @@ void page_unprotect_range(target_ulong data, target_ulong data_size); | @@ -754,6 +754,8 @@ void page_unprotect_range(target_ulong data, target_ulong data_size); | ||
| 754 | 754 | ||
| 755 | #endif /* SINGLE_CPU_DEFINES */ | 755 | #endif /* SINGLE_CPU_DEFINES */ |
| 756 | 756 | ||
| 757 | +CPUState *cpu_copy(CPUState *env); | ||
| 758 | + | ||
| 757 | void cpu_dump_state(CPUState *env, FILE *f, | 759 | void cpu_dump_state(CPUState *env, FILE *f, |
| 758 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), | 760 | int (*cpu_fprintf)(FILE *f, const char *fmt, ...), |
| 759 | int flags); | 761 | int flags); |
exec.c
| @@ -1222,6 +1222,18 @@ void cpu_abort(CPUState *env, const char *fmt, ...) | @@ -1222,6 +1222,18 @@ void cpu_abort(CPUState *env, const char *fmt, ...) | ||
| 1222 | abort(); | 1222 | abort(); |
| 1223 | } | 1223 | } |
| 1224 | 1224 | ||
| 1225 | +CPUState *cpu_copy(CPUState *env) | ||
| 1226 | +{ | ||
| 1227 | + CPUState *new_env = cpu_init(); | ||
| 1228 | + /* preserve chaining and index */ | ||
| 1229 | + CPUState *next_cpu = new_env->next_cpu; | ||
| 1230 | + int cpu_index = new_env->cpu_index; | ||
| 1231 | + memcpy(new_env, env, sizeof(CPUState)); | ||
| 1232 | + new_env->next_cpu = next_cpu; | ||
| 1233 | + new_env->cpu_index = cpu_index; | ||
| 1234 | + return new_env; | ||
| 1235 | +} | ||
| 1236 | + | ||
| 1225 | #if !defined(CONFIG_USER_ONLY) | 1237 | #if !defined(CONFIG_USER_ONLY) |
| 1226 | 1238 | ||
| 1227 | /* NOTE: if flush_global is true, also flush global entries (not | 1239 | /* NOTE: if flush_global is true, also flush global entries (not |
linux-user/syscall.c
| @@ -1720,8 +1720,7 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) | @@ -1720,8 +1720,7 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp) | ||
| 1720 | ts->next = first_task_state; | 1720 | ts->next = first_task_state; |
| 1721 | first_task_state = ts; | 1721 | first_task_state = ts; |
| 1722 | /* we create a new CPU instance. */ | 1722 | /* we create a new CPU instance. */ |
| 1723 | - new_env = cpu_init(); | ||
| 1724 | - memcpy(new_env, env, sizeof(CPUState)); | 1723 | + new_env = cpu_copy(env); |
| 1725 | #if defined(TARGET_I386) | 1724 | #if defined(TARGET_I386) |
| 1726 | if (!newsp) | 1725 | if (!newsp) |
| 1727 | newsp = env->regs[R_ESP]; | 1726 | newsp = env->regs[R_ESP]; |