Need to use "TCG inlining" to avoid showing a trace entry for each exit point (up to two per BBL).
Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- accel/tcg/translator.c | 54 +++++++++++++++++++++++++++++++++++++++++++++ include/exec/translator.h | 22 ++++++++++++++++++ tcg/tcg-op.c | 2 ++ tcg/tcg-op.h | 1 + tcg/tcg.h | 5 ++++ trace-events | 11 +++++++++ 6 files changed, 94 insertions(+), 1 deletion(-) diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c index 6598931171..d66d601c89 100644 --- a/accel/tcg/translator.c +++ b/accel/tcg/translator.c @@ -35,6 +35,7 @@ void translator_loop_temp_check(DisasContextBase *db) void translator_loop(const TranslatorOps *ops, DisasContextBase *db, CPUState *cpu, TranslationBlock *tb) { + target_ulong pc_bbl; int max_insns; /* Initialize DisasContext */ @@ -63,6 +64,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, /* Reset the temp count so that we can identify leaks */ tcg_clear_temp_count(); + /* Tracking gen_goto_tb / gen_exit_tb */ + pc_bbl = db->pc_first; + tcg_ctx.disas.seen_goto_tb = false; + tcg_ctx.disas.in_guest_code = false; + /* Start translating. */ gen_tb_start(db->tb); ops->tb_start(db, cpu); @@ -74,6 +80,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, int insn_size_opcode_idx; db->num_insns++; + if (db->num_insns == 1) { + tcg_ctx.disas.in_guest_code = true; + tcg_ctx.disas.inline_label = NULL; + } + ops->insn_start(db, cpu); tcg_debug_assert(db->is_jmp == DISAS_NEXT); /* no early exit */ @@ -144,6 +155,22 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, } } + /* Tracing after */ + if (TRACE_GUEST_BBL_AFTER_ENABLED) { + tcg_ctx.disas.in_guest_code = false; + if (tcg_ctx.disas.inline_label == NULL) { + tcg_ctx.disas.inline_label = gen_new_inline_label(); + } + + gen_set_inline_region_begin(tcg_ctx.disas.inline_label); + + if (TRACE_GUEST_BBL_AFTER_ENABLED) { + trace_guest_bbl_after_tcg(cpu, tcg_ctx.tcg_env, pc_bbl); + } + + gen_set_inline_region_end(tcg_ctx.disas.inline_label); + } + /* Emit code to exit the TB, as indicated by db->is_jmp. */ ops->tb_stop(db, cpu); gen_tb_end(db->tb, db->num_insns); @@ -163,3 +190,30 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, } #endif } + + +void translator__gen_goto_tb(TCGContext *ctx) +{ + if (ctx->disas.in_guest_code && + (TRACE_GUEST_BBL_AFTER_ENABLED)) { + if (ctx->disas.inline_label == NULL) { + ctx->disas.inline_label = gen_new_inline_label(); + } + gen_set_inline_point(ctx->disas.inline_label); + /* disable next exit_tb */ + ctx->disas.seen_goto_tb = true; + } +} + +void translator__gen_exit_tb(TCGContext *ctx) +{ + if (ctx->disas.in_guest_code && !ctx->disas.seen_goto_tb && + (TRACE_GUEST_BBL_AFTER_ENABLED)) { + if (ctx->disas.inline_label == NULL) { + ctx->disas.inline_label = gen_new_inline_label(); + } + gen_set_inline_point(ctx->disas.inline_label); + /* enable next exit_tb */ + ctx->disas.seen_goto_tb = false; + } +} diff --git a/include/exec/translator.h b/include/exec/translator.h index e2dc2a04ae..83aeea59a1 100644 --- a/include/exec/translator.h +++ b/include/exec/translator.h @@ -20,7 +20,6 @@ #include "exec/exec-all.h" -#include "tcg/tcg.h" /** @@ -71,6 +70,21 @@ typedef struct DisasContextBase { bool singlestep_enabled; } DisasContextBase; +/** + * TCGContextDisas: + * @seen_goto_tb: Whether we've seen a call to tcg_gen_goto_tb(). + * @in_guest_code: Whether we're generating guest code (or supporting + * boilerplate otherwise). + * @inline_label: Inline label. + * + * Extensions to #TCGContext specific to the generic translation framework. + */ +typedef struct TCGContextDisas { + bool seen_goto_tb; + bool in_guest_code; + TCGInlineLabel *inline_label; +} TCGContextDisas; + /** * TranslatorOps: * @init_disas_context: @@ -117,6 +131,8 @@ typedef struct TranslatorOps { void (*disas_log)(const DisasContextBase *db, CPUState *cpu); } TranslatorOps; +#include "tcg/tcg.h" + /** * translator_loop: * @ops: Target-specific operations. @@ -141,4 +157,8 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, void translator_loop_temp_check(DisasContextBase *db); +/* Internal functions to hook tracing into */ +void translator__gen_goto_tb(TCGContext *ctx); +void translator__gen_exit_tb(TCGContext *ctx); + #endif /* EXEC__TRANSLATOR_H */ diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 688d91755b..575b4faf84 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -2578,6 +2578,8 @@ void tcg_gen_extr32_i64(TCGv_i64 lo, TCGv_i64 hi, TCGv_i64 arg) void tcg_gen_goto_tb(unsigned idx) { + translator__gen_goto_tb(&tcg_ctx); + /* We only support two chained exits. */ tcg_debug_assert(idx <= 1); #ifdef CONFIG_DEBUG_TCG diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index da3784f8f2..9ab1497bc1 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -817,6 +817,7 @@ static inline void tcg_gen_insn_start(target_ulong pc, target_ulong a1, static inline void tcg_gen_exit_tb(uintptr_t val) { + translator__gen_exit_tb(&tcg_ctx); tcg_gen_op1i(INDEX_op_exit_tb, val); } diff --git a/tcg/tcg.h b/tcg/tcg.h index c6e3c6e68d..6483ed75d6 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -655,6 +655,8 @@ QEMU_BUILD_BUG_ON(OPPARAM_BUF_SIZE > (1 << 14)); /* Make sure that we don't overflow 64 bits without noticing. */ QEMU_BUILD_BUG_ON(sizeof(TCGOp) > 8); +#include "exec/translator.h" + struct TCGContext { uint8_t *pool_cur, *pool_end; TCGPool *pool_first, *pool_current, *pool_first_large; @@ -730,6 +732,9 @@ struct TCGContext { CPUState *cpu; /* *_trans */ TCGv_env tcg_env; /* *_exec */ + /* Used by generic gen_intermediate_code */ + TCGContextDisas disas; + /* These structures are private to tcg-target.inc.c. */ #ifdef TCG_TARGET_NEED_LDST_LABELS struct TCGLabelQemuLdst *ldst_labels; diff --git a/trace-events b/trace-events index 4e61697297..ce54bb4993 100644 --- a/trace-events +++ b/trace-events @@ -99,6 +99,17 @@ vcpu guest_cpu_reset(void) # Targets: TCG(all) vcpu tcg guest_bbl_before(uint64_t vaddr) "vaddr=0x%016"PRIx64, "vaddr=0x%016"PRIx64 +# @vaddr: BBL's starting virtual address +# +# Mark end of BBL execution (after the BBL-exiting instruction). +# +# NOTE: This event might not be raised if the BBL ends unexpectedly (e.g., +# triggers an exception). +# +# Mode: user, softmmu +# Targets: TCG(all) +vcpu tcg guest_bbl_after(uint64_t vaddr) "vaddr=0x%016"PRIx64, "vaddr=0x%016"PRIx64 + # @vaddr: Instruction's virtual address # # Mark start of instruction execution (before anything gets really executed).