aboutsummaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-06-14 18:56:36 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-06-14 18:56:36 +0000
commitea1c18022edd0e2c45552d6fc2da6e15a3486b33 (patch)
tree86c5fe301fa6820d734b1fda60e72bb85f9b8183 /exec.c
parent516633dc42a2cd92347f1bd2ba365b4043b6e8e3 (diff)
fixed self modifying code in case of asynchronous interrupt
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@924 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/exec.c b/exec.c
index 617dea13ca..91694a53a2 100644
--- a/exec.c
+++ b/exec.c
@@ -613,7 +613,7 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
CPUState *env = cpu_single_env;
#endif
PageDesc *p;
- TranslationBlock *tb, *tb_next, *current_tb;
+ TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
target_ulong tb_start, tb_end;
target_ulong current_pc, current_cs_base;
@@ -681,7 +681,12 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
#endif
}
#endif /* TARGET_HAS_PRECISE_SMC */
+ saved_tb = env->current_tb;
+ env->current_tb = NULL;
tb_phys_invalidate(tb, -1);
+ env->current_tb = saved_tb;
+ if (env->interrupt_request && env->current_tb)
+ cpu_interrupt(env, env->interrupt_request);
}
tb = tb_next;
}
@@ -699,6 +704,7 @@ void tb_invalidate_phys_page_range(target_ulong start, target_ulong end,
/* we generate a block containing just the instruction
modifying the memory. It will ensure that it cannot modify
itself */
+ env->current_tb = NULL;
tb_gen_code(env, current_pc, current_cs_base, current_flags,
CF_SINGLE_INSN);
cpu_resume_from_signal(env, NULL);
@@ -795,6 +801,7 @@ static void tb_invalidate_phys_page(target_ulong addr,
/* we generate a block containing just the instruction
modifying the memory. It will ensure that it cannot modify
itself */
+ env->current_tb = NULL;
tb_gen_code(env, current_pc, current_cs_base, current_flags,
CF_SINGLE_INSN);
cpu_resume_from_signal(env, puc);