Apologies, the patch got messed up.
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index c01f59c743..7a9e8c94bd 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -238,8 +238,11 @@ void cpu_exec_step_atomic(CPUState *cpu) uint32_t flags; uint32_t cflags = 1; uint32_t cf_mask = cflags & CF_HASH_MASK; + unsigned flush_count;
if (sigsetjmp(cpu->jmp_env, 0) == 0) { +retry: + flush_count = tb_flush_count(); tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask); if (tb == NULL) { mmap_lock(); @@ -248,6 +251,11 @@ void cpu_exec_step_atomic(CPUState *cpu) }
start_exclusive(); + /* do_tb_flush() might run and make tb invalid */ + if (flush_count != tb_flush_count()) { + end_exclusive(); + goto retry; + }
/* Since we got here, we know that parallel_cpus must be true. */ parallel_cpus = false; diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 9f48da9472..2fb7da9b51 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -2674,3 +2674,8 @@ void tcg_flush_softmmu_tlb(CPUState *cs) tlb_flush(cs); #endif } + +unsigned tb_flush_count(void) +{ + return atomic_read(&tb_ctx.tb_flush_count); +} diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index d85e610e85..aa3c2d219a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -579,6 +579,9 @@ void tlb_set_dirty(CPUState *cpu, target_ulong vaddr); /* exec.c */ void tb_flush_jmp_cache(CPUState *cpu, target_ulong addr);
+/* translate-all.c */ +unsigned tb_flush_count(void); + MemoryRegionSection * address_space_translate_for_iotlb(CPUState *cpu, int asidx, hwaddr addr, hwaddr *xlat, hwaddr *plen,
Apologies, the patch got messed up.
diff --git a/accel/ tcg/cpu- exec.c b/accel/ tcg/cpu- exec.c .7a9e8c94bd 100644 tcg/cpu- exec.c tcg/cpu- exec.c step_atomic( CPUState *cpu)
index c01f59c743.
--- a/accel/
+++ b/accel/
@@ -238,8 +238,11 @@ void cpu_exec_
uint32_t flags;
uint32_t cflags = 1;
uint32_t cf_mask = cflags & CF_HASH_MASK;
+ unsigned flush_count;
if (sigsetjmp( cpu->jmp_ env, 0) == 0) { _cpu_state( cpu, &pc, &cs_base, &flags, cf_mask);
mmap_ lock(); step_atomic( CPUState *cpu)
+retry:
+ flush_count = tb_flush_count();
tb = tb_lookup_
if (tb == NULL) {
@@ -248,6 +251,11 @@ void cpu_exec_
}
+ /* do_tb_flush() might run and make tb invalid */
+ if (flush_count != tb_flush_count()) {
+ end_exclusive();
+ goto retry;
+ }
/* Since we got here, we know that parallel_cpus must be true. */
parallel_ cpus = false; tcg/translate- all.c b/accel/ tcg/translate- all.c .2fb7da9b51 100644 tcg/translate- all.c tcg/translate- all.c softmmu_ tlb(CPUState *cs) count(void) read(&tb_ ctx.tb_ flush_count) ; exec/exec- all.h b/include/ exec/exec- all.h .aa3c2d219a 100644 exec/exec- all.h exec/exec- all.h dirty(CPUState *cpu, target_ulong vaddr); jmp_cache( CPUState *cpu, target_ulong addr);
diff --git a/accel/
index 9f48da9472.
--- a/accel/
+++ b/accel/
@@ -2674,3 +2674,8 @@ void tcg_flush_
tlb_flush(cs);
#endif
}
+
+unsigned tb_flush_
+{
+ return atomic_
+}
diff --git a/include/
index d85e610e85.
--- a/include/
+++ b/include/
@@ -579,6 +579,9 @@ void tlb_set_
/* exec.c */
void tb_flush_
+/* translate-all.c */ count(void) ; ction * space_translate _for_iotlb( CPUState *cpu, int asidx, hwaddr addr,
hwaddr *xlat, hwaddr *plen,
+unsigned tb_flush_
+
MemoryRegionSe
address_