From patchwork Fri Dec 9 20:16:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Llu=C3=ADs_Vilanova?= X-Patchwork-Id: 130462 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8C7B7B6F6F for ; Sat, 10 Dec 2011 07:16:41 +1100 (EST) Received: from localhost ([::1]:52191 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RZ6s1-0001ml-7E for incoming@patchwork.ozlabs.org; Fri, 09 Dec 2011 15:16:37 -0500 Received: from eggs.gnu.org ([140.186.70.92]:49487) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RZ6rt-0001eU-PN for qemu-devel@nongnu.org; Fri, 09 Dec 2011 15:16:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RZ6rs-0003P2-3E for qemu-devel@nongnu.org; Fri, 09 Dec 2011 15:16:29 -0500 Received: from gw.ac.upc.edu ([147.83.30.3]:40207) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RZ6rr-0003Om-Iq for qemu-devel@nongnu.org; Fri, 09 Dec 2011 15:16:28 -0500 Received: from localhost (unknown [84.88.53.92]) by gw.ac.upc.edu (Postfix) with ESMTP id 6E42C6B01CA for ; Fri, 9 Dec 2011 21:16:26 +0100 (CET) To: qemu-devel@nongnu.org From: =?utf-8?b?TGx1w61z?= Vilanova Date: Fri, 09 Dec 2011 21:16:19 +0100 Message-ID: <20111209201619.11487.32134.stgit@ginnungagap.bsc.es> In-Reply-To: <20111209201430.11487.82078.stgit@ginnungagap.bsc.es> References: <20111209201430.11487.82078.stgit@ginnungagap.bsc.es> User-Agent: StGit/0.15 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 147.83.30.3 Subject: [Qemu-devel] [PATCH 7/7] trace: [all] Add "vmem" TCG tracing event X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Lluís Vilanova --- cpu-all.h | 58 +++++++++++++++++++------------------ exec-all.h | 3 ++ softmmu_header.h | 15 ++++++++++ tcg/tcg-op.h | 6 ++++ trace-events | 9 ++++++ trace/tcg-op-internal.h | 74 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 137 insertions(+), 28 deletions(-) create mode 100644 trace/tcg-op-internal.h diff --git a/cpu-all.h b/cpu-all.h index 5f47ab8..5a4c2f6 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -243,21 +243,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_vmem(p, 1, 0); ldub_raw(p); }) +#define ldsb(p) ({ trace_vmem(p, 1, 0); ldsb_raw(p); }) +#define lduw(p) ({ trace_vmem(p, 2, 0); lduw_raw(p); }) +#define ldsw(p) ({ trace_vmem(p, 2, 0); ldsw_raw(p); }) +#define ldl(p) ({ trace_vmem(p, 4, 0); ldl_raw(p); }) +#define ldq(p) ({ trace_vmem(p, 8, 0); ldq_raw(p); }) +#define ldfl(p) ({ trace_vmem(p, 4, 0); ldfl_raw(p); }) +#define ldfq(p) ({ trace_vmem(p, 8, 0); ldfq_raw(p); }) +#define stb(p, v) ({ trace_vmem(p, 1, 1); stb_raw(p, v); }) +#define stw(p, v) ({ trace_vmem(p, 2, 1); stw_raw(p, v); }) +#define stl(p, v) ({ trace_vmem(p, 4, 1); stl_raw(p, v); }) +#define stq(p, v) ({ trace_vmem(p, 8, 1); stq_raw(p, v); }) +#define stfl(p, v) ({ trace_vmem(p, 4, 1); stfl_raw(p, v); }) +#define stfq(p, v) ({ trace_vmem(p, 8, 1); stfq_raw(p, v); }) #define ldub_code(p) ldub_raw(p) #define ldsb_code(p) ldsb_raw(p) @@ -266,20 +268,20 @@ extern unsigned long reserved_va; #define ldl_code(p) ldl_raw(p) #define ldq_code(p) ldq_raw(p) -#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_vmem(p, 1, 0); ldub_raw(p); }) +#define ldsb_kernel(p) ({ trace_vmem(p, 1, 0); ldsb_raw(p); }) +#define lduw_kernel(p) ({ trace_vmem(p, 2, 0); lduw_raw(p); }) +#define ldsw_kernel(p) ({ trace_vmem(p, 2, 0); ldsw_raw(p); }) +#define ldl_kernel(p) ({ trace_vmem(p, 4, 0); ldl_raw(p); }) +#define ldq_kernel(p) ({ trace_vmem(p, 8, 0); ldq_raw(p); }) +#define ldfl_kernel(p) ({ trace_vmem(p, 4, 0); ldfl_raw(p); }) +#define ldfq_kernel(p) ({ trace_vmem(p, 8, 0); ldfq_raw(p); }) +#define stb_kernel(p, v) ({ trace_vmem(p, 1, 1); stb_raw(p, v); }) +#define stw_kernel(p, v) ({ trace_vmem(p, 2, 1); stw_raw(p, v); }) +#define stl_kernel(p, v) ({ trace_vmem(p, 4, 1); stl_raw(p, v); }) +#define stq_kernel(p, v) ({ trace_vmem(p, 8, 1); stq_raw(p, v); }) +#define stfl_kernel(p, v) ({ trace_vmem(p, 4, 1); stfl_raw(p, v); }) +#define stfq_kernel(p, vt) ({ trace_vmem(p, 8, 1); stfq_raw(p, v); }) #endif /* defined(CONFIG_USER_ONLY) */ diff --git a/exec-all.h b/exec-all.h index c211242..2c97ff1 100644 --- a/exec-all.h +++ b/exec-all.h @@ -309,6 +309,8 @@ void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, #include "softmmu_defs.h" #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 env cpu_single_env @@ -325,6 +327,7 @@ void tlb_fill(CPUState *env1, target_ulong addr, int is_write, int mmu_idx, #include "softmmu_header.h" #undef ACCESS_TYPE +#undef TRACE_TCG_CODE_ACCESSOR #undef MEMSUFFIX #undef env diff --git a/softmmu_header.h b/softmmu_header.h index 818d7b6..a50c71f 100644 --- a/softmmu_header.h +++ b/softmmu_header.h @@ -25,6 +25,9 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ + +#include "trace.h" + #if DATA_SIZE == 8 #define SUFFIX q #define USUFFIX q @@ -88,6 +91,10 @@ static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr) unsigned long physaddr; int mmu_idx; +#if !defined(TRACE_TCG_CODE_ACCESSOR) + trace_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 +116,10 @@ static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr) unsigned long physaddr; int mmu_idx; +#if !defined(TRACE_TCG_CODE_ACCESSOR) + trace_vmem(ptr, DATA_SIZE, 0); +#endif + addr = ptr; page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); mmu_idx = CPU_MMU_INDEX; @@ -134,6 +145,10 @@ static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE unsigned long physaddr; int mmu_idx; +#if !defined(TRACE_TCG_CODE_ACCESSOR) + trace_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 82e04e7..8b738f0 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -2522,3 +2522,9 @@ static inline void tcg_gen_qemu_st64(TCGv_i64 arg, TCGv addr, int mem_index) TCGV_PTR_TO_NAT(A), (B)) #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 */ + +/* 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" diff --git a/trace-events b/trace-events index 9b315c5..14ea7ef 100644 --- a/trace-events +++ b/trace-events @@ -660,3 +660,12 @@ disable tcg vbbl(uint64_t vaddr) "vaddr=0x%016"PRIx64 # # vaddr : instruction's virtual address disable tcg vfetch(uint64_t vaddr) "vaddr=0x%016"PRIx64 + +# Start virtual memory access (before any potential access violation) +# +# Targets: all +# +# vaddr : access' virtual address +# size : access' size (bytes) +# write : whether the access is a write +disable tcg 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..e19657d --- /dev/null +++ b/trace/tcg-op-internal.h @@ -0,0 +1,74 @@ +/* -*- mode: c -*- + * Copyright (c) 2011 Lluís Vilanova + * + * 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. + */ + +#ifndef TRACE__TCG_OP_INTERNAL_H +#define TRACE__TCG_OP_INTERNAL_H + +#define tcg_gen_qemu_ld8u(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 1, 0); \ + (tcg_gen_qemu_ld8u)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_ld8s(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 1, 0); \ + (tcg_gen_qemu_ld8s)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_ld16u(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 2, 0); \ + (tcg_gen_qemu_ld16u)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_ld16s(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 2, 0); \ + (tcg_gen_qemu_ld16s)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_ld32u(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 4, 0); \ + (tcg_gen_qemu_ld32u)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_ld32s(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 4, 0); \ + (tcg_gen_qemu_ld32s)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_ld64(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 8, 0); \ + (tcg_gen_qemu_ld64)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_st8(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 1, 1); \ + (tcg_gen_qemu_st8)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_st16(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 2, 1); \ + (tcg_gen_qemu_st16)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_st32(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 4, 1); \ + (tcg_gen_qemu_st32)(arg, addr, mem_index); \ + } while (0) +#define tcg_gen_qemu_st64(arg, addr, mem_index) \ + do { \ + gen_helper_trace_vmem(addr, 8, 1); \ + (tcg_gen_qemu_st64)(arg, addr, mem_index); \ + } while (0) + +#endif /* TRACE__TCG_OP_INTERNAL_H */