Commit 6db8b538 authored by Alex Bennée's avatar Alex Bennée Committed by Stefan Hajnoczi

trace: add some tcg tracing support

This adds a couple of tcg specific trace-events which are useful for
tracing execution though tcg generated blocks. It's been tested with
lttng user space tracing but is generic enough for all systems. The tcg
events are:

  * translate_block - when a subject block is translated
  * exec_tb - when a translated block is entered
  * exec_tb_exit - when we exit the translated code
  * exec_tb_nocache - special case translations

Of course we can only trace the entrance to the first block of a chain
as each block will jump directly to the next when it can. See the -d
nochain patch to allow more complete tracing at the expense of
performance.
Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 41ef7b00
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
*/ */
#include "config.h" #include "config.h"
#include "cpu.h" #include "cpu.h"
#include "trace.h"
#include "disas/disas.h" #include "disas/disas.h"
#include "tcg.h" #include "tcg.h"
#include "qemu/atomic.h" #include "qemu/atomic.h"
...@@ -168,6 +169,9 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr) ...@@ -168,6 +169,9 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, uint8_t *tb_ptr)
#endif /* DEBUG_DISAS */ #endif /* DEBUG_DISAS */
next_tb = tcg_qemu_tb_exec(env, tb_ptr); next_tb = tcg_qemu_tb_exec(env, tb_ptr);
trace_exec_tb_exit((void *) (next_tb & ~TB_EXIT_MASK),
next_tb & TB_EXIT_MASK);
if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) { if ((next_tb & TB_EXIT_MASK) > TB_EXIT_IDX1) {
/* We didn't start executing this TB (eg because the instruction /* We didn't start executing this TB (eg because the instruction
* counter hit zero); we must restore the guest PC to the address * counter hit zero); we must restore the guest PC to the address
...@@ -208,6 +212,7 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles, ...@@ -208,6 +212,7 @@ static void cpu_exec_nocache(CPUArchState *env, int max_cycles,
max_cycles); max_cycles);
cpu->current_tb = tb; cpu->current_tb = tb;
/* execute the generated code */ /* execute the generated code */
trace_exec_tb_nocache(tb, tb->pc);
cpu_tb_exec(cpu, tb->tc_ptr); cpu_tb_exec(cpu, tb->tc_ptr);
cpu->current_tb = NULL; cpu->current_tb = NULL;
tb_phys_invalidate(tb, -1); tb_phys_invalidate(tb, -1);
...@@ -749,6 +754,7 @@ int cpu_exec(CPUArchState *env) ...@@ -749,6 +754,7 @@ int cpu_exec(CPUArchState *env)
cpu->current_tb = tb; cpu->current_tb = tb;
barrier(); barrier();
if (likely(!cpu->exit_request)) { if (likely(!cpu->exit_request)) {
trace_exec_tb(tb, tb->pc);
tc_ptr = tb->tc_ptr; tc_ptr = tb->tc_ptr;
/* execute the generated code */ /* execute the generated code */
next_tb = cpu_tb_exec(cpu, tc_ptr); next_tb = cpu_tb_exec(cpu, tc_ptr);
......
...@@ -1265,6 +1265,15 @@ kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d ...@@ -1265,6 +1265,15 @@ kvm_failed_spr_get(int str, const char *msg) "Warning: Unable to retrieve SPR %d
kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s" kvm_failed_reg_get(uint64_t id, const char *msg) "Warning: Unable to retrieve ONEREG %" PRIu64 " from KVM: %s"
kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s" kvm_failed_reg_set(uint64_t id, const char *msg) "Warning: Unable to set ONEREG %" PRIu64 " to KVM: %s"
# TCG related tracing (mostly disabled by default)
# cpu-exec.c
disable exec_tb(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
disable exec_tb_nocache(void *tb, uintptr_t pc) "tb:%p pc=0x%"PRIxPTR
disable exec_tb_exit(void *next_tb, unsigned int flags) "tb:%p flags=%x"
# translate-all.c
translate_block(void *tb, uintptr_t pc, uint8_t *tb_code) "tb:%p, pc:0x%"PRIxPTR", tb_code:%p"
# memory.c # memory.c
memory_region_ops_read(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u" memory_region_ops_read(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u"
memory_region_ops_write(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u" memory_region_ops_write(void *mr, uint64_t addr, uint64_t value, unsigned size) "mr %p addr %#"PRIx64" value %#"PRIx64" size %u"
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "qemu-common.h" #include "qemu-common.h"
#define NO_CPU_IO_DEFS #define NO_CPU_IO_DEFS
#include "cpu.h" #include "cpu.h"
#include "trace.h"
#include "disas/disas.h" #include "disas/disas.h"
#include "tcg.h" #include "tcg.h"
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
...@@ -158,6 +159,8 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr ...@@ -158,6 +159,8 @@ int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr
gen_intermediate_code(env, tb); gen_intermediate_code(env, tb);
trace_translate_block(tb, tb->pc, tb->tc_ptr);
/* generate machine code */ /* generate machine code */
gen_code_buf = tb->tc_ptr; gen_code_buf = tb->tc_ptr;
tb->tb_next_offset[0] = 0xffff; tb->tb_next_offset[0] = 0xffff;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment