[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_si
From: |
Nathan Froyd |
Subject: |
[Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal |
Date: |
Tue, 21 Apr 2009 18:33:28 -0700 |
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.
I don't understand what the "activate soft MMU for this block" is trying
to do. (Especially since handle_cpu_signal and company are under
!defined(CONFIG_SOFTMMU)...) Even though it appears that if
cpu_*_handle_mmu_fault ever returns a value > 0, that value is always
one and therefore that block is superfluous, I've left that cleanup for
a later time. Likewise for why x86 has a different EXCEPTION_ACTION
than everyone else.
Signed-off-by: Nathan Froyd <address@hidden>
---
cpu-exec.c | 379 +++-------------------------------------------------
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-mips/cpu.h | 1 +
target-ppc/cpu.h | 1 +
target-sh4/cpu.h | 1 +
target-sparc/cpu.h | 1 +
10 files changed, 31 insertions(+), 357 deletions(-)
diff --git a/cpu-exec.c b/cpu-exec.c
index 122bdd1..4d316b0 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -754,6 +754,24 @@ 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)
+#define SOFTMMU_EXTRA_ACTION env->hflags |= HF_SOFTMMU_MASK
+#define ACTIVATE_SOFTMMU 1
+#elif defined(TARGET_PPC)
+#define ACTIVATE_SOFTMMU 1
+#elif defined(TARGET_MIPS)
+#define ACTIVATE_SOFTMMU 1
+#endif
+
+#if !defined(EXCEPTION_ACTION)
+#define EXCEPTION_ACTION cpu_loop_exit()
+#endif
+#if !defined(SOFTMMU_EXTRA_ACTION
+#define SOFTMMU_EXTRA_ACTION
+#endif
+#if !defined(ACTIVATE_SOFTMMU)
+#define ACTIVATE_SOFTMMU 0
+#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
@@ -778,7 +796,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);
+ 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)
@@ -790,373 +808,20 @@ static inline int handle_cpu_signal(unsigned long pc,
unsigned long address,
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
+ if (!ACTIVATE_SOFTMMU || ret == 1) {
/* 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);
- 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_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;
-}
-
-#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();
+ EXCEPTION_ACTION;
} else {
/* activate soft MMU for this block */
+ SOFTMMU_EXTRA_ACTION;
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__)
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index 8c64def..ade180d 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -434,6 +434,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_fault
void do_interrupt (CPUState *env);
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index f98655f..192a92f 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -221,6 +221,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_fault
void cpu_lock(void);
void cpu_unlock(void);
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index e98a48d..e313a0b 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -219,6 +219,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)
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index c6bca94..9a6b00c 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -774,6 +774,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_fault
void 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,
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index e2529eb..195cb23 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -225,6 +225,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)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index b415dc4..459edb5 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -579,6 +579,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_fault
void do_interrupt (CPUState *env);
void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 87b3460..b4ad998 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -703,6 +703,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_fault
int get_physical_address (CPUPPCState *env, mmu_ctx_t *ctx, target_ulong vaddr,
int rw, int access_type);
void do_interrupt (CPUPPCState *env);
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index e597f65..3c125c8 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -164,6 +164,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_fault
void do_interrupt(CPUSH4State * env);
void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 8b84789..2b6c1bb 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -349,6 +349,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_fault
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
void dump_mmu(CPUSPARCState *env);
--
1.6.0.5
- [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal,
Nathan Froyd <=
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Paul Brook, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Avi Kivity, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Paul Brook, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Avi Kivity, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Blue Swirl, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Avi Kivity, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Blue Swirl, 2009/04/30
- Re: [Qemu-devel] [PATCH] [RFC] cleanup cpu-exec.c: consolidate handle_cpu_signal, Laurent Desnogues, 2009/04/30