cleanup cpu-exec.c, part 0/N: consolidate handle_cpu_signal
PATCH 1/1 cleanup cpu-exec.c, part 0/N: consolidate handle_cpu_signal
From: Nathan Froyd <[email protected]>
handle_cpu_signal is very nearly copy-paste code for each target, with a few minor variations. This patch sets up appropriate defaults for a generic handle_cpu_signal and provides overrides for particular targets that did things differently. Fixing things like the persistent (XXX:
use sigsetjmp) should now become somewhat easier.
Previous comments on this patch suggest that the "activate soft MMU for this block" comments refer to defunct functionality. I have removed such blocks for the appropriate targets in this patch.
--- cpu-exec.c | 415 +---------------------------------------------- target-alpha/cpu.h | 1 + target-arm/cpu.h | 1 + target-cris/cpu.h | 1 + target-i386/cpu.h | 1 + target-m68k/cpu.h | 1 + target-microblaze/cpu.h | 1 + target-mips/cpu.h | 1 + target-ppc/cpu.h | 1 + target-sh4/cpu.h | 1 + target-sparc/cpu.h | 1 + 11 files changed, 16 insertions(+), 409 deletions(-)
cpu-exec.c +6 -409
@@ -785,6 +785,10 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)#if !defined(CONFIG_SOFTMMU )#if defined(TARGET_I386 ) +#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code) +#else +#define EXCEPTION_ACTION cpu_loop_exit() +#endif /* 'pc' is the host PC at which the exception was raised. 'address' is the effective address of the memory exception. 'is_write' is 1 if a
@@ -809,56 +813,7 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address, }/* see if it is an MMU fault */ - ret =cpu_x86_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -if (ret ==1 ) { -#if 0 -printf ("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n" , - env->eip, env->cr[2 ], env->error_code); -#endif -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -raise_exception_err (env->exception_index, env->error_code); - }else { -/* activate soft MMU for this block */ - env->hflags |=HF_SOFTMMU_MASK ; -cpu_resume_from_signal (env, puc); - } -/* never comes here */ -return 1 ; -} - -#elif defined(TARGET_ARM) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } -/* see if it is an MMU fault */ - ret =cpu_arm_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); + ret =cpu_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 );if (ret <0 )return 0 ;/* not an MMU fault */ if (ret ==0 )
@@ -870,374 +825,16 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,a virtual CPU fault */ cpu_restore_state (tb, env, pc, puc); } -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); -/* never comes here */ -return 1 ; -} -#elif defined(TARGET_SPARC) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } -/* see if it is an MMU fault */ - ret =cpu_sparc_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - }/* we restore the process signal mask as the sigreturn should do it (XXX: use sigsetjmp) */ sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); -/* never comes here */ -return 1 ; -} -#elif defined (TARGET_PPC) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } - -/* see if it is an MMU fault */ - ret =cpu_ppc_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ - -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -if (ret ==1 ) { -#if 0 -printf ("PF exception: NIP=0x%08x error=0x%x %p\n" , - env->nip, env->error_code, tb); -#endif -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); - }else { -/* activate soft MMU for this block */ -cpu_resume_from_signal (env, puc); - } -/* never comes here */ -return 1 ; -} +EXCEPTION_ACTION ; -#elif defined(TARGET_M68K) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (address, pc, puc)) { -return 1 ; - } -/* see if it is an MMU fault */ - ret =cpu_m68k_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit ();/* never comes here */ return 1 ; } -#elif defined (TARGET_MIPS) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } - -/* see if it is an MMU fault */ - ret =cpu_mips_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ - -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -if (ret ==1 ) { -#if 0 -printf ("PF exception: PC=0x" TARGET_FMT_lx" error=0x%x %p\n" , - env->PC, env->error_code, tb); -#endif -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); - }else { -/* activate soft MMU for this block */ -cpu_resume_from_signal (env, puc); - } -/* never comes here */ -return 1 ; -} - -#elif defined (TARGET_MICROBLAZE) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } - -/* see if it is an MMU fault */ - ret =cpu_mb_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ - -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -if (ret ==1 ) { -#if 0 -printf ("PF exception: PC=0x" TARGET_FMT_lx" error=0x%x %p\n" , - env->PC, env->error_code, tb); -#endif -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); - }else { -/* activate soft MMU for this block */ -cpu_resume_from_signal (env, puc); - } -/* never comes here */ -return 1 ; -} - -#elif defined (TARGET_SH4) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } - -/* see if it is an MMU fault */ - ret =cpu_sh4_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ - -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -#if 0 -printf ("PF exception: NIP=0x%08x error=0x%x %p\n" , - env->nip, env->error_code, tb); -#endif -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); -/* never comes here */ -return 1 ; -} - -#elif defined (TARGET_ALPHA) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } - -/* see if it is an MMU fault */ - ret =cpu_alpha_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ - -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -#if 0 -printf ("PF exception: NIP=0x%08x error=0x%x %p\n" , - env->nip, env->error_code, tb); -#endif -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); -/* never comes here */ -return 1 ; -} -#elif defined (TARGET_CRIS) -static inline int handle_cpu_signal (unsigned long pc,unsigned long address, -int is_write,sigset_t *old_set, -void *puc) -{ -TranslationBlock *tb; -int ret; - -if (cpu_single_env) - env = cpu_single_env;/* XXX: find a correct solution for multithread */ -#if defined(DEBUG_SIGNAL ) -printf ("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n" , - pc, address, is_write, *(unsigned long *)old_set); -#endif -/* XXX: locking issue */ -if (is_write &&page_unprotect (h2g (address), pc, puc)) { -return 1 ; - } - -/* see if it is an MMU fault */ - ret =cpu_cris_handle_mmu_fault (env, address, is_write,MMU_USER_IDX ,0 ); -if (ret <0 ) -return 0 ;/* not an MMU fault */ -if (ret ==0 ) -return 1 ;/* the MMU fault was handled without causing real CPU fault */ - -/* now we have a real cpu fault */ - tb =tb_find_pc (pc); -if (tb) { -/* the PC is inside the translated code. It means that we have -a virtual CPU fault */ -cpu_restore_state (tb, env, pc, puc); - } -/* we restore the process signal mask as the sigreturn should -do it (XXX: use sigsetjmp) */ -sigprocmask (SIG_SETMASK , old_set,NULL ); -cpu_loop_exit (); -/* never comes here */ -return 1 ; -} - -#else -#error unsupported target CPU -#endif -#if defined(__i386__)#if defined(__APPLE__)
target-alpha/cpu.h +1 -0
@@ -433,6 +433,7 @@ int cpu_alpha_signal_handler(int host_signum, void *pinfo, void *puc);int cpu_alpha_handle_mmu_fault (CPUState *env,uint64_t address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_faultvoid do_interrupt (CPUState *env);int cpu_alpha_mfpr (CPUState *env,int iprn,uint64_t *valp);
target-arm/cpu.h +1 -0
@@ -220,6 +220,7 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo, void *puc);int cpu_arm_handle_mmu_fault (CPUARMState *env,target_ulong address,int rw,int mmu_idx,int is_softmuu); +#define cpu_handle_mmu_fault cpu_arm_handle_mmu_faultvoid cpu_lock (void );void cpu_unlock (void );
target-cris/cpu.h +1 -0
@@ -213,6 +213,7 @@ static inline int cpu_mmu_index (CPUState *env)int cpu_cris_handle_mmu_fault (CPUState *env,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_cris_handle_mmu_fault#if defined(CONFIG_USER_ONLY )static inline void cpu_clone_regs (CPUState *env,target_ulong newsp)
target-i386/cpu.h +1 -0
@@ -804,6 +804,7 @@ int cpu_x86_signal_handler(int host_signum, void *pinfo,/* helper.c */ int cpu_x86_handle_mmu_fault (CPUX86State *env,target_ulong addr,int is_write,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_x86_handle_mmu_faultvoid cpu_x86_set_a20 (CPUX86State *env,int a20_state); void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *eax, uint32_t *ebx,
target-m68k/cpu.h +1 -0
@@ -227,6 +227,7 @@ static inline int cpu_mmu_index (CPUState *env)int cpu_m68k_handle_mmu_fault (CPUState *env,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_m68k_handle_mmu_fault#if defined(CONFIG_USER_ONLY )static inline void cpu_clone_regs (CPUState *env,target_ulong newsp)
target-microblaze/cpu.h +1 -0
@@ -268,6 +268,7 @@ static inline int cpu_mmu_index (CPUState *env)int cpu_mb_handle_mmu_fault (CPUState *env,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_mb_handle_mmu_fault#if defined(CONFIG_USER_ONLY )static inline void cpu_clone_regs (CPUState *env,target_ulong newsp)
target-mips/cpu.h +1 -0
@@ -584,6 +584,7 @@ void cpu_mips_update_irq (CPUState *env);/* helper.c */ int cpu_mips_handle_mmu_fault (CPUState *env,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_mips_handle_mmu_faultvoid do_interrupt (CPUState *env);void r4k_invalidate_tlb (CPUState *env,int idx,int use_extra);
target-ppc/cpu.h +1 -0
@@ -710,6 +710,7 @@ int cpu_ppc_signal_handler (int host_signum, void *pinfo, void *puc);int cpu_ppc_handle_mmu_fault (CPUPPCState *env,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_ppc_handle_mmu_faultint get_physical_address (CPUPPCState *env,mmu_ctx_t *ctx,target_ulong vaddr,int rw,int access_type);void do_interrupt (CPUPPCState *env);
target-sh4/cpu.h +1 -0
@@ -163,6 +163,7 @@ int cpu_sh4_signal_handler(int host_signum, void *pinfo, void *puc);int cpu_sh4_handle_mmu_fault (CPUSH4State * env,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_sh4_handle_mmu_faultvoid do_interrupt (CPUSH4State * env);void sh4_cpu_list (FILE *f,int (*cpu_fprintf)(FILE *f,const char *fmt, ...));
target-sparc/cpu.h +1 -0
@@ -413,6 +413,7 @@ void cpu_lock(void);void cpu_unlock (void );int cpu_sparc_handle_mmu_fault (CPUSPARCState *env1,target_ulong address,int rw,int mmu_idx,int is_softmmu); +#define cpu_handle_mmu_fault cpu_sparc_handle_mmu_faulttarget_ulong mmu_probe (CPUSPARCState *env,target_ulong address,int mmulev);void dump_mmu (CPUSPARCState *env);
Signature · 1 line
1.6.3.2
Quoted 8 lines · On Mon, Aug 10, 2009 at 10:37 PM, <[email protected]> wrote:
From: Nathan Froyd <[email protected]>
handle_cpu_signalis very nearly copy-paste code for each target, with a few minor variations. This patch sets up appropriate defaults for a generichandle_cpu_signaland provides overrides for particular targets that did things differently. Fixing things like the persistent (XXX:
use sigsetjmp) should now become somewhat easier.
Quoted 5 lines
Previous comments on this patch suggest that the "activate soft MMU for this block" comments refer to defunct functionality. I have removed such blocks for the appropriate targets in this patch.
Signed-off-by Nathan Froyd <[email protected]>
Thanks for the patch!
Best regards,
Filip Navara