trace: [all] Add "guest_mem_before" event
The event is described in "trace-events". Note that the "MO_AMASK" flag is not traced, since it does not seem to affect the visible semantics of instructions. [s/inline inline/inline/ to fix clang build. --Stefan] Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Reviewed-by: Richard Henderson <rth@twiddle.net> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 146549350711.18437.726780393247474362.stgit@fimbulvetr.bsc.es Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
		
							parent
							
								
									7c2550432a
								
							
						
					
					
						commit
						dcdaadb6ea
					
				| @ -23,6 +23,13 @@ | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #if !defined(SOFTMMU_CODE_ACCESS) | ||||
| #include "trace.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "trace/mem.h" | ||||
| 
 | ||||
| #if DATA_SIZE == 8 | ||||
| #define SUFFIX q | ||||
| #define USUFFIX q | ||||
| @ -80,6 +87,12 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | ||||
|     int mmu_idx; | ||||
|     TCGMemOpIdx oi; | ||||
| 
 | ||||
| #if !defined(SOFTMMU_CODE_ACCESS) | ||||
|     trace_guest_mem_before_exec( | ||||
|         ENV_GET_CPU(env), ptr, | ||||
|         trace_mem_build_info(SHIFT, false, MO_TE, false)); | ||||
| #endif | ||||
| 
 | ||||
|     addr = ptr; | ||||
|     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | ||||
|     mmu_idx = CPU_MMU_INDEX; | ||||
| @ -112,6 +125,12 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | ||||
|     int mmu_idx; | ||||
|     TCGMemOpIdx oi; | ||||
| 
 | ||||
| #if !defined(SOFTMMU_CODE_ACCESS) | ||||
|     trace_guest_mem_before_exec( | ||||
|         ENV_GET_CPU(env), ptr, | ||||
|         trace_mem_build_info(SHIFT, true, MO_TE, false)); | ||||
| #endif | ||||
| 
 | ||||
|     addr = ptr; | ||||
|     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | ||||
|     mmu_idx = CPU_MMU_INDEX; | ||||
| @ -148,6 +167,12 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | ||||
|     int mmu_idx; | ||||
|     TCGMemOpIdx oi; | ||||
| 
 | ||||
| #if !defined(SOFTMMU_CODE_ACCESS) | ||||
|     trace_guest_mem_before_exec( | ||||
|         ENV_GET_CPU(env), ptr, | ||||
|         trace_mem_build_info(SHIFT, false, MO_TE, true)); | ||||
| #endif | ||||
| 
 | ||||
|     addr = ptr; | ||||
|     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); | ||||
|     mmu_idx = CPU_MMU_INDEX; | ||||
|  | ||||
| @ -22,6 +22,13 @@ | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 | ||||
|  */ | ||||
| 
 | ||||
| #if !defined(CODE_ACCESS) | ||||
| #include "trace.h" | ||||
| #endif | ||||
| 
 | ||||
| #include "trace/mem.h" | ||||
| 
 | ||||
| #if DATA_SIZE == 8 | ||||
| #define SUFFIX q | ||||
| #define USUFFIX q | ||||
| @ -53,6 +60,11 @@ | ||||
| static inline RES_TYPE | ||||
| glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) | ||||
| { | ||||
| #if !defined(CODE_ACCESS) | ||||
|     trace_guest_mem_before_exec( | ||||
|         ENV_GET_CPU(env), ptr, | ||||
|         trace_mem_build_info(DATA_SIZE, false, MO_TE, false)); | ||||
| #endif | ||||
|     return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); | ||||
| } | ||||
| 
 | ||||
| @ -68,6 +80,11 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, | ||||
| static inline int | ||||
| glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) | ||||
| { | ||||
| #if !defined(CODE_ACCESS) | ||||
|     trace_guest_mem_before_exec( | ||||
|         ENV_GET_CPU(env), ptr, | ||||
|         trace_mem_build_info(DATA_SIZE, true, MO_TE, false)); | ||||
| #endif | ||||
|     return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); | ||||
| } | ||||
| 
 | ||||
| @ -85,6 +102,11 @@ static inline void | ||||
| glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, | ||||
|                                       RES_TYPE v) | ||||
| { | ||||
| #if !defined(CODE_ACCESS) | ||||
|     trace_guest_mem_before_exec( | ||||
|         ENV_GET_CPU(env), ptr, | ||||
|         trace_mem_build_info(DATA_SIZE, false, MO_TE, true)); | ||||
| #endif | ||||
|     glue(glue(st, SUFFIX), _p)(g2h(ptr), v); | ||||
| } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										10
									
								
								tcg/tcg-op.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								tcg/tcg-op.c
									
									
									
									
									
								
							| @ -28,6 +28,8 @@ | ||||
| #include "exec/exec-all.h" | ||||
| #include "tcg.h" | ||||
| #include "tcg-op.h" | ||||
| #include "trace-tcg.h" | ||||
| #include "trace/mem.h" | ||||
| 
 | ||||
| /* Reduce the number of ifdefs below.  This assumes that all uses of
 | ||||
|    TCGV_HIGH and TCGV_LOW are properly protected by a conditional that | ||||
| @ -1910,12 +1912,16 @@ static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 val, TCGv addr, | ||||
| void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) | ||||
| { | ||||
|     memop = tcg_canonicalize_memop(memop, 0, 0); | ||||
|     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, | ||||
|                                addr, trace_mem_get_info(memop, 0)); | ||||
|     gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx); | ||||
| } | ||||
| 
 | ||||
| void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp memop) | ||||
| { | ||||
|     memop = tcg_canonicalize_memop(memop, 0, 1); | ||||
|     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, | ||||
|                                addr, trace_mem_get_info(memop, 1)); | ||||
|     gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx); | ||||
| } | ||||
| 
 | ||||
| @ -1932,6 +1938,8 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) | ||||
|     } | ||||
| 
 | ||||
|     memop = tcg_canonicalize_memop(memop, 1, 0); | ||||
|     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, | ||||
|                                addr, trace_mem_get_info(memop, 0)); | ||||
|     gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx); | ||||
| } | ||||
| 
 | ||||
| @ -1943,5 +1951,7 @@ void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp memop) | ||||
|     } | ||||
| 
 | ||||
|     memop = tcg_canonicalize_memop(memop, 1, 1); | ||||
|     trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, | ||||
|                                addr, trace_mem_get_info(memop, 1)); | ||||
|     gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx); | ||||
| } | ||||
|  | ||||
							
								
								
									
										21
									
								
								trace-events
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								trace-events
									
									
									
									
									
								
							| @ -2206,3 +2206,24 @@ gicv3_redist_write(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, | ||||
| gicv3_redist_badwrite(uint32_t cpu, uint64_t offset, uint64_t data, unsigned size, bool secure) "GICv3 redistributor %x write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u secure %d: error" | ||||
| gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor %x interrupt %d level changed to %d" | ||||
| gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor %x pending SGI %d" | ||||
| 
 | ||||
| ### Guest events, keep at bottom | ||||
| 
 | ||||
| # @vaddr: Access' virtual address. | ||||
| # @info : Access' information (see below). | ||||
| # | ||||
| # Start virtual memory access (before any potential access violation). | ||||
| # | ||||
| # Does not include memory accesses performed by devices. | ||||
| # | ||||
| # Access information can be parsed as: | ||||
| # | ||||
| # struct mem_info { | ||||
| #     uint8_t size_shift : 2; /* interpreted as "1 << size_shift" bytes */ | ||||
| #     bool    sign_extend: 1; /* sign-extended */ | ||||
| #     uint8_t endianness : 1; /* 0: little, 1: big */ | ||||
| #     bool    store      : 1; /* wheter it's a store operation */ | ||||
| # }; | ||||
| # | ||||
| # Targets: TCG(all) | ||||
| disable vcpu tcg guest_mem_before(TCGv vaddr, uint8_t info) "info=%d", "vaddr=0x%016"PRIx64" info=%d" | ||||
|  | ||||
							
								
								
									
										46
									
								
								trace/mem-internal.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								trace/mem-internal.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| /*
 | ||||
|  * Helper functions for guest memory tracing | ||||
|  * | ||||
|  * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu> | ||||
|  * | ||||
|  * This work is licensed under the terms of the GNU GPL, version 2 or later. | ||||
|  * See the COPYING file in the top-level directory. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef TRACE__MEM_INTERNAL_H | ||||
| #define TRACE__MEM_INTERNAL_H | ||||
| 
 | ||||
| static inline uint8_t trace_mem_get_info(TCGMemOp op, bool store) | ||||
| { | ||||
|     uint8_t res = op; | ||||
|     bool be = (op & MO_BSWAP) == MO_BE; | ||||
| 
 | ||||
|     /* remove untraced fields */ | ||||
|     res &= (1ULL << 4) - 1; | ||||
|     /* make endianness absolute */ | ||||
|     res &= ~MO_BSWAP; | ||||
|     if (be) { | ||||
|         res |= 1ULL << 3; | ||||
|     } | ||||
|     /* add fields */ | ||||
|     if (store) { | ||||
|         res |= 1ULL << 4; | ||||
|     } | ||||
| 
 | ||||
|     return res; | ||||
| } | ||||
| 
 | ||||
| static inline uint8_t trace_mem_build_info( | ||||
|     TCGMemOp size, bool sign_extend, TCGMemOp endianness, bool store) | ||||
| { | ||||
|     uint8_t res = 0; | ||||
|     res |= size; | ||||
|     res |= (sign_extend << 2); | ||||
|     if (endianness == MO_BE) { | ||||
|         res |= (1ULL << 3); | ||||
|     } | ||||
|     res |= (store << 4); | ||||
|     return res; | ||||
| } | ||||
| 
 | ||||
| #endif  /* TRACE__MEM_INTERNAL_H */ | ||||
							
								
								
									
										34
									
								
								trace/mem.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								trace/mem.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| /*
 | ||||
|  * Helper functions for guest memory tracing | ||||
|  * | ||||
|  * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu> | ||||
|  * | ||||
|  * This work is licensed under the terms of the GNU GPL, version 2 or later. | ||||
|  * See the COPYING file in the top-level directory. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef TRACE__MEM_H | ||||
| #define TRACE__MEM_H | ||||
| 
 | ||||
| #include "tcg/tcg.h" | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * trace_mem_get_info: | ||||
|  * | ||||
|  * Return a value for the 'info' argument in guest memory access traces. | ||||
|  */ | ||||
| static uint8_t trace_mem_get_info(TCGMemOp op, bool store); | ||||
| 
 | ||||
| /**
 | ||||
|  * trace_mem_build_info: | ||||
|  * | ||||
|  * Return a value for the 'info' argument in guest memory access traces. | ||||
|  */ | ||||
| static uint8_t trace_mem_build_info(TCGMemOp size, bool sign_extend, | ||||
|                                     TCGMemOp endianness, bool store); | ||||
| 
 | ||||
| 
 | ||||
| #include "trace/mem-internal.h" | ||||
| 
 | ||||
| #endif  /* TRACE__MEM_H */ | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Lluís Vilanova
						Lluís Vilanova