@@ -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);
@@ -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. */
@@ -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;