From nobody Thu Nov 6 10:38:32 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1540489255394417.62751725307305; Thu, 25 Oct 2018 10:40:55 -0700 (PDT) Received: from localhost ([::1]:56112 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gFjcr-00089d-Lm for importer@patchew.org; Thu, 25 Oct 2018 13:40:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40311) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gFjKj-0006hn-At for qemu-devel@nongnu.org; Thu, 25 Oct 2018 13:22:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gFjKJ-00008N-7F for qemu-devel@nongnu.org; Thu, 25 Oct 2018 13:21:45 -0400 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:37033) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gFjKH-0008Qz-9l for qemu-devel@nongnu.org; Thu, 25 Oct 2018 13:21:43 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 6D16D221DB; Thu, 25 Oct 2018 13:21:11 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 25 Oct 2018 13:21:11 -0400 Received: from localhost (flamenco.cs.columbia.edu [128.59.20.216]) by mail.messagingengine.com (Postfix) with ESMTPA id D061FE4897; Thu, 25 Oct 2018 13:21:10 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=braap.org; h= from:to:cc:subject:date:message-id:in-reply-to:references; s= mesmtp; bh=bpnD0ZnLUoFh8c4992Zev1J45j9zHMTl9UIsGquI/bY=; b=gx6Ta JBLWkY++MMRxayWMuBkAJGpASCamA818dlZiSYLNEwJMzIL8imFbDbm0eWVUJxGh KVPX29fNqN/rsK2bbExwIZsjI45sg7zAGKZJS/g4Hl7hd8ygmWfpJiV6QNOaJ1Jf Yykv6WonPagxWlYFJRWn8fBQXNegPsBMeizdn0= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; bh=bpnD0ZnLUoFh8c4992Zev1J45j9zH MTl9UIsGquI/bY=; b=zYr9DUD7vgvAwjgnU1m4s96zZYq6TXiaNV5l548t/jyuz EajojuKNmz9dR9hWtNc+acNiyp0f/gSeQXiA7FqIxFGADvkKxKHYc1fbUuNUl/0U vr8tjKpRp/GSLpY+nSEuzJEPUWK5Ny93eTPzptD3KuPuz17auLiA44up7mGhqK+T 9phIeJBb2np50fc8kvi2+U9vZQ/LBJ7x7uM4DC72jbrTmWm8XzuDRTbsuiuSbVj6 CU5/N3KZK75p6IADIASLJf+/aMFmlNzLzF/axnScH8oTdhBvsNOMMq7mlZ5HCETM dsubyOn7mDp7PclAumrD/OvfikiR3wLFGhwDuFcrQ== X-ME-Sender: X-ME-Proxy: From: "Emilio G. Cota" To: qemu-devel@nongnu.org Date: Thu, 25 Oct 2018 13:20:27 -0400 Message-Id: <20181025172057.20414-19-cota@braap.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181025172057.20414-1-cota@braap.org> References: <20181025172057.20414-1-cota@braap.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 66.111.4.27 Subject: [Qemu-devel] [RFC 18/48] tcg: add memory callbacks for plugins (WIP) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , =?UTF-8?q?Alex=20Benn=C3=A9e?= , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , Pavel Dovgalyuk , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" XXX: store hostaddr from non-i386 TCG backends XXX: what hostaddr to return for I/O accesses? XXX: what hostaddr to return for cross-page accesses? Here the trickiest feature is passing the host address to memory callbacks that request it. Perhaps it would be more appropriate to pass a "physical" address to plugins, but since in QEMU host addr ~=3D guest physical, I'm going with that for simplicity. To keep the implementation simple we piggy-back on the TLB fast path, and thus can only provide the host address _after_ memory accesses have occurred. For the slow path, it's a bit tedious because there are many places to update, but it's fairly simple. However, note that cross-page accesses are tricky, since the access might be to non-contiguous host addresses. So I'm punting on that and just passing NULL. Signed-off-by: Emilio G. Cota --- accel/tcg/atomic_template.h | 8 ++++- accel/tcg/softmmu_template.h | 39 ++++++++++++++++++++ include/exec/cpu-defs.h | 2 ++ include/exec/cpu_ldst_template.h | 43 +++++++++++++++-------- include/exec/cpu_ldst_useronly_template.h | 42 +++++++++++++++------- tcg/tcg-op.h | 5 +++ tcg/tcg.h | 4 +++ tcg/i386/tcg-target.inc.c | 5 +++ tcg/tcg-op.c | 37 ++++++++++++++----- tcg/tcg.c | 3 ++ 10 files changed, 152 insertions(+), 36 deletions(-) diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h index b13318c1ce..3de34dc462 100644 --- a/accel/tcg/atomic_template.h +++ b/accel/tcg/atomic_template.h @@ -18,6 +18,7 @@ * License along with this library; if not, see . */ =20 +#include "qemu/plugin.h" #include "trace/mem.h" =20 #if DATA_SIZE =3D=3D 16 @@ -66,17 +67,22 @@ trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info | TRACE_MEM_S= T); \ } while (0) =20 -# define ATOMIC_TRACE_RMW_POST \ +# define ATOMIC_TRACE_RMW_POST do { = \ + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info); = \ + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info | TRACE_MEM_= ST); \ +} while (0) =20 # define ATOMIC_TRACE_LD_PRE \ trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info) =20 # define ATOMIC_TRACE_LD_POST \ + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info) =20 # define ATOMIC_TRACE_ST_PRE \ trace_guest_mem_before_exec(ENV_GET_CPU(env), addr, info) =20 # define ATOMIC_TRACE_ST_POST \ + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), addr, haddr, info) =20 #endif /* ATOMIC_TRACE_RMW_PRE */ =20 diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h index b0adea045e..f6d2f60b81 100644 --- a/accel/tcg/softmmu_template.h +++ b/accel/tcg/softmmu_template.h @@ -103,6 +103,11 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchS= tate *env, MMUAccessType access_type) { CPUIOTLBEntry *iotlbentry =3D &env->iotlb[mmu_idx][index]; + + /* XXX Any sensible choice other than NULL? */ + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D NULL; + } return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, recheck, access_type, DATA_SIZE); } @@ -162,12 +167,23 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target= _ulong addr, res2 =3D helper_le_ld_name(env, addr2, oi, retaddr); shift =3D (addr & (DATA_SIZE - 1)) * 8; =20 + /* + * XXX cross-page accesses would have to be split into separate ac= cesses + * for the host address to make sense. For now, just return NULL. + */ + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D NULL; + } + /* Little-endian combine. */ res =3D (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift)); return res; } =20 haddr =3D addr + entry->addend; + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D (void *)haddr; + } #if DATA_SIZE =3D=3D 1 res =3D glue(glue(ld, LSUFFIX), _p)((uint8_t *)haddr); #else @@ -231,12 +247,19 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target= _ulong addr, res2 =3D helper_be_ld_name(env, addr2, oi, retaddr); shift =3D (addr & (DATA_SIZE - 1)) * 8; =20 + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D NULL; + } + /* Big-endian combine. */ res =3D (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift)); return res; } =20 haddr =3D addr + entry->addend; + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D (void *)haddr; + } res =3D glue(glue(ld, LSUFFIX), _be_p)((uint8_t *)haddr); return res; } @@ -270,6 +293,10 @@ static inline void glue(io_write, SUFFIX)(CPUArchState= *env, bool recheck) { CPUIOTLBEntry *iotlbentry =3D &env->iotlb[mmu_idx][index]; + + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D NULL; + } return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, recheck, DATA_SIZE); } @@ -340,10 +367,16 @@ void helper_le_st_name(CPUArchState *env, target_ulon= g addr, DATA_TYPE val, glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, oi, retaddr); } + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D NULL; + } return; } =20 haddr =3D addr + entry->addend; + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D (void *)haddr; + } #if DATA_SIZE =3D=3D 1 glue(glue(st, SUFFIX), _p)((uint8_t *)haddr, val); #else @@ -418,10 +451,16 @@ void helper_be_st_name(CPUArchState *env, target_ulon= g addr, DATA_TYPE val, glue(helper_ret_stb, MMUSUFFIX)(env, addr + i, val8, oi, retaddr); } + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D NULL; + } return; } =20 haddr =3D addr + entry->addend; + if (tcg_ctx->plugin_mem_cb) { + env->hostaddr =3D (void *)haddr; + } glue(glue(st, SUFFIX), _be_p)((uint8_t *)haddr, val); } #endif /* DATA_SIZE > 1 */ diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index 40cd5d4774..c92c24a4a3 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -186,6 +186,8 @@ typedef struct CPUTLBDesc { CPUTLBEntry tlb_v_table[NB_MMU_MODES][CPU_VTLB_SIZE]; \ CPU_IOTLB \ CPUIOTLBEntry iotlb_v[NB_MMU_MODES][CPU_VTLB_SIZE]; \ + /* stores the host address of a guest access, if needed for plugins */= \ + void *hostaddr; \ size_t tlb_flush_count; \ target_ulong tlb_flush_addr; \ target_ulong tlb_flush_mask; \ diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_templ= ate.h index 0f061d47ef..e25319de4b 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -28,6 +28,7 @@ #include "trace-root.h" #endif =20 +#include "qemu/plugin.h" #include "trace/mem.h" =20 #if DATA_SIZE =3D=3D 8 @@ -86,11 +87,11 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUAr= chState *env, target_ulong addr; int mmu_idx; TCGMemOpIdx oi; - + uintptr_t hostaddr; #if !defined(SOFTMMU_CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, false, MO_TE, false)); + uint8_t meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, false); + + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); #endif =20 addr =3D ptr; @@ -101,10 +102,14 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPU= ArchState *env, oi =3D make_memop_idx(SHIFT, mmu_idx); res =3D glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr, oi, retaddr); + hostaddr =3D (uintptr_t)env->hostaddr; } else { - uintptr_t hostaddr =3D addr + entry->addend; + hostaddr =3D addr + entry->addend; res =3D glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr); } +#ifndef SOFTMMU_CODE_ACCESS + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), ptr, (void *)hostaddr, memin= fo); +#endif return res; } =20 @@ -125,11 +130,11 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPU= ArchState *env, target_ulong addr; int mmu_idx; TCGMemOpIdx oi; - + uintptr_t hostaddr; #if !defined(SOFTMMU_CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, true, MO_TE, false)); + uint8_t meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, false); + + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); #endif =20 addr =3D ptr; @@ -140,10 +145,14 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPU= ArchState *env, oi =3D make_memop_idx(SHIFT, mmu_idx); res =3D (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX), MMUSUFFIX)(env, addr, oi, retaddr); + hostaddr =3D (uintptr_t)env->hostaddr; } else { - uintptr_t hostaddr =3D addr + entry->addend; + hostaddr =3D addr + entry->addend; res =3D glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr); } +#ifndef SOFTMMU_CODE_ACCESS + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), ptr, (void *)hostaddr, memin= fo); +#endif return res; } =20 @@ -167,11 +176,11 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUA= rchState *env, target_ulong addr; int mmu_idx; TCGMemOpIdx oi; - + uintptr_t hostaddr; #if !defined(SOFTMMU_CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, false, MO_TE, true)); + uint8_t meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, true); + + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); #endif =20 addr =3D ptr; @@ -182,10 +191,14 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUA= rchState *env, oi =3D make_memop_idx(SHIFT, mmu_idx); glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi, retaddr); + hostaddr =3D (uintptr_t)env->hostaddr; } else { - uintptr_t hostaddr =3D addr + entry->addend; + hostaddr =3D addr + entry->addend; glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v); } +#ifndef SOFTMMU_CODE_ACCESS + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), ptr, (void *)hostaddr, memin= fo); +#endif } =20 static inline void diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_l= dst_useronly_template.h index 0fd6019af0..e752e9c00e 100644 --- a/include/exec/cpu_ldst_useronly_template.h +++ b/include/exec/cpu_ldst_useronly_template.h @@ -64,12 +64,19 @@ static inline RES_TYPE glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr) { + RES_TYPE ret; +#if !defined(CODE_ACCESS) + uint8_t meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, false); + + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); +#endif + + ret =3D glue(glue(ld, USUFFIX), _p)(g2h(ptr)); + #if !defined(CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, false, MO_TE, false)); + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), ptr, NULL, meminfo); #endif - return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); + return ret; } =20 static inline RES_TYPE @@ -88,12 +95,19 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUAr= chState *env, static inline int glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr) { + int ret; #if !defined(CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, true, MO_TE, false)); + uint8_t meminfo =3D trace_mem_build_info(SHIFT, true, MO_TE, false); + + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); #endif - return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); + + ret =3D glue(glue(lds, SUFFIX), _p)(g2h(ptr)); + +#if !defined(CODE_ACCESS) + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), ptr, NULL, meminfo); +#endif + return ret; } =20 static inline int @@ -109,17 +123,21 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPU= ArchState *env, } #endif =20 -#ifndef CODE_ACCESS +#if !defined(CODE_ACCESS) static inline void glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, abi_ptr ptr, RES_TYPE v) { #if !defined(CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, false, MO_TE, true)); + uint8_t meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, true); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); #endif + glue(glue(st, SUFFIX), _p)(g2h(ptr), v); + +#if !defined(CODE_ACCESS) + qemu_plugin_vcpu_mem_cb(ENV_GET_CPU(env), ptr, NULL, meminfo); +#endif } =20 static inline void diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h index 7513c1eb7c..cded8fc05b 100644 --- a/tcg/tcg-op.h +++ b/tcg/tcg-op.h @@ -1208,6 +1208,11 @@ static inline void tcg_gen_ld_ptr(TCGv_ptr r, TCGv_p= tr a, intptr_t o) glue(tcg_gen_ld_,PTR)((NAT)r, a, o); } =20 +static inline void tcg_gen_st_ptr(TCGv_ptr r, TCGv_ptr a, intptr_t o) +{ + glue(tcg_gen_st_,PTR)((NAT)r, a, o); +} + static inline void tcg_gen_discard_ptr(TCGv_ptr a) { glue(tcg_gen_discard_,PTR)((NAT)a); diff --git a/tcg/tcg.h b/tcg/tcg.h index 2c378415d2..d5afe25c97 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -29,6 +29,7 @@ #include "cpu.h" #include "exec/tb-context.h" #include "qemu/bitops.h" +#include "qemu/plugin.h" #include "qemu/queue.h" #include "tcg-mo.h" #include "tcg-target.h" @@ -719,6 +720,9 @@ struct TCGContext { =20 TCGLabel *exitreq_label; =20 + struct qemu_plugin_dyn_cb_arr *plugin_mem_cb; + struct qemu_plugin_insn *plugin_insn; + TCGTempSet free_temps[TCG_TYPE_COUNT * 2]; TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */ =20 diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index 5cbb07deab..7d9e6765c4 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -1685,6 +1685,11 @@ static inline void tcg_out_tlb_load(TCGContext *s, T= CGReg addrlo, TCGReg addrhi, /* add addend(r0), r1 */ tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0, offsetof(CPUTLBEntry, addend)); + + if (s->plugin_mem_cb) { + tcg_out_st(s, TCG_TYPE_PTR, r1, TCG_AREG0, + offsetof(CPUArchState, hostaddr)); + } } =20 /* diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 7a8015c5a9..add63547e3 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -31,6 +31,7 @@ #include "tcg-mo.h" #include "trace-tcg.h" #include "trace/mem.h" +#include "exec/plugin-gen.h" =20 /* Reduce the number of ifdefs below. This assumes that all uses of TCGV_HIGH and TCGV_LOW are properly protected by a conditional that @@ -2699,26 +2700,42 @@ static void tcg_gen_req_mo(TCGBar type) } } =20 +static inline void plugin_gen_mem_callbacks(TCGv vaddr, uint8_t info) +{ + struct qemu_plugin_dyn_cb_arr *arr =3D tcg_ctx->plugin_mem_cb; + + if (arr =3D=3D NULL) { + return; + } + qemu_plugin_gen_vcpu_mem_callbacks(arr, vaddr, info); +} + void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + uint8_t info =3D trace_mem_get_info(memop, 0); + tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); memop =3D tcg_canonicalize_memop(memop, 0, 0); - trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, - addr, trace_mem_get_info(memop, 0)); + trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, addr, info); gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx); + plugin_gen_mem_callbacks(addr, info); } =20 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + uint8_t info =3D trace_mem_get_info(memop, 1); + tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); memop =3D tcg_canonicalize_memop(memop, 0, 1); - trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, - addr, trace_mem_get_info(memop, 1)); + trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, addr, info); gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx); + plugin_gen_mem_callbacks(addr, info); } =20 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + uint8_t info; + tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); if (TCG_TARGET_REG_BITS =3D=3D 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop); @@ -2731,13 +2748,16 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, T= CGArg idx, TCGMemOp memop) } =20 memop =3D tcg_canonicalize_memop(memop, 1, 0); - trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, - addr, trace_mem_get_info(memop, 0)); + info =3D trace_mem_get_info(memop, 0); + trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, addr, info); gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx); + plugin_gen_mem_callbacks(addr, info); } =20 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + uint8_t info; + tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); if (TCG_TARGET_REG_BITS =3D=3D 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop); @@ -2745,9 +2765,10 @@ void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TC= GArg idx, TCGMemOp memop) } =20 memop =3D tcg_canonicalize_memop(memop, 1, 1); - trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, - addr, trace_mem_get_info(memop, 1)); + info =3D trace_mem_get_info(memop, 1); + trace_guest_mem_before_tcg(tcg_ctx->cpu, cpu_env, addr, info); gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx); + plugin_gen_mem_callbacks(addr, info); } =20 static void tcg_gen_ext_i32(TCGv_i32 ret, TCGv_i32 val, TCGMemOp opc) diff --git a/tcg/tcg.c b/tcg/tcg.c index a6824145b0..b10bda587a 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -1839,6 +1839,9 @@ void tcg_gen_callN(void *func, TCGTemp *ret, int narg= s, TCGTemp **args) * that @func can only be in one TCGHelperInfo. */ info =3D qht_lookup_custom(&helper_table, func, hash, tcg_helper_looku= p_cmp); + if (unlikely(tcg_ctx->plugin_insn)) { + tcg_ctx->plugin_insn->calls_helpers =3D true; + } do_tcg_gen_callN(info, ret, nargs, args); } =20 --=20 2.17.1