@@ -19,6 +19,12 @@
#include "tcg/tcg-mo.h"
struct TCGCPUOps {
+ /**
+ * @precise_smc: Stores which modify code within the current TB force
+ * the TB to exit; the next executed instruction will see
+ * the result of the store.
+ */
+ bool precise_smc;
/**
* @guest_default_memory_order: default barrier that is required
@@ -38,7 +38,6 @@
#pragma GCC poison TARGET_SUPPORTS_MTTCG
#pragma GCC poison TARGET_BIG_ENDIAN
#pragma GCC poison TCG_GUEST_DEFAULT_MO
-#pragma GCC poison TARGET_HAS_PRECISE_SMC
#pragma GCC poison TARGET_LONG_BITS
#pragma GCC poison TARGET_FMT_lx
@@ -35,10 +35,6 @@
#define XEN_NR_VIRQS 24
-/* support for self modifying code even if the modified instruction is
- close to the modifying instruction */
-#define TARGET_HAS_PRECISE_SMC
-
#ifdef TARGET_X86_64
#define I386_ELF_MACHINE EM_X86_64
#define ELF_MACHINE_UNAME "x86_64"
@@ -35,8 +35,6 @@
#define ELF_MACHINE_UNAME "S390X"
-#define TARGET_HAS_PRECISE_SMC
-
#define MMU_USER_IDX 0
#define S390_MAX_CPUS 248
@@ -28,6 +28,7 @@
#include "exec/mmap-lock.h"
#include "exec/tb-flush.h"
#include "exec/target_page.h"
+#include "accel/tcg/cpu-ops.h"
#include "tb-internal.h"
#include "system/tcg.h"
#include "tcg/tcg.h"
@@ -1041,9 +1042,7 @@ static void tb_invalidate_phys_page(tb_page_addr_t addr)
/*
* Called with mmap_lock held. If pc is not 0 then it indicates the
* host PC of the faulting store instruction that caused this invalidate.
- * Returns true if the caller needs to abort execution of the current
- * TB (because it was modified by this store and the guest CPU has
- * precise-SMC semantics).
+ * Returns true if the caller needs to abort execution of the current TB.
*/
bool tb_invalidate_phys_page_unwind(CPUState *cpu, tb_page_addr_t addr,
uintptr_t pc)
@@ -1058,10 +1057,7 @@ bool tb_invalidate_phys_page_unwind(CPUState *cpu, tb_page_addr_t addr,
* Without precise smc semantics, or when outside of a TB,
* we can skip to invalidate.
*/
-#ifndef TARGET_HAS_PRECISE_SMC
- pc = 0;
-#endif
- if (!pc) {
+ if (!pc || !cpu->cc->tcg_ops->precise_smc) {
tb_invalidate_phys_page(addr);
return false;
}
@@ -1109,14 +1105,16 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
{
TranslationBlock *tb;
PageForEachNext n;
-#ifdef TARGET_HAS_PRECISE_SMC
bool current_tb_modified = false;
- TranslationBlock *current_tb = retaddr ? tcg_tb_lookup(retaddr) : NULL;
-#endif /* TARGET_HAS_PRECISE_SMC */
+ TranslationBlock *current_tb = NULL;
/* Range may not cross a page. */
tcg_debug_assert(((start ^ last) & TARGET_PAGE_MASK) == 0);
+ if (retaddr && current_cpu->cc->tcg_ops->precise_smc) {
+ current_tb = tcg_tb_lookup(retaddr);
+ }
+
/*
* We remove all the TBs in the range [start, last].
* XXX: see if in some cases it could be faster to invalidate all the code
@@ -1134,8 +1132,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
tb_last = tb_start + (tb_last & ~TARGET_PAGE_MASK);
}
if (!(tb_last < start || tb_start > last)) {
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb == tb &&
+ if (unlikely(current_tb == tb) &&
(tb_cflags(current_tb) & CF_COUNT_MASK) != 1) {
/*
* If we are modifying the current TB, we must stop
@@ -1147,7 +1144,6 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
current_tb_modified = true;
cpu_restore_state_from_tb(current_cpu, current_tb, retaddr);
}
-#endif /* TARGET_HAS_PRECISE_SMC */
tb_phys_invalidate__locked(tb);
}
}
@@ -1157,15 +1153,13 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
tlb_unprotect_code(start);
}
-#ifdef TARGET_HAS_PRECISE_SMC
- if (current_tb_modified) {
+ if (unlikely(current_tb_modified)) {
page_collection_unlock(pages);
/* Force execution of one insn next time. */
current_cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(current_cpu);
mmap_unlock();
cpu_loop_exit_noexc(current_cpu);
}
-#endif
}
/*
@@ -125,6 +125,7 @@ static bool x86_debug_check_breakpoint(CPUState *cs)
#include "accel/tcg/cpu-ops.h"
static const TCGCPUOps x86_tcg_ops = {
+ .precise_smc = true,
/*
* The x86 has a strong memory model with some store-after-load re-ordering
*/
@@ -345,6 +345,7 @@ void cpu_get_tb_cpu_state(CPUS390XState *env, vaddr *pc,
}
static const TCGCPUOps s390_tcg_ops = {
+ .precise_smc = true,
/*
* The z/Architecture has a strong memory model with some
* store-after-load re-ordering.
Instead of having a compile-time TARGET_HAS_PRECISE_SMC definition, have each target set the 'precise_smc' field in the TCGCPUOps structure. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- include/accel/tcg/cpu-ops.h | 6 ++++++ include/exec/poison.h | 1 - target/i386/cpu.h | 4 ---- target/s390x/cpu.h | 2 -- accel/tcg/tb-maint.c | 26 ++++++++++---------------- target/i386/tcg/tcg-cpu.c | 1 + target/s390x/cpu.c | 1 + 7 files changed, 18 insertions(+), 23 deletions(-)