[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 12/12] trace: [all] Add "guest_vmem" event
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH 12/12] trace: [all] Add "guest_vmem" event |
Date: |
Fri, 31 Jan 2014 17:10:08 +0100 |
User-agent: |
StGit/0.16 |
Signed-off-by: Lluís Vilanova <address@hidden>
---
include/exec/cpu-all.h | 58 +++++++++++++++++++++--------------------
include/exec/exec-all.h | 3 ++
include/exec/softmmu_header.h | 17 ++++++++++++
tcg/tcg-op.h | 8 ++++++
tcg/tcg.c | 1 +
trace-events | 15 +++++++++++
trace/tcg-op-internal.h | 55 +++++++++++++++++++++++++++++++++++++++
7 files changed, 129 insertions(+), 28 deletions(-)
create mode 100644 trace/tcg-op-internal.h
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index 4cb4b4a..4ecb486 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -250,21 +250,23 @@ extern unsigned long reserved_va;
#if defined(CONFIG_USER_ONLY)
+#include "trace.h"
+
/* if user mode, no other memory access functions */
-#define ldub(p) ldub_raw(p)
-#define ldsb(p) ldsb_raw(p)
-#define lduw(p) lduw_raw(p)
-#define ldsw(p) ldsw_raw(p)
-#define ldl(p) ldl_raw(p)
-#define ldq(p) ldq_raw(p)
-#define ldfl(p) ldfl_raw(p)
-#define ldfq(p) ldfq_raw(p)
-#define stb(p, v) stb_raw(p, v)
-#define stw(p, v) stw_raw(p, v)
-#define stl(p, v) stl_raw(p, v)
-#define stq(p, v) stq_raw(p, v)
-#define stfl(p, v) stfl_raw(p, v)
-#define stfq(p, v) stfq_raw(p, v)
+#define ldub(p) ({ trace_guest_vmem(p, 1, 0); ldub_raw(p); })
+#define ldsb(p) ({ trace_guest_vmem(p, 1, 0); ldsb_raw(p); })
+#define lduw(p) ({ trace_guest_vmem(p, 2, 0); lduw_raw(p); })
+#define ldsw(p) ({ trace_guest_vmem(p, 2, 0); ldsw_raw(p); })
+#define ldl(p) ({ trace_guest_vmem(p, 4, 0); ldl_raw(p); })
+#define ldq(p) ({ trace_guest_vmem(p, 8, 0); ldq_raw(p); })
+#define ldfl(p) ({ trace_guest_vmem(p, 4, 0); ldfl_raw(p); })
+#define ldfq(p) ({ trace_guest_vmem(p, 8, 0); ldfq_raw(p); })
+#define stb(p, v) ({ trace_guest_vmem(p, 1, 1); stb_raw(p, v); })
+#define stw(p, v) ({ trace_guest_vmem(p, 2, 1); stw_raw(p, v); })
+#define stl(p, v) ({ trace_guest_vmem(p, 4, 1); stl_raw(p, v); })
+#define stq(p, v) ({ trace_guest_vmem(p, 8, 1); stq_raw(p, v); })
+#define stfl(p, v) ({ trace_guest_vmem(p, 4, 1); stfl_raw(p, v); })
+#define stfq(p, v) ({ trace_guest_vmem(p, 8, 1); stfq_raw(p, v); })
#define cpu_ldub_code(env1, p) ldub_raw(p)
#define cpu_ldsb_code(env1, p) ldsb_raw(p)
@@ -295,20 +297,20 @@ extern unsigned long reserved_va;
#define cpu_stl_kernel(env, addr, data) stl_raw(addr, data)
#define cpu_stq_kernel(env, addr, data) stq_raw(addr, data)
-#define ldub_kernel(p) ldub_raw(p)
-#define ldsb_kernel(p) ldsb_raw(p)
-#define lduw_kernel(p) lduw_raw(p)
-#define ldsw_kernel(p) ldsw_raw(p)
-#define ldl_kernel(p) ldl_raw(p)
-#define ldq_kernel(p) ldq_raw(p)
-#define ldfl_kernel(p) ldfl_raw(p)
-#define ldfq_kernel(p) ldfq_raw(p)
-#define stb_kernel(p, v) stb_raw(p, v)
-#define stw_kernel(p, v) stw_raw(p, v)
-#define stl_kernel(p, v) stl_raw(p, v)
-#define stq_kernel(p, v) stq_raw(p, v)
-#define stfl_kernel(p, v) stfl_raw(p, v)
-#define stfq_kernel(p, vt) stfq_raw(p, v)
+#define ldub_kernel(p) ({ trace_guest_vmem(p, 1, 0); ldub_raw(p); })
+#define ldsb_kernel(p) ({ trace_guest_vmem(p, 1, 0); ldsb_raw(p); })
+#define lduw_kernel(p) ({ trace_guest_vmem(p, 2, 0); lduw_raw(p); })
+#define ldsw_kernel(p) ({ trace_guest_vmem(p, 2, 0); ldsw_raw(p); })
+#define ldl_kernel(p) ({ trace_guest_vmem(p, 4, 0); ldl_raw(p); })
+#define ldq_kernel(p) ({ trace_guest_vmem(p, 8, 0); ldq_raw(p); })
+#define ldfl_kernel(p) ({ trace_guest_vmem(p, 4, 0); ldfl_raw(p); })
+#define ldfq_kernel(p) ({ trace_guest_vmem(p, 8, 0); ldfq_raw(p); })
+#define stb_kernel(p, v) ({ trace_guest_vmem(p, 1, 1); stb_raw(p, v); })
+#define stw_kernel(p, v) ({ trace_guest_vmem(p, 2, 1); stw_raw(p, v); })
+#define stl_kernel(p, v) ({ trace_guest_vmem(p, 4, 1); stl_raw(p, v); })
+#define stq_kernel(p, v) ({ trace_guest_vmem(p, 8, 1); stq_raw(p, v); })
+#define stfl_kernel(p, v) ({ trace_guest_vmem(p, 4, 1); stfl_raw(p, v); })
+#define stfq_kernel(p, vt) ({ trace_guest_vmem(p, 8, 1); stfq_raw(p, v); })
#define cpu_ldub_data(env, addr) ldub_raw(addr)
#define cpu_lduw_data(env, addr) lduw_raw(addr)
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index ea90b64..f30cc4e 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -339,6 +339,8 @@ uint32_t helper_ldl_cmmu(CPUArchState *env, target_ulong
addr, int mmu_idx);
uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong addr, int mmu_idx);
#define ACCESS_TYPE (NB_MMU_MODES + 1)
+/* do not trace '*_code' accesses during instruction disassembly */
+#define TRACE_TCG_CODE_ACCESSOR 1
#define MEMSUFFIX _code
#define DATA_SIZE 1
@@ -354,6 +356,7 @@ uint64_t helper_ldq_cmmu(CPUArchState *env, target_ulong
addr, int mmu_idx);
#include "exec/softmmu_header.h"
#undef ACCESS_TYPE
+#undef TRACE_TCG_CODE_ACCESSOR
#undef MEMSUFFIX
#endif
diff --git a/include/exec/softmmu_header.h b/include/exec/softmmu_header.h
index d8d9c81..ccd9cb1 100644
--- a/include/exec/softmmu_header.h
+++ b/include/exec/softmmu_header.h
@@ -25,6 +25,11 @@
* 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(TRACE_TCG_CODE_ACCESSOR)
+#include "trace.h"
+#endif
+
#if DATA_SIZE == 8
#define SUFFIX q
#define USUFFIX q
@@ -88,6 +93,10 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env,
target_ulong ptr)
target_ulong addr;
int mmu_idx;
+#if !defined(TRACE_TCG_CODE_ACCESSOR)
+ trace_guest_vmem(ptr, DATA_SIZE, 0);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -109,6 +118,10 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env,
target_ulong ptr)
target_ulong addr;
int mmu_idx;
+#if !defined(TRACE_TCG_CODE_ACCESSOR)
+ trace_guest_vmem(ptr, DATA_SIZE, 0);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
@@ -136,6 +149,10 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env,
target_ulong ptr,
target_ulong addr;
int mmu_idx;
+#if !defined(TRACE_TCG_CODE_ACCESSOR)
+ trace_guest_vmem(ptr, DATA_SIZE, 1);
+#endif
+
addr = ptr;
page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
mmu_idx = CPU_MMU_INDEX;
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index 7eabf22..0ce2f81 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -2888,3 +2888,11 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv
addr, int mem_index)
# define tcg_gen_ext_i32_ptr(R, A) \
tcg_gen_ext_i32_i64(TCGV_PTR_TO_NAT(R), (A))
#endif /* TCG_TARGET_REG_BITS == 32 */
+
+#if !defined(TCG_OP_NOTRACE_GUEST_MEM)
+/* To avoid a circular dependency with helper.h, overload tcg_gen_qemu_*
+ * routines with preprocessor macros to insert TCG virtual memory access
+ * tracing.
+ */
+#include "trace/tcg-op-internal.h"
+#endif
diff --git a/tcg/tcg.c b/tcg/tcg.c
index acd02b9..7847277 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -47,6 +47,7 @@
#define NO_CPU_IO_DEFS
#include "cpu.h"
+#define TCG_OP_NOTRACE_GUEST_MEM
#include "tcg-op.h"
#if UINTPTR_MAX == UINT32_MAX
diff --git a/trace-events b/trace-events
index 1b668d1..3f5a55c 100644
--- a/trace-events
+++ b/trace-events
@@ -1186,3 +1186,18 @@ xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen
PV Device MMIO space (ad
# hw/pci/pci_host.c
pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs,
unsigned val) "%s %02u:%u @0x%x -> 0x%x"
pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs,
unsigned val) "%s %02u:%u @0x%x <- 0x%x"
+
+
+
+## Guest events, keep at bottom
+
+# @vaddr: Access' virtual address.
+# @size : Access' size (bytes).
+# @write: Whether the access is a write.
+#
+# Start virtual memory access (before any potential access violation).
+#
+# This event can be raised at execution time when running in 'user' mode.
+#
+# Targets: TCG(all)
+disable tcg guest_vmem(TCGv vaddr, uint8_t size, uint8_t write)
"vaddr=0x%016"PRIx64" size=%d write=%d"
diff --git a/trace/tcg-op-internal.h b/trace/tcg-op-internal.h
new file mode 100644
index 0000000..fea46fa
--- /dev/null
+++ b/trace/tcg-op-internal.h
@@ -0,0 +1,55 @@
+/* -*- mode: c -*-
+ * Copyright (c) 2012-2014 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/**
+ * @file Capture TCG code generation for virtual memory accesses.
+ *
+ * Assumes that no other lower-level call will be performed by target
+ * architecture disassembly code on TCG instructions for accessing memory.
+ *
+ * Capturing calls to higher-level functions like @tcg_gen_qemu_ld8u would
allow
+ * using constants for the access size (instead of computing it from the memory
+ * operand argument), but is harder to maintain.
+ */
+
+#ifndef TRACE__TCG_OP_INTERNAL_H
+#define TRACE__TCG_OP_INTERNAL_H
+
+static inline uint8_t _tcg_memop_size(TCGMemOp op)
+{
+ return 1 << (op & MO_SIZE);
+}
+
+#define tcg_gen_qemu_ld_i32(val, addr, idx, memop) \
+ do { \
+ uint8_t _memop_size = _tcg_memop_size(memop); \
+ trace_guest_vmem_tcg(addr, _memop_size, 0); \
+ tcg_gen_qemu_ld_i32(val, addr, idx, memop); \
+ } while (0)
+
+#define tcg_gen_qemu_st_i32(val, addr, idx, memop) \
+ do { \
+ uint8_t _memop_size = _tcg_memop_size(memop); \
+ trace_guest_vmem_tcg(addr, _memop_size, 1); \
+ tcg_gen_qemu_st_i32(val, addr, idx, memop); \
+ } while (0)
+
+#define tcg_gen_qemu_ld_i64(val, addr, idx, memop) \
+ do { \
+ uint8_t _memop_size = _tcg_memop_size(memop); \
+ trace_guest_vmem_tcg(addr, _memop_size, 0); \
+ tcg_gen_qemu_ld_i64(val, addr, idx, memop); \
+ } while (0)
+
+#define tcg_gen_qemu_st_i64(val, addr, idx, memop) \
+ do { \
+ uint8_t _memop_size = _tcg_memop_size(memop); \
+ trace_guest_vmem_tcg(addr, _memop_size, 1); \
+ tcg_gen_qemu_st_i64(val, addr, idx, memop); \
+ } while (0)
+
+#endif /* TRACE__TCG_OP_INTERNAL_H */
- [Qemu-devel] [PATCH 00/12] trace: [tcg] Allow tracing guest events in TCG-generated code, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 01/12] trace: [tcg] Add documentation, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 02/12] trace: [tracetool, tcg] Allow TCG types in trace event declarations, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 03/12] trace: [tracetool] Add method 'Event.api' to get the name of public routines, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 04/12] trace: [tracetool, tcg] Provide TCG-related type transformation rules, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 05/12] trace: [tracetool] Allow argument types to be transformed, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 06/12] trace: [tcg] Declare TCG tracing helper routines, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 07/12] trace: [tcg] Define TCG tracing helper routines, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 09/12] trace: [tcg] Generate TCG tracing routines, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 10/12] trace: [trivial] Include event definitions in "trace.h", Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 12/12] trace: [all] Add "guest_vmem" event,
Lluís Vilanova <=
- [Qemu-devel] [PATCH 11/12] trace: [tcg] Include TCG-tracing header on all targets, Lluís Vilanova, 2014/01/31
- [Qemu-devel] [PATCH 08/12] trace: [tcg] Include TCG-tracing helpers on all helper.h, Lluís Vilanova, 2014/01/31