Commit 6e68e076e72f42d43cc3b5435751d796c2410a3f
1 parent
a4a99d71
Move clone() register setup to target specific code. Handle fork-like clone.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4623 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
10 changed files
with
92 additions
and
58 deletions
linux-user/syscall.c
| ... | ... | @@ -2744,64 +2744,8 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) |
| 2744 | 2744 | first_task_state = ts; |
| 2745 | 2745 | /* we create a new CPU instance. */ |
| 2746 | 2746 | new_env = cpu_copy(env); |
| 2747 | -#if defined(TARGET_I386) | |
| 2748 | - if (!newsp) | |
| 2749 | - newsp = env->regs[R_ESP]; | |
| 2750 | - new_env->regs[R_ESP] = newsp; | |
| 2751 | - new_env->regs[R_EAX] = 0; | |
| 2752 | -#elif defined(TARGET_ARM) | |
| 2753 | - if (!newsp) | |
| 2754 | - newsp = env->regs[13]; | |
| 2755 | - new_env->regs[13] = newsp; | |
| 2756 | - new_env->regs[0] = 0; | |
| 2757 | -#elif defined(TARGET_SPARC) | |
| 2758 | - if (!newsp) | |
| 2759 | - newsp = env->regwptr[22]; | |
| 2760 | - new_env->regwptr[22] = newsp; | |
| 2761 | - new_env->regwptr[0] = 0; | |
| 2762 | - /* XXXXX */ | |
| 2763 | - printf ("HELPME: %s:%d\n", __FILE__, __LINE__); | |
| 2764 | -#elif defined(TARGET_M68K) | |
| 2765 | - if (!newsp) | |
| 2766 | - newsp = env->aregs[7]; | |
| 2767 | - new_env->aregs[7] = newsp; | |
| 2768 | - new_env->dregs[0] = 0; | |
| 2769 | - /* ??? is this sufficient? */ | |
| 2770 | -#elif defined(TARGET_MIPS) | |
| 2771 | - if (!newsp) | |
| 2772 | - newsp = env->gpr[env->current_tc][29]; | |
| 2773 | - new_env->gpr[env->current_tc][29] = newsp; | |
| 2774 | -#elif defined(TARGET_PPC) | |
| 2775 | - if (!newsp) | |
| 2776 | - newsp = env->gpr[1]; | |
| 2777 | - new_env->gpr[1] = newsp; | |
| 2778 | - { | |
| 2779 | - int i; | |
| 2780 | - for (i = 7; i < 32; i++) | |
| 2781 | - new_env->gpr[i] = 0; | |
| 2782 | - } | |
| 2783 | -#elif defined(TARGET_SH4) | |
| 2784 | - if (!newsp) | |
| 2785 | - newsp = env->gregs[15]; | |
| 2786 | - new_env->gregs[15] = newsp; | |
| 2787 | - /* XXXXX */ | |
| 2788 | -#elif defined(TARGET_ALPHA) | |
| 2789 | - if (!newsp) | |
| 2790 | - newsp = env->ir[30]; | |
| 2791 | - new_env->ir[30] = newsp; | |
| 2792 | - /* ? */ | |
| 2793 | - { | |
| 2794 | - int i; | |
| 2795 | - for (i = 7; i < 30; i++) | |
| 2796 | - new_env->ir[i] = 0; | |
| 2797 | - } | |
| 2798 | -#elif defined(TARGET_CRIS) | |
| 2799 | - if (!newsp) | |
| 2800 | - newsp = env->regs[14]; | |
| 2801 | - new_env->regs[14] = newsp; | |
| 2802 | -#else | |
| 2803 | -#error unsupported target CPU | |
| 2804 | -#endif | |
| 2747 | + /* Init regs that differ from the parent. */ | |
| 2748 | + cpu_clone_regs(new_env, newsp); | |
| 2805 | 2749 | new_env->opaque = ts; |
| 2806 | 2750 | #ifdef __ia64__ |
| 2807 | 2751 | ret = __clone2(clone_func, new_stack + NEW_STACK_SIZE, flags, new_env); |
| ... | ... | @@ -2813,6 +2757,9 @@ int do_fork(CPUState *env, unsigned int flags, abi_ulong newsp) |
| 2813 | 2757 | if ((flags & ~CSIGNAL) != 0) |
| 2814 | 2758 | return -EINVAL; |
| 2815 | 2759 | ret = fork(); |
| 2760 | + if (ret == 0) { | |
| 2761 | + cpu_clone_regs(env, newsp); | |
| 2762 | + } | |
| 2816 | 2763 | } |
| 2817 | 2764 | return ret; |
| 2818 | 2765 | } | ... | ... |
target-alpha/cpu.h
| ... | ... | @@ -311,6 +311,15 @@ static inline int cpu_mmu_index (CPUState *env) |
| 311 | 311 | return (env->ps >> 3) & 3; |
| 312 | 312 | } |
| 313 | 313 | |
| 314 | +#if defined(CONFIG_USER_ONLY) | |
| 315 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 316 | +{ | |
| 317 | + if (!newsp) | |
| 318 | + env->ir[30] = newsp; | |
| 319 | + /* FIXME: Zero syscall return value. */ | |
| 320 | +} | |
| 321 | +#endif | |
| 322 | + | |
| 314 | 323 | #include "cpu-all.h" |
| 315 | 324 | |
| 316 | 325 | enum { | ... | ... |
target-arm/cpu.h
| ... | ... | @@ -408,6 +408,15 @@ static inline int cpu_mmu_index (CPUState *env) |
| 408 | 408 | return (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR ? 1 : 0; |
| 409 | 409 | } |
| 410 | 410 | |
| 411 | +#if defined(CONFIG_USER_ONLY) | |
| 412 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 413 | +{ | |
| 414 | + if (!newsp) | |
| 415 | + env->regs[13] = newsp; | |
| 416 | + env->regs[0] = 0; | |
| 417 | +} | |
| 418 | +#endif | |
| 419 | + | |
| 411 | 420 | #include "cpu-all.h" |
| 412 | 421 | |
| 413 | 422 | #endif | ... | ... |
target-cris/cpu.h
| ... | ... | @@ -218,6 +218,15 @@ static inline int cpu_mmu_index (CPUState *env) |
| 218 | 218 | return !!(env->pregs[PR_CCS] & U_FLAG); |
| 219 | 219 | } |
| 220 | 220 | |
| 221 | +#if defined(CONFIG_USER_ONLY) | |
| 222 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 223 | +{ | |
| 224 | + if (!newsp) | |
| 225 | + env->regs[14] = newsp; | |
| 226 | + env->regs[10] = 0; | |
| 227 | +} | |
| 228 | +#endif | |
| 229 | + | |
| 221 | 230 | /* Support function regs. */ |
| 222 | 231 | #define SFR_RW_GC_CFG 0][0 |
| 223 | 232 | #define SFR_RW_MM_CFG env->pregs[PR_SRS]][0 | ... | ... |
target-i386/cpu.h
| ... | ... | @@ -734,6 +734,15 @@ typedef struct CCTable { |
| 734 | 734 | |
| 735 | 735 | extern CCTable cc_table[]; |
| 736 | 736 | |
| 737 | +#if defined(CONFIG_USER_ONLY) | |
| 738 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 739 | +{ | |
| 740 | + if (!newsp) | |
| 741 | + env->regs[R_ESP] = newsp; | |
| 742 | + env->regs[R_EAX] = 0; | |
| 743 | +} | |
| 744 | +#endif | |
| 745 | + | |
| 737 | 746 | #include "cpu-all.h" |
| 738 | 747 | |
| 739 | 748 | #include "svm.h" | ... | ... |
target-m68k/cpu.h
| ... | ... | @@ -226,6 +226,15 @@ static inline int cpu_mmu_index (CPUState *env) |
| 226 | 226 | return (env->sr & SR_S) == 0 ? 1 : 0; |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | +#if defined(CONFIG_USER_ONLY) | |
| 230 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 231 | +{ | |
| 232 | + if (!newsp) | |
| 233 | + env->aregs[7] = newsp; | |
| 234 | + env->dregs[0] = 0; | |
| 235 | +} | |
| 236 | +#endif | |
| 237 | + | |
| 229 | 238 | #include "cpu-all.h" |
| 230 | 239 | |
| 231 | 240 | #endif | ... | ... |
target-mips/cpu.h
| ... | ... | @@ -500,6 +500,16 @@ static inline int cpu_mmu_index (CPUState *env) |
| 500 | 500 | return env->hflags & MIPS_HFLAG_KSU; |
| 501 | 501 | } |
| 502 | 502 | |
| 503 | +#if defined(CONFIG_USER_ONLY) | |
| 504 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 505 | +{ | |
| 506 | + if (!newsp) | |
| 507 | + env->gpr[env->current_tc][29] = newsp; | |
| 508 | + env->gpr[env->current_tc][7] = 0; | |
| 509 | + env->gpr[env->current_tc][2] = 0; | |
| 510 | +} | |
| 511 | +#endif | |
| 512 | + | |
| 503 | 513 | #include "cpu-all.h" |
| 504 | 514 | |
| 505 | 515 | /* Memory access type : | ... | ... |
target-ppc/cpu.h
| ... | ... | @@ -822,6 +822,17 @@ static inline int cpu_mmu_index (CPUState *env) |
| 822 | 822 | return env->mmu_idx; |
| 823 | 823 | } |
| 824 | 824 | |
| 825 | +#if defined(CONFIG_USER_ONLY) | |
| 826 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 827 | +{ | |
| 828 | + int i; | |
| 829 | + if (!newsp) | |
| 830 | + env->gpr[1] = newsp; | |
| 831 | + for (i = 7; i < 32; i++) | |
| 832 | + env->gpr[i] = 0; | |
| 833 | +} | |
| 834 | +#endif | |
| 835 | + | |
| 825 | 836 | #include "cpu-all.h" |
| 826 | 837 | |
| 827 | 838 | /*****************************************************************************/ | ... | ... |
target-sh4/cpu.h
| ... | ... | @@ -143,6 +143,15 @@ static inline int cpu_mmu_index (CPUState *env) |
| 143 | 143 | return (env->sr & SR_MD) == 0 ? 1 : 0; |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | +#if defined(CONFIG_USER_ONLY) | |
| 147 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 148 | +{ | |
| 149 | + if (!newsp) | |
| 150 | + env->gregs[15] = newsp; | |
| 151 | + env->gregs[0] = 0; | |
| 152 | +} | |
| 153 | +#endif | |
| 154 | + | |
| 146 | 155 | #include "cpu-all.h" |
| 147 | 156 | |
| 148 | 157 | /* Memory access type */ | ... | ... |
target-sparc/cpu.h
| ... | ... | @@ -403,6 +403,18 @@ static inline int cpu_fpu_enabled(CPUState *env1) |
| 403 | 403 | #endif |
| 404 | 404 | } |
| 405 | 405 | |
| 406 | +#if defined(CONFIG_USER_ONLY) | |
| 407 | +static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) | |
| 408 | +{ | |
| 409 | + if (!newsp) | |
| 410 | + env->regwptr[22] = newsp; | |
| 411 | + env->regwptr[0] = 0; | |
| 412 | + /* FIXME: Do we also need to clear CF? */ | |
| 413 | + /* XXXXX */ | |
| 414 | + printf ("HELPME: %s:%d\n", __FILE__, __LINE__); | |
| 415 | +} | |
| 416 | +#endif | |
| 417 | + | |
| 406 | 418 | #include "cpu-all.h" |
| 407 | 419 | |
| 408 | 420 | #endif | ... | ... |