Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions accel/tcg/cpu-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,24 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
#endif
}

static void retranslation_segv_tb(CPUState *cpu)
{
if (option_mem_test != 1) {
return;
}
CPUX86State *env = (CPUX86State *)cpu->env_ptr;
TranslationBlock *tb = env->segv_tb;
if (!tb || (tb->bool_flags & IS_MT_TB)) {
return;
}
mmap_lock();
tb_phys_invalidate(tb, tb->pc & TARGET_PAGE_MASK);
mem_test_retrans_insert(tb->pc);
tb_gen_code(cpu, tb->pc, 0, tb->flags, tb->cflags & ~CF_INVALID);
env->segv_tb = NULL;
mmap_unlock();
}

/* main execution loop */
int cpu_exec(CPUState *cpu)
{
Expand Down Expand Up @@ -1180,6 +1198,10 @@ int cpu_exec(CPUState *cpu)
}
}

if (ret == EXCP0E_PAGE) {
retranslation_segv_tb(cpu);
}

cpu_exec_exit(cpu);
rcu_read_unlock();

Expand Down
49 changes: 49 additions & 0 deletions accel/tcg/translate-all.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,48 @@ void tu_reset_tb(TranslationBlock *tb);
result; \
}) /* EXPAND_TO_64BIT */

static __thread GTree *mem_test_retrans_tree;
static gint pc_cmp(gconstpointer ap, gconstpointer bp)
{
const target_ulong *a = ap;
const target_ulong *b = bp;
if (*a > *b) {
return 1;
} else if (*a < *b) {
return -1;
}
return 0;
}

static inline void mem_test_retrans_tree_init(void)
{
if (mem_test_retrans_tree) return;
mem_test_retrans_tree = g_tree_new(pc_cmp);
}

static inline void *mem_test_retrans_lookup(uint64_t pc)
{
if ((option_mem_test != 1)|| !mem_test_retrans_tree)
return NULL;
pc &= TARGET_PAGE_MASK;
return g_tree_lookup(mem_test_retrans_tree, &pc);
}

bool mem_test_retrans_insert(target_ulong pc)
{
if (option_mem_test != 1)
return false;
pc &= TARGET_PAGE_MASK;
mem_test_retrans_tree_init();
target_ulong *key = malloc(sizeof(target_ulong));
*key = pc;
if (!mem_test_retrans_lookup(pc)) {
g_tree_insert(mem_test_retrans_tree, key, key);
return true;
}
return false;
}

#ifdef CONFIG_LATX_SMC_OPT

/*
Expand Down Expand Up @@ -465,6 +507,9 @@ static int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb,
return -1;

found:
if ((option_mem_test == 1) && !(tb->bool_flags & IS_MT_TB)) {
env->segv_tb = tb;
}
if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) {
assert(icount_enabled());
/* Reset the cycle counter to the start of the block
Expand Down Expand Up @@ -2191,6 +2236,10 @@ TranslationBlock *tb_gen_code(CPUState *cpu,
#endif
#endif

if (mem_test_retrans_lookup(pc)) {
tb->bool_flags |= IS_MT_TB;
}

#ifndef CONFIG_LATX
#ifdef CONFIG_PROFILER
/* includes aborted translations because of exceptions */
Expand Down
7 changes: 5 additions & 2 deletions include/exec/exec-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ void restore_state_to_opc(CPUArchState *env, TranslationBlock *tb,
target_ulong *data);
int encode_search(TranslationBlock *tb, uint8_t *block);

bool mem_test_retrans_insert(target_ulong pc);

/**
* cpu_restore_state:
* @cpu: the vCPU state is to be restore to
Expand Down Expand Up @@ -647,8 +649,9 @@ struct TranslationBlock {
#define SIGNAL_RELINK0 0x200
#define SIGNAL_UNLINK1 0x400
#define SIGNAL_RELINK1 0x800
#define IS_CODE64 0x1000
#define IS_TU_SPLIT 0x2000
#define IS_CODE64 0x1000
#define IS_TU_SPLIT 0x2000
#define IS_MT_TB 0x4000
uint16_t bool_flags;
uint8_t eflag_use;
#ifdef CONFIG_LATX_INSTS_PATTERN
Expand Down
1 change: 1 addition & 0 deletions target/i386/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1662,6 +1662,7 @@ typedef struct CPUX86State {
ucontext_t *puc;
uintptr_t insn_save[2];
#endif
TranslationBlock *segv_tb;
} CPUX86State;

struct kvm_msrs;
Expand Down
15 changes: 11 additions & 4 deletions target/i386/latx/translator/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -3898,14 +3898,21 @@ static inline void helper_restore_reg(IR2_OPND opnd)

void gen_test_page_flag(IR2_OPND mem_opnd, int mem_imm, uint32_t flag)
{
if (!option_mem_test) {
if (!option_mem_test || !(flag & PAGE_WRITE)) {
return;
}
TranslationBlock *tb __attribute__((unused)) = NULL;
if (option_aot) {
tb = (TranslationBlock *)lsenv->tr_data->curr_tb;

TranslationBlock *tb = (TranslationBlock *)lsenv->tr_data->curr_tb;
CPUX86State *cpu = (CPUX86State *)lsenv->cpu_state;
if ((option_mem_test == 1) &&
(!cpu->segv_tb || (cpu->segv_tb->pc != tb->pc))) {
if ((tb->pc & ~TARGET_PAGE_MASK) != 0x259) {
return;
}
}

tb->bool_flags |= IS_MT_TB;

IR2_OPND label_exit = ra_alloc_label();
IR2_OPND label0 = ra_alloc_label();
IR2_OPND label1 = ra_alloc_label();
Expand Down