cpu-exec: invalidate nocache translation if they are interrupted
authorPavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Wed, 26 Nov 2014 10:40:16 +0000 (13:40 +0300)
committerPaolo Bonzini <pbonzini@redhat.com>
Mon, 15 Dec 2014 11:21:02 +0000 (12:21 +0100)
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.

Signed-off-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
cpu-exec.c
include/exec/exec-all.h
translate-all.c

index cce80f0c01c203ff7cf78dd38acc777c7b863582..a4f0effaf4c9593d4f6cc1dbb64a6bed80692716 100644 (file)
@@ -216,7 +216,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);
+                     max_cycles | CF_NOCACHE);
     cpu->current_tb = tb;
     /* execute the generated code */
     trace_exec_tb_nocache(tb, tb->pc);
index 0844885eddc1750cc894ca5f1982deffa8a703cb..38a8a09b422109f2dc77273da7d18a47ba63b55d 100644 (file)
@@ -145,6 +145,7 @@ struct TranslationBlock {
     uint16_t cflags;    /* compile flags */
 #define CF_COUNT_MASK  0x7fff
 #define CF_LAST_IO     0x8000 /* Last insn may be an IO access.  */
+#define CF_NOCACHE     0x10000 /* To be freed after execution */
 
     void *tc_ptr;    /* pointer to the translated code */
     /* next matching tb for physical address. */
index ba5c8403d30b83f915253dc9d08edd7bc2af5913..cf054720085791aa0841c71964f94db12fbe3b11 100644 (file)
@@ -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;