Skip to content

Commit a57cc32

Browse files
committed
LATX, refactor: isolate TCG mode by refactoring tb_find, tb_gen_code, cpu_tb_exec
Signed-off-by: Zhaoyang Xie <xie_zyang@163.com>
1 parent e784c57 commit a57cc32

2 files changed

Lines changed: 367 additions & 130 deletions

File tree

accel/tcg/cpu-exec.c

Lines changed: 119 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ static void init_delay_params(SyncClocks *sc, const CPUState *cpu)
182182
* TCG is not considered a security-sensitive part of QEMU so this does not
183183
* affect the impact of CFI in environment with high security requirements
184184
*/
185+
#ifdef CONFIG_LATX
185186
static inline TranslationBlock * QEMU_DISABLE_CFI
186187
cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
187188
{
@@ -263,7 +264,6 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
263264
#ifdef CONFIG_LATX_DEBUG
264265
latx_before_exec_trace_tb(env, itb);
265266
#endif
266-
#ifdef CONFIG_LATX
267267

268268
env->fpu_clobber = false;
269269
ret = tcg_qemu_tb_exec(env, tb_ptr);
@@ -304,9 +304,6 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
304304
link_indirect_jmp(env);
305305
}
306306

307-
#else
308-
ret = tcg_qemu_tb_exec(env, tb_ptr);
309-
#endif
310307
#ifdef CONFIG_LATX_DEBUG
311308
latx_after_exec_trace_tb(env, itb);
312309
#endif
@@ -366,6 +363,80 @@ cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
366363

367364
return last_tb;
368365
}
366+
#else
367+
static inline TranslationBlock * QEMU_DISABLE_CFI
368+
cpu_tb_exec(CPUState *cpu, TranslationBlock *itb, int *tb_exit)
369+
{
370+
if (!itb) {
371+
fprintf(stderr, "[LATX] ERROR!\n");
372+
}
373+
CPUArchState *env = cpu->env_ptr;
374+
uintptr_t ret;
375+
TranslationBlock *last_tb;
376+
const void *tb_ptr = itb->tc.ptr;
377+
if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
378+
qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
379+
"pid(%d) - tid(%" PRIuPTR ") Trace cpu%d: %p [ "
380+
TARGET_FMT_lx "/%#x] %s\n",
381+
getpid(), (uintptr_t)pthread_self(), cpu->cpu_index, itb->tc.ptr,
382+
itb->pc, itb->flags, lookup_symbol(itb->pc));
383+
}
384+
385+
#if defined(DEBUG_DISAS)
386+
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
387+
&& qemu_log_in_addr_range(itb->pc)) {
388+
FILE *logfile = qemu_log_lock();
389+
int flags = 0;
390+
if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
391+
flags |= CPU_DUMP_FPU;
392+
}
393+
#if defined(TARGET_I386)
394+
flags |= CPU_DUMP_CCOP;
395+
#endif
396+
log_cpu_state(cpu, flags);
397+
qemu_log_unlock(logfile);
398+
}
399+
#endif /* DEBUG_DISAS */
400+
401+
qemu_thread_jit_execute();
402+
ret = tcg_qemu_tb_exec(env, tb_ptr);
403+
cpu->can_do_io = 1;
404+
/*
405+
* TODO: Delay swapping back to the read-write region of the TB
406+
* until we actually need to modify the TB. The read-only copy,
407+
* coming from the rx region, shares the same host TLB entry as
408+
* the code that executed the exit_tb opcode that arrived here.
409+
* If we insist on touching both the RX and the RW pages, we
410+
* double the host TLB pressure.
411+
*/
412+
last_tb = tcg_splitwx_to_rw((void *)(ret & ~TB_EXIT_MASK));
413+
*tb_exit = ret & TB_EXIT_MASK;
414+
415+
trace_exec_tb_exit(last_tb, *tb_exit);
416+
417+
if (*tb_exit > TB_EXIT_IDX1) {
418+
/* We didn't start executing this TB (eg because the instruction
419+
* counter hit zero); we must restore the guest PC to the address
420+
* of the start of the TB.
421+
*/
422+
CPUClass *cc = CPU_GET_CLASS(cpu);
423+
qemu_log_mask_and_addr(CPU_LOG_EXEC, last_tb->pc,
424+
"Stopped execution of TB chain before %p ["
425+
TARGET_FMT_lx "] %s\n",
426+
last_tb->tc.ptr, last_tb->pc,
427+
lookup_symbol(last_tb->pc));
428+
if (cc->tcg_ops->synchronize_from_tb) {
429+
cc->tcg_ops->synchronize_from_tb(cpu, last_tb);
430+
} else {
431+
assert(cc->set_pc);
432+
cc->set_pc(cpu, last_tb->pc);
433+
}
434+
}
435+
436+
437+
return last_tb;
438+
}
439+
#endif
369440

370441

371442
static void cpu_exec_enter(CPUState *cpu)
@@ -718,6 +789,7 @@ static inline void tb_add_jump(TranslationBlock *tb, int n,
718789
#include "tu.h"
719790
#endif
720791

792+
#ifdef CONFIG_LATX
721793
static inline TranslationBlock *tb_find(CPUState *cpu,
722794
TranslationBlock *last_tb,
723795
int tb_exit, uint32_t cflags)
@@ -786,6 +858,49 @@ static inline TranslationBlock *tb_find(CPUState *cpu,
786858
}
787859
return tb;
788860
}
861+
#else
862+
static inline TranslationBlock *tb_find(CPUState *cpu,
863+
TranslationBlock *last_tb,
864+
int tb_exit, uint32_t cflags)
865+
{
866+
CPUArchState *env = (CPUArchState *)cpu->env_ptr;
867+
TranslationBlock *tb;
868+
target_ulong cs_base, pc;
869+
uint32_t flags;
870+
871+
cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
872+
873+
tb = tb_lookup(cpu, pc, cs_base, flags, cflags);
874+
if (tb == NULL) {
875+
mmap_lock();
876+
877+
tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
878+
879+
if (!tb) {
880+
mmap_unlock();
881+
return NULL;
882+
}
883+
/* We add the TB in the virtual pc hash table for the fast lookup */
884+
int hash_value = tb_jmp_cache_hash_func(pc);
885+
qatomic_set(&cpu->tb_jmp_cache[hash_value], tb);
886+
mmap_unlock();
887+
}
888+
#ifndef CONFIG_USER_ONLY
889+
/* We don't take care of direct jumps when address mapping changes in
890+
* system emulation. So it's not safe to make a direct jump to a TB
891+
* spanning two pages because the mapping for the second page can change.
892+
*/
893+
if (tb->page_addr[1] != -1) {
894+
last_tb = NULL;
895+
}
896+
#endif
897+
/* See if we can patch the calling TB. */
898+
if (last_tb) {
899+
tb_add_jump(last_tb, tb_exit, tb);
900+
}
901+
return tb;
902+
}
903+
#endif
789904

790905
static inline bool cpu_handle_halt(CPUState *cpu)
791906
{

0 commit comments

Comments
 (0)