diff mbox

[RFC,v5,16/31] cpu-exec: invalidate nocache translation if they are interrupted

Message ID 20141126104016.7772.3680.stgit@PASHA-ISP
State New
Headers show

Commit Message

Pavel Dovgalyuk Nov. 26, 2014, 10:40 a.m. UTC
In this case, QEMU might longjmp out of cpu-exec.c and miss the final
cleanup in cpu_exec_nocache.  Do this manually through a new compile
flag.  This is important once we add no-icount translations.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 cpu-exec.c              |    2 +-
 include/exec/exec-all.h |    1 +
 translate-all.c         |    6 ++++++
 3 files changed, 8 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/cpu-exec.c b/cpu-exec.c
index 05341cf..65cbeb7 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -214,7 +214,7 @@  static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
     /* tb_gen_code can flush our orig_tb, invalidate it now */
     tb_phys_invalidate(orig_tb, -1);
     tb = tb_gen_code(cpu, pc, cs_base, flags,
-                     max_cycles | (ignore_icount ? CF_IGNORE_ICOUNT : 0));
+                     max_cycles | CF_NOCACHE | (ignore_icount ? CF_IGNORE_ICOUNT : 0));
     cpu->current_tb = tb;
     /* execute the generated code */
     trace_exec_tb_nocache(tb, tb->pc);
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 1e6d7e8..d409565 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -148,6 +148,7 @@  struct TranslationBlock {
 #define CF_LAST_IO     0x8000 /* Last insn may be an IO access.  */
 #define CF_USE_ICOUNT  0x10000
 #define CF_IGNORE_ICOUNT 0x20000 /* Do not generate icount code */
+#define CF_NOCACHE     0x40000 /* To be freed after execution */
 
     void *tc_ptr;    /* pointer to the translated code */
     /* next matching tb for physical address. */
diff --git a/translate-all.c b/translate-all.c
index 21a78a4..269c4ba 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -264,6 +264,12 @@  bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
     tb = tb_find_pc(retaddr);
     if (tb) {
         cpu_restore_state_from_tb(cpu, tb, retaddr);
+        if (tb->cflags & CF_NOCACHE) {
+            /* one-shot translation, invalidate it immediately */
+            cpu->current_tb = NULL;
+            tb_phys_invalidate(tb, -1);
+            tb_free(tb);
+        }
         return true;
     }
     return false;