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: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
							parent
							
								
									41ef7b00ab
								
							
						
					
					
						commit
						6db8b53866
					
				@ -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)
 | 
				
			|||||||
#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,
 | 
				
			|||||||
                     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)
 | 
				
			|||||||
                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
 | 
				
			|||||||
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 @@
 | 
				
			|||||||
#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
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    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;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user