From patchwork Tue Mar 12 07:54:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13589576 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2BB8DC54E67 for ; Tue, 12 Mar 2024 07:56:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rjwyR-0001xQ-Mj; Tue, 12 Mar 2024 03:54:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rjwyP-0001xG-Ly for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:54:57 -0400 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rjwyN-0003ce-FO for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:54:57 -0400 Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-413428499a6so1428805e9.1 for ; Tue, 12 Mar 2024 00:54:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710230093; x=1710834893; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TQXLS2DY4B02v/A7m/9REcxNzZa6pRdyk/GVQIcPWYo=; b=zg7vjwFGzRshYlj6eTWpIIgSHTrkAdk9R2VvqdYeaF4EMi5yX+fzfoRUhCk6q1fwkk quYJ7P0oH+UnQ9dIqYmYmZR5E32TRcMBL5A1qZMom+4DSvNlIfzqyBH53MaUR5UZmENB Zh+XHCy83JiA26hCa5BS07G912iwuj+oKSAiuhabpsW9aX/HRsY1VC8EG9LRIk4l4dil 9cnGmS0a7y+pp5Gf0jj1goTphS8lE99MasrQs9aHPN20PRpVvdnHz0LHdHrGOoligrq8 1Yg+BkYs9R6JWwCEoe9EoYG/N7v6GwPvE2omsobXSq2ICqVBhIGt/KrCKwJWA0MjsQnD i+bQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710230093; x=1710834893; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TQXLS2DY4B02v/A7m/9REcxNzZa6pRdyk/GVQIcPWYo=; b=TEWxwCQlQJ+jtr9hDpL5SZ3uzJo4NSRkcAOZwZPT/B20q0uTAuHVaDjrDJHqLIXIoW ukS4y/ERZc6sG8Vp1AWuO6NBBp1YbuRFFTB/F18FTdWpF9+QCj6g+uxH2pZmScbQCsjE whLmTfIA/jKjorgxLE/99uo+Ap8x+lf5OENYfFO0DOByqLHqrd0Sr8JjhYzDRBU5edA1 D0wYu5abHShpqHi6RD7441XkANE/c8ixE4X2XUlM0SJCltl2QQKpqd2mes6xSn1EeHjr QvrOMDEjc2MUb6Pove0Eroj/tsQNR+BgBSkVVHKDssCCt+H8xxBRL0XBj4meqi9Xjhvn l3PA== X-Gm-Message-State: AOJu0YxwIlnm4ja8EGMRb6hW0RS2J4q0QveOf4caHrOs7WH/GdnJa1vJ 9zIHlsXNuHz0RpLW/fzX2iYFV1GGJpg8dLvsnDie4KQIeAVfTvbpteio60tzB/17hybROS18EZs vK80= X-Google-Smtp-Source: AGHT+IF5sGxv223kaiJAgHWIKcwUFp/przBTtBxZclIp60pdmNgO0c/9PBrPhgHbrvFCrY9qgBC3rQ== X-Received: by 2002:a5d:4144:0:b0:33e:8a1f:ff19 with SMTP id c4-20020a5d4144000000b0033e8a1fff19mr5442185wrq.2.1710230093491; Tue, 12 Mar 2024 00:54:53 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id u12-20020a5d6acc000000b0033e7a499deasm6108795wrw.109.2024.03.12.00.54.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Mar 2024 00:54:53 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Alexandre Iooss , Pierrick Bouvier , Mahmoud Mandour , Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Subject: [PATCH v2 1/5] plugins: prepare introduction of new inline ops Date: Tue, 12 Mar 2024 11:54:24 +0400 Message-Id: <20240312075428.244210-2-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312075428.244210-1-pierrick.bouvier@linaro.org> References: <20240312075428.244210-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::329; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wm1-x329.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Until now, only add_u64 was available, and all functions assumed this or were named uniquely. Signed-off-by: Pierrick Bouvier Reviewed-by: Richard Henderson --- include/qemu/plugin.h | 2 +- plugins/plugin.h | 1 + accel/tcg/plugin-gen.c | 77 +++++++++++++++++++++--------------------- plugins/api.c | 23 ++++++++++--- plugins/core.c | 5 +-- 5 files changed, 61 insertions(+), 47 deletions(-) diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index 12a96cea2a4..33a7cbe910c 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -74,7 +74,7 @@ enum plugin_dyn_cb_type { enum plugin_dyn_cb_subtype { PLUGIN_CB_REGULAR, PLUGIN_CB_REGULAR_R, - PLUGIN_CB_INLINE, + PLUGIN_CB_INLINE_ADD_U64, PLUGIN_N_CB_SUBTYPES, }; diff --git a/plugins/plugin.h b/plugins/plugin.h index 7c34f23cfcb..696b1fa38b0 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -70,6 +70,7 @@ struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id); void plugin_register_inline_op_on_entry(GArray **arr, enum qemu_plugin_mem_rw rw, + enum plugin_dyn_cb_subtype type, enum qemu_plugin_op op, qemu_plugin_u64 entry, uint64_t imm); diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c index 8028786c7bb..494467e0833 100644 --- a/accel/tcg/plugin-gen.c +++ b/accel/tcg/plugin-gen.c @@ -81,7 +81,7 @@ enum plugin_gen_from { enum plugin_gen_cb { PLUGIN_GEN_CB_UDATA, PLUGIN_GEN_CB_UDATA_R, - PLUGIN_GEN_CB_INLINE, + PLUGIN_GEN_CB_INLINE_ADD_U64, PLUGIN_GEN_CB_MEM, PLUGIN_GEN_ENABLE_MEM_HELPER, PLUGIN_GEN_DISABLE_MEM_HELPER, @@ -127,11 +127,7 @@ static void gen_empty_udata_cb_no_rwg(void) gen_empty_udata_cb(gen_helper_plugin_vcpu_udata_cb_no_rwg); } -/* - * For now we only support addi_i64. - * When we support more ops, we can generate one empty inline cb for each. - */ -static void gen_empty_inline_cb(void) +static void gen_empty_inline_cb_add_u64(void) { TCGv_i32 cpu_index = tcg_temp_ebb_new_i32(); TCGv_ptr cpu_index_as_ptr = tcg_temp_ebb_new_ptr(); @@ -219,9 +215,11 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from) gen_empty_mem_helper); /* fall through */ case PLUGIN_GEN_FROM_TB: + /* emit inline op before any callback */ + gen_wrapped(from, PLUGIN_GEN_CB_INLINE_ADD_U64, + gen_empty_inline_cb_add_u64); gen_wrapped(from, PLUGIN_GEN_CB_UDATA, gen_empty_udata_cb_no_rwg); gen_wrapped(from, PLUGIN_GEN_CB_UDATA_R, gen_empty_udata_cb_no_wg); - gen_wrapped(from, PLUGIN_GEN_CB_INLINE, gen_empty_inline_cb); break; default: g_assert_not_reached(); @@ -232,13 +230,14 @@ void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info) { enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info); + /* emit inline op before any callback */ + gen_plugin_cb_start(PLUGIN_GEN_FROM_MEM, PLUGIN_GEN_CB_INLINE_ADD_U64, rw); + gen_empty_inline_cb_add_u64(); + tcg_gen_plugin_cb_end(); + gen_plugin_cb_start(PLUGIN_GEN_FROM_MEM, PLUGIN_GEN_CB_MEM, rw); gen_empty_mem_cb(addr, info); tcg_gen_plugin_cb_end(); - - gen_plugin_cb_start(PLUGIN_GEN_FROM_MEM, PLUGIN_GEN_CB_INLINE, rw); - gen_empty_inline_cb(); - tcg_gen_plugin_cb_end(); } static TCGOp *find_op(TCGOp *op, TCGOpcode opc) @@ -436,9 +435,9 @@ static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb, return op; } -static TCGOp *append_inline_cb(const struct qemu_plugin_dyn_cb *cb, - TCGOp *begin_op, TCGOp *op, - int *unused) +static TCGOp *append_inline_cb_add_u64(const struct qemu_plugin_dyn_cb *cb, + TCGOp *begin_op, TCGOp *op, + int *unused) { char *ptr = cb->inline_insn.entry.score->data->data; size_t elem_size = g_array_get_element_size( @@ -538,9 +537,9 @@ inject_udata_cb(const GArray *cbs, TCGOp *begin_op) } static void -inject_inline_cb(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok) +inject_inline_cb_add_u64(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok) { - inject_cb_type(cbs, begin_op, append_inline_cb, ok); + inject_cb_type(cbs, begin_op, append_inline_cb_add_u64, ok); } static void @@ -588,8 +587,9 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb, GArray *arr; size_t n_cbs, i; - cbs[0] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR]; - cbs[1] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE]; + /* emit inline op before any callback */ + cbs[0] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_ADD_U64]; + cbs[1] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR]; n_cbs = 0; for (i = 0; i < ARRAY_SIZE(cbs); i++) { @@ -655,10 +655,11 @@ static void plugin_gen_tb_udata_r(const struct qemu_plugin_tb *ptb, inject_udata_cb(ptb->cbs[PLUGIN_CB_REGULAR_R], begin_op); } -static void plugin_gen_tb_inline(const struct qemu_plugin_tb *ptb, - TCGOp *begin_op) +static void plugin_gen_tb_inline_add_u64(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op) { - inject_inline_cb(ptb->cbs[PLUGIN_CB_INLINE], begin_op, op_ok); + inject_inline_cb_add_u64(ptb->cbs[PLUGIN_CB_INLINE_ADD_U64], + begin_op, op_ok); } static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb, @@ -677,12 +678,12 @@ static void plugin_gen_insn_udata_r(const struct qemu_plugin_tb *ptb, inject_udata_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR_R], begin_op); } -static void plugin_gen_insn_inline(const struct qemu_plugin_tb *ptb, - TCGOp *begin_op, int insn_idx) +static void plugin_gen_insn_inline_add_u64(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op, int insn_idx) { struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); - inject_inline_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE], - begin_op, op_ok); + inject_inline_cb_add_u64( + insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE_ADD_U64], begin_op, op_ok); } static void plugin_gen_mem_regular(const struct qemu_plugin_tb *ptb, @@ -692,14 +693,12 @@ static void plugin_gen_mem_regular(const struct qemu_plugin_tb *ptb, inject_mem_cb(insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR], begin_op); } -static void plugin_gen_mem_inline(const struct qemu_plugin_tb *ptb, - TCGOp *begin_op, int insn_idx) +static void plugin_gen_mem_inline_add_u64(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op, int insn_idx) { - const GArray *cbs; struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); - - cbs = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE]; - inject_inline_cb(cbs, begin_op, op_rw); + inject_inline_cb_add_u64(insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_ADD_U64], + begin_op, op_rw); } static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb, @@ -748,8 +747,8 @@ static void pr_ops(void) case PLUGIN_GEN_CB_UDATA: type = "udata"; break; - case PLUGIN_GEN_CB_INLINE: - type = "inline"; + case PLUGIN_GEN_CB_INLINE_ADD_U64: + type = "inline add u64"; break; case PLUGIN_GEN_CB_MEM: type = "mem"; @@ -799,8 +798,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_UDATA_R: plugin_gen_tb_udata_r(plugin_tb, op); break; - case PLUGIN_GEN_CB_INLINE: - plugin_gen_tb_inline(plugin_tb, op); + case PLUGIN_GEN_CB_INLINE_ADD_U64: + plugin_gen_tb_inline_add_u64(plugin_tb, op); break; default: g_assert_not_reached(); @@ -818,8 +817,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_UDATA_R: plugin_gen_insn_udata_r(plugin_tb, op, insn_idx); break; - case PLUGIN_GEN_CB_INLINE: - plugin_gen_insn_inline(plugin_tb, op, insn_idx); + case PLUGIN_GEN_CB_INLINE_ADD_U64: + plugin_gen_insn_inline_add_u64(plugin_tb, op, insn_idx); break; case PLUGIN_GEN_ENABLE_MEM_HELPER: plugin_gen_enable_mem_helper(plugin_tb, op, insn_idx); @@ -837,8 +836,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_MEM: plugin_gen_mem_regular(plugin_tb, op, insn_idx); break; - case PLUGIN_GEN_CB_INLINE: - plugin_gen_mem_inline(plugin_tb, op, insn_idx); + case PLUGIN_GEN_CB_INLINE_ADD_U64: + plugin_gen_mem_inline_add_u64(plugin_tb, op, insn_idx); break; default: g_assert_not_reached(); diff --git a/plugins/api.c b/plugins/api.c index 8fa5a600ac3..09ff7c70127 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -55,6 +55,16 @@ #endif #endif +static enum plugin_dyn_cb_subtype op_to_cb_subtype(enum qemu_plugin_op op) +{ + switch (op) { + case QEMU_PLUGIN_INLINE_ADD_U64: + return PLUGIN_CB_INLINE_ADD_U64; + default: + g_assert_not_reached(); + } +} + /* Uninstall and Reset handlers */ void qemu_plugin_uninstall(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb) @@ -108,8 +118,9 @@ void qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( uint64_t imm) { if (!tb->mem_only) { - plugin_register_inline_op_on_entry( - &tb->cbs[PLUGIN_CB_INLINE], 0, op, entry, imm); + enum plugin_dyn_cb_subtype type = op_to_cb_subtype(op); + plugin_register_inline_op_on_entry(&tb->cbs[type], + 0, type, op, entry, imm); } } @@ -135,8 +146,9 @@ void qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( uint64_t imm) { if (!insn->mem_only) { - plugin_register_inline_op_on_entry( - &insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE], 0, op, entry, imm); + enum plugin_dyn_cb_subtype type = op_to_cb_subtype(op); + plugin_register_inline_op_on_entry(&insn->cbs[PLUGIN_CB_INSN][type], + 0, type, op, entry, imm); } } @@ -162,8 +174,9 @@ void qemu_plugin_register_vcpu_mem_inline_per_vcpu( qemu_plugin_u64 entry, uint64_t imm) { + enum plugin_dyn_cb_subtype type = op_to_cb_subtype(op); plugin_register_inline_op_on_entry( - &insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE], rw, op, entry, imm); + &insn->cbs[PLUGIN_CB_MEM][type], rw, type, op, entry, imm); } void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id, diff --git a/plugins/core.c b/plugins/core.c index 11ca20e6267..a641a366ef9 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -318,6 +318,7 @@ static struct qemu_plugin_dyn_cb *plugin_get_dyn_cb(GArray **arr) void plugin_register_inline_op_on_entry(GArray **arr, enum qemu_plugin_mem_rw rw, + enum plugin_dyn_cb_subtype type, enum qemu_plugin_op op, qemu_plugin_u64 entry, uint64_t imm) @@ -326,7 +327,7 @@ void plugin_register_inline_op_on_entry(GArray **arr, dyn_cb = plugin_get_dyn_cb(arr); dyn_cb->userp = NULL; - dyn_cb->type = PLUGIN_CB_INLINE; + dyn_cb->type = type; dyn_cb->rw = rw; dyn_cb->inline_insn.entry = entry; dyn_cb->inline_insn.op = op; @@ -514,7 +515,7 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr, cb->f.vcpu_mem(cpu->cpu_index, make_plugin_meminfo(oi, rw), vaddr, cb->userp); break; - case PLUGIN_CB_INLINE: + case PLUGIN_CB_INLINE_ADD_U64: exec_inline_op(cb, cpu->cpu_index); break; default: From patchwork Tue Mar 12 07:54:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13589578 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 02CD5C54E66 for ; Tue, 12 Mar 2024 07:56:19 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rjwyT-0001xp-BS; Tue, 12 Mar 2024 03:55:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rjwyS-0001xh-8e for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:00 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rjwyQ-0003cn-5B for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:00 -0400 Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-33e70d71756so2707091f8f.1 for ; Tue, 12 Mar 2024 00:54:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710230096; x=1710834896; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+G3JO44I+TxZBMJCq8y8IXXNFiDh61c1hkycZ0ZrhWs=; b=CeByDYahlN3h50C3JiqXOZtrCQRJsQ3uV5xgxp+c5RoD53oyTev/7fB/pxTeKqMtb1 wsn/4ybrPcsQCuy1FlwmuJsQ29GT2JktpJM6UmDTo03bTXYoJoCv8o38xYqNCr4l+SII TPuKhywLEBN4rtoMpCgNP/7K0EuqzNHpl3zWixff4qQ2MNnSHlA+T7XOoN9Y7qyCiIVK L7L3MwO66GOyaQh6bixsPrmtRNpMOJn2p54urDc3fetsYdGZgxSskOHapn8+QyIZUpv7 S/ZiwFLHVaTW8RBzUfpBSky0JQE3xrNJh6jCm9Ocwsuf/c16SlAXvbIbX9H9xRnenMU0 aHuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710230096; x=1710834896; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+G3JO44I+TxZBMJCq8y8IXXNFiDh61c1hkycZ0ZrhWs=; b=FsYYOVb7qYohCY+rRvIgpQihhSDNKq0UzSC8puWbsDniSIBJmBq5rBl7w27UghRVit rtgZ9wY5XeODMMl9kiZPS2AmlVVE2Jtoy48mSsEPjCsq2eg2Kgxe7jFLQqZEQl1eAfsq EgLTEDnVQL9GGXcFOee+Hyc6MqH6JYjdSQcN1PIMIr4/sNHkZaIvj9ZvFe9OZnQPG3Gk QGs59JwklbocsuWT7NQEn4a3OIOqICoQW4jBwLKO/F+uDyuNnLsfKytX163rGZgfp7Ge xpcuWjbICXUEtszOlKGFwTLqg+aX0GdvPIYCbUWjbj9JN/JF1AK5bDfOJHudz3/WaIg4 QZ6A== X-Gm-Message-State: AOJu0YyUmjS0BvoZ5/cBzt1gKZdNTNEALFuAVurrGxucsOW15r3uX5eR a1vDBHJlNDuiFZXrRsofNgR7fF1HDixLcEr5VyzWmc9BSTIEdGeCW0Q+Jt+PEm1L9e07qOrMZde PKEk= X-Google-Smtp-Source: AGHT+IGhW4n5yUA9LF7GK5GdH/P7B2ozIOtsE5av7M4oZBieAq8OATzBdxyD7I/2l3/SaABIevVZww== X-Received: by 2002:adf:ca07:0:b0:33e:929e:5366 with SMTP id o7-20020adfca07000000b0033e929e5366mr5564145wrh.28.1710230096205; Tue, 12 Mar 2024 00:54:56 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id u12-20020a5d6acc000000b0033e7a499deasm6108795wrw.109.2024.03.12.00.54.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Mar 2024 00:54:55 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Alexandre Iooss , Pierrick Bouvier , Mahmoud Mandour , Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Subject: [PATCH v2 2/5] plugins: add new inline op STORE_U64 Date: Tue, 12 Mar 2024 11:54:25 +0400 Message-Id: <20240312075428.244210-3-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312075428.244210-1-pierrick.bouvier@linaro.org> References: <20240312075428.244210-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wr1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Pierrick Bouvier --- include/qemu/plugin.h | 1 + include/qemu/qemu-plugin.h | 4 +- accel/tcg/plugin-gen.c | 114 ++++++++++++++++++++++++++++++++++++- plugins/api.c | 2 + plugins/core.c | 4 ++ 5 files changed, 120 insertions(+), 5 deletions(-) diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index 33a7cbe910c..d92d64744e6 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -75,6 +75,7 @@ enum plugin_dyn_cb_subtype { PLUGIN_CB_REGULAR, PLUGIN_CB_REGULAR_R, PLUGIN_CB_INLINE_ADD_U64, + PLUGIN_CB_INLINE_STORE_U64, PLUGIN_N_CB_SUBTYPES, }; diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 4fc6c3739b2..c5cac897a0b 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -305,12 +305,12 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb, * enum qemu_plugin_op - describes an inline op * * @QEMU_PLUGIN_INLINE_ADD_U64: add an immediate value uint64_t - * - * Note: currently only a single inline op is supported. + * @QEMU_PLUGIN_INLINE_STORE_U64: store an immediate value uint64_t */ enum qemu_plugin_op { QEMU_PLUGIN_INLINE_ADD_U64, + QEMU_PLUGIN_INLINE_STORE_U64, }; /** diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c index 494467e0833..02c894106e2 100644 --- a/accel/tcg/plugin-gen.c +++ b/accel/tcg/plugin-gen.c @@ -46,8 +46,9 @@ #include "qemu/plugin.h" #include "cpu.h" #include "tcg/tcg.h" -#include "tcg/tcg-temp-internal.h" +#include "tcg/tcg-internal.h" #include "tcg/tcg-op.h" +#include "tcg/tcg-temp-internal.h" #include "exec/exec-all.h" #include "exec/plugin-gen.h" #include "exec/translator.h" @@ -82,6 +83,7 @@ enum plugin_gen_cb { PLUGIN_GEN_CB_UDATA, PLUGIN_GEN_CB_UDATA_R, PLUGIN_GEN_CB_INLINE_ADD_U64, + PLUGIN_GEN_CB_INLINE_STORE_U64, PLUGIN_GEN_CB_MEM, PLUGIN_GEN_ENABLE_MEM_HELPER, PLUGIN_GEN_DISABLE_MEM_HELPER, @@ -153,6 +155,30 @@ static void gen_empty_inline_cb_add_u64(void) tcg_temp_free_i32(cpu_index); } +static void gen_empty_inline_cb_store_u64(void) +{ + TCGv_i32 cpu_index = tcg_temp_ebb_new_i32(); + TCGv_ptr cpu_index_as_ptr = tcg_temp_ebb_new_ptr(); + TCGv_i64 val = tcg_temp_ebb_new_i64(); + TCGv_ptr ptr = tcg_temp_ebb_new_ptr(); + + tcg_gen_ld_i32(cpu_index, tcg_env, + -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index)); + /* second operand will be replaced by immediate value */ + tcg_gen_mul_i32(cpu_index, cpu_index, cpu_index); + tcg_gen_ext_i32_ptr(cpu_index_as_ptr, cpu_index); + tcg_gen_movi_ptr(ptr, 0); + tcg_gen_add_ptr(ptr, ptr, cpu_index_as_ptr); + + tcg_gen_movi_i64(val, 0); + tcg_gen_st_i64(val, ptr, 0); + + tcg_temp_free_ptr(ptr); + tcg_temp_free_i64(val); + tcg_temp_free_ptr(cpu_index_as_ptr); + tcg_temp_free_i32(cpu_index); +} + static void gen_empty_mem_cb(TCGv_i64 addr, uint32_t info) { TCGv_i32 cpu_index = tcg_temp_ebb_new_i32(); @@ -218,6 +244,8 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from) /* emit inline op before any callback */ gen_wrapped(from, PLUGIN_GEN_CB_INLINE_ADD_U64, gen_empty_inline_cb_add_u64); + gen_wrapped(from, PLUGIN_GEN_CB_INLINE_STORE_U64, + gen_empty_inline_cb_store_u64); gen_wrapped(from, PLUGIN_GEN_CB_UDATA, gen_empty_udata_cb_no_rwg); gen_wrapped(from, PLUGIN_GEN_CB_UDATA_R, gen_empty_udata_cb_no_wg); break; @@ -235,6 +263,11 @@ void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info) gen_empty_inline_cb_add_u64(); tcg_gen_plugin_cb_end(); + gen_plugin_cb_start(PLUGIN_GEN_FROM_MEM, + PLUGIN_GEN_CB_INLINE_STORE_U64, rw); + gen_empty_inline_cb_store_u64(); + tcg_gen_plugin_cb_end(); + gen_plugin_cb_start(PLUGIN_GEN_FROM_MEM, PLUGIN_GEN_CB_MEM, rw); gen_empty_mem_cb(addr, info); tcg_gen_plugin_cb_end(); @@ -352,6 +385,20 @@ static TCGOp *copy_st_i64(TCGOp **begin_op, TCGOp *op) return op; } +static TCGOp *copy_mov_i64(TCGOp **begin_op, TCGOp *op, uint64_t v) +{ + if (TCG_TARGET_REG_BITS == 32) { + op = copy_op(begin_op, op, INDEX_op_mov_i32); + op->args[1] = tcgv_i32_arg(TCGV_LOW(tcg_constant_i64(v))); + op = copy_op(begin_op, op, INDEX_op_mov_i32); + op->args[1] = tcgv_i32_arg(TCGV_HIGH(tcg_constant_i64(v))); + } else { + op = copy_op(begin_op, op, INDEX_op_mov_i64); + op->args[1] = tcgv_i64_arg(tcg_constant_i64(v)); + } + return op; +} + static TCGOp *copy_add_i64(TCGOp **begin_op, TCGOp *op, uint64_t v) { if (TCG_TARGET_REG_BITS == 32) { @@ -455,6 +502,24 @@ static TCGOp *append_inline_cb_add_u64(const struct qemu_plugin_dyn_cb *cb, return op; } +static TCGOp *append_inline_cb_store_u64(const struct qemu_plugin_dyn_cb *cb, + TCGOp *begin_op, TCGOp *op, + int *unused) +{ + char *ptr = cb->inline_insn.entry.score->data->data; + size_t elem_size = g_array_get_element_size( + cb->inline_insn.entry.score->data); + size_t offset = cb->inline_insn.entry.offset; + op = copy_ld_i32(&begin_op, op); + op = copy_mul_i32(&begin_op, op, elem_size); + op = copy_ext_i32_ptr(&begin_op, op); + op = copy_const_ptr(&begin_op, op, ptr + offset); + op = copy_add_ptr(&begin_op, op); + op = copy_mov_i64(&begin_op, op, cb->inline_insn.imm); + op = copy_st_i64(&begin_op, op); + return op; +} + static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb, TCGOp *begin_op, TCGOp *op, int *cb_idx) { @@ -542,6 +607,12 @@ inject_inline_cb_add_u64(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok) inject_cb_type(cbs, begin_op, append_inline_cb_add_u64, ok); } +static void +inject_inline_cb_store_u64(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok) +{ + inject_cb_type(cbs, begin_op, append_inline_cb_store_u64, ok); +} + static void inject_mem_cb(const GArray *cbs, TCGOp *begin_op) { @@ -583,13 +654,14 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb, struct qemu_plugin_insn *plugin_insn, TCGOp *begin_op) { - GArray *cbs[2]; + GArray *cbs[3]; GArray *arr; size_t n_cbs, i; /* emit inline op before any callback */ cbs[0] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_ADD_U64]; - cbs[1] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR]; + cbs[1] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_STORE_U64]; + cbs[2] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR]; n_cbs = 0; for (i = 0; i < ARRAY_SIZE(cbs); i++) { @@ -662,6 +734,13 @@ static void plugin_gen_tb_inline_add_u64(const struct qemu_plugin_tb *ptb, begin_op, op_ok); } +static void plugin_gen_tb_inline_store_u64(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op) +{ + inject_inline_cb_store_u64(ptb->cbs[PLUGIN_CB_INLINE_STORE_U64], + begin_op, op_ok); +} + static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb, TCGOp *begin_op, int insn_idx) { @@ -686,6 +765,14 @@ static void plugin_gen_insn_inline_add_u64(const struct qemu_plugin_tb *ptb, insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE_ADD_U64], begin_op, op_ok); } +static void plugin_gen_insn_inline_store_u64(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op, int insn_idx) +{ + struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); + inject_inline_cb_store_u64( + insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE_STORE_U64], begin_op, op_ok); +} + static void plugin_gen_mem_regular(const struct qemu_plugin_tb *ptb, TCGOp *begin_op, int insn_idx) { @@ -701,6 +788,15 @@ static void plugin_gen_mem_inline_add_u64(const struct qemu_plugin_tb *ptb, begin_op, op_rw); } +static void plugin_gen_mem_inline_store_u64(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op, int insn_idx) +{ + struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); + inject_inline_cb_store_u64( + insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_STORE_U64], + begin_op, op_rw); +} + static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb, TCGOp *begin_op, int insn_idx) { @@ -750,6 +846,9 @@ static void pr_ops(void) case PLUGIN_GEN_CB_INLINE_ADD_U64: type = "inline add u64"; break; + case PLUGIN_GEN_CB_INLINE_STORE_U64: + type = "inline store u64"; + break; case PLUGIN_GEN_CB_MEM: type = "mem"; break; @@ -801,6 +900,9 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_INLINE_ADD_U64: plugin_gen_tb_inline_add_u64(plugin_tb, op); break; + case PLUGIN_GEN_CB_INLINE_STORE_U64: + plugin_gen_tb_inline_store_u64(plugin_tb, op); + break; default: g_assert_not_reached(); } @@ -820,6 +922,9 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_INLINE_ADD_U64: plugin_gen_insn_inline_add_u64(plugin_tb, op, insn_idx); break; + case PLUGIN_GEN_CB_INLINE_STORE_U64: + plugin_gen_insn_inline_store_u64(plugin_tb, op, insn_idx); + break; case PLUGIN_GEN_ENABLE_MEM_HELPER: plugin_gen_enable_mem_helper(plugin_tb, op, insn_idx); break; @@ -839,6 +944,9 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_INLINE_ADD_U64: plugin_gen_mem_inline_add_u64(plugin_tb, op, insn_idx); break; + case PLUGIN_GEN_CB_INLINE_STORE_U64: + plugin_gen_mem_inline_store_u64(plugin_tb, op, insn_idx); + break; default: g_assert_not_reached(); } diff --git a/plugins/api.c b/plugins/api.c index 09ff7c70127..b7feed224a8 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -60,6 +60,8 @@ static enum plugin_dyn_cb_subtype op_to_cb_subtype(enum qemu_plugin_op op) switch (op) { case QEMU_PLUGIN_INLINE_ADD_U64: return PLUGIN_CB_INLINE_ADD_U64; + case QEMU_PLUGIN_INLINE_STORE_U64: + return PLUGIN_CB_INLINE_STORE_U64; default: g_assert_not_reached(); } diff --git a/plugins/core.c b/plugins/core.c index a641a366ef9..11f72594229 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -489,6 +489,9 @@ void exec_inline_op(struct qemu_plugin_dyn_cb *cb, int cpu_index) case QEMU_PLUGIN_INLINE_ADD_U64: *val += cb->inline_insn.imm; break; + case QEMU_PLUGIN_INLINE_STORE_U64: + *val = cb->inline_insn.imm; + break; default: g_assert_not_reached(); } @@ -516,6 +519,7 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr, vaddr, cb->userp); break; case PLUGIN_CB_INLINE_ADD_U64: + case PLUGIN_CB_INLINE_STORE_U64: exec_inline_op(cb, cpu->cpu_index); break; default: From patchwork Tue Mar 12 07:54:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13589579 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 65510C54E58 for ; Tue, 12 Mar 2024 07:56:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rjwyl-0002JW-60; Tue, 12 Mar 2024 03:55:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rjwyj-0002Il-LL for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:17 -0400 Received: from mail-wr1-x42b.google.com ([2a00:1450:4864:20::42b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rjwyU-0003d6-A1 for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:17 -0400 Received: by mail-wr1-x42b.google.com with SMTP id ffacd0b85a97d-33e959d8bc0so1761578f8f.1 for ; Tue, 12 Mar 2024 00:55:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710230099; x=1710834899; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GdadDDsYSdx5C71pz10Y8GnqMQs9L+4uC1BJhhVgUB0=; b=j9JYnajv9GY6Fe7q0eD2sxXKqqgMIViKaUtOToWpcAn1n2Klpq1V2YJ1EhUPksEJDi /iMlHXAEFLTctFxQzgaad/aoGrlaFM55LXsEtCWPmizLsXKhv/L3309jhh1of5mpjNOs L1xiC0ZayY593dfbOSGd83nBWxmMNARG8HBwq422Q4/o6+kf/Iq9OjWvvveXbI7PdJ1/ U7PWbbYTPclyVjgQZp6uBzTuYtqQ2kTRuzWY658+0s94zeySdkfO7u8Iy0EezZfJM/X2 jXTa6GpfN+I6fqMozTEHxl1UVOTwx56gDHT1FIQ30ruIDibNT0FPxR5EHqRfXYUvRRIb lboQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710230099; x=1710834899; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GdadDDsYSdx5C71pz10Y8GnqMQs9L+4uC1BJhhVgUB0=; b=KGndMJQNrwSBCGMbq73/DWCp9UB/flgh7V6/QmY5ueUbqVSK0YtDMgXlbTcsv01SrO 1muWs5wRrfft4Hkxq0dUgdqphW+cmj1pcplaW16EymanSWH+JoBin1iUn/jUvOrV7CFu Izdu2qHdkwXkd5QTP8J+CoJwEp3CPI6AKPcNFnZgkAwXvkRc2iSK1zUOVN5n8I1mhiwO 7Htssvv7GOF7MK2u5+iIgvkCxMTAYVUosQAhpql9A40Bb16AHlCBZoHIa7LOfAv+/yrU fTdOVUz7HmBuLbucJzrfkw/OCFl5paNeo4l4E+9kQc8J4em1P9pTHOUnrgHXAINnkgBk 04HQ== X-Gm-Message-State: AOJu0YwakgugnSDdRosGZ+AnJQ0FjhChuTRbN21xMY90kzx1Xa/KIaDK 1PlStSO9xBEO67soD3Ks0fFekMo0riUenFE6VXdKYReLPCD8bAgze3WM7pJaCLCq3GwN5Z0ZTLp tdhM= X-Google-Smtp-Source: AGHT+IF42cD+nqkplVug7n6utyuMZTGD9ARQgTPiQaOxzGCff5owluXzNX8sJMJDnwyVhSVtHjaRhQ== X-Received: by 2002:a5d:5222:0:b0:33e:67b1:f7c8 with SMTP id i2-20020a5d5222000000b0033e67b1f7c8mr5313278wra.37.1710230098978; Tue, 12 Mar 2024 00:54:58 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id u12-20020a5d6acc000000b0033e7a499deasm6108795wrw.109.2024.03.12.00.54.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Mar 2024 00:54:58 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Alexandre Iooss , Pierrick Bouvier , Mahmoud Mandour , Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Subject: [PATCH v2 3/5] tests/plugin/inline: add test for STORE_U64 inline op Date: Tue, 12 Mar 2024 11:54:26 +0400 Message-Id: <20240312075428.244210-4-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312075428.244210-1-pierrick.bouvier@linaro.org> References: <20240312075428.244210-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42b; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wr1-x42b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Pierrick Bouvier --- tests/plugin/inline.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/tests/plugin/inline.c b/tests/plugin/inline.c index 0163e9b51c5..30acc7a1838 100644 --- a/tests/plugin/inline.c +++ b/tests/plugin/inline.c @@ -22,6 +22,12 @@ typedef struct { uint64_t count_mem_inline; } CPUCount; +typedef struct { + uint64_t data_insn; + uint64_t data_tb; + uint64_t data_mem; +} CPUData; + static struct qemu_plugin_scoreboard *counts; static qemu_plugin_u64 count_tb; static qemu_plugin_u64 count_tb_inline; @@ -29,6 +35,10 @@ static qemu_plugin_u64 count_insn; static qemu_plugin_u64 count_insn_inline; static qemu_plugin_u64 count_mem; static qemu_plugin_u64 count_mem_inline; +static struct qemu_plugin_scoreboard *data; +static qemu_plugin_u64 data_insn; +static qemu_plugin_u64 data_tb; +static qemu_plugin_u64 data_mem; static uint64_t global_count_tb; static uint64_t global_count_insn; @@ -109,11 +119,13 @@ static void plugin_exit(qemu_plugin_id_t id, void *udata) stats_mem(); qemu_plugin_scoreboard_free(counts); + qemu_plugin_scoreboard_free(data); } static void vcpu_tb_exec(unsigned int cpu_index, void *udata) { qemu_plugin_u64_add(count_tb, cpu_index, 1); + g_assert(qemu_plugin_u64_get(data_tb, cpu_index) == (uintptr_t) udata); g_mutex_lock(&tb_lock); max_cpu_index = MAX(max_cpu_index, cpu_index); global_count_tb++; @@ -123,6 +135,7 @@ static void vcpu_tb_exec(unsigned int cpu_index, void *udata) static void vcpu_insn_exec(unsigned int cpu_index, void *udata) { qemu_plugin_u64_add(count_insn, cpu_index, 1); + g_assert(qemu_plugin_u64_get(data_insn, cpu_index) == (uintptr_t) udata); g_mutex_lock(&insn_lock); global_count_insn++; g_mutex_unlock(&insn_lock); @@ -131,9 +144,10 @@ static void vcpu_insn_exec(unsigned int cpu_index, void *udata) static void vcpu_mem_access(unsigned int cpu_index, qemu_plugin_meminfo_t info, uint64_t vaddr, - void *userdata) + void *udata) { qemu_plugin_u64_add(count_mem, cpu_index, 1); + g_assert(qemu_plugin_u64_get(data_mem, cpu_index) == (uintptr_t) udata); g_mutex_lock(&mem_lock); global_count_mem++; g_mutex_unlock(&mem_lock); @@ -141,20 +155,34 @@ static void vcpu_mem_access(unsigned int cpu_index, static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { + void *tb_store = tb; qemu_plugin_register_vcpu_tb_exec_cb( - tb, vcpu_tb_exec, QEMU_PLUGIN_CB_NO_REGS, 0); + tb, vcpu_tb_exec, QEMU_PLUGIN_CB_NO_REGS, tb_store); qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( tb, QEMU_PLUGIN_INLINE_ADD_U64, count_tb_inline, 1); + qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( + tb, QEMU_PLUGIN_INLINE_STORE_U64, data_tb, (uintptr_t) tb_store); for (int idx = 0; idx < qemu_plugin_tb_n_insns(tb); ++idx) { struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, idx); + void *insn_store = insn; + void *mem_store = (char *)insn_store + 0xff; + qemu_plugin_register_vcpu_insn_exec_cb( - insn, vcpu_insn_exec, QEMU_PLUGIN_CB_NO_REGS, 0); + insn, vcpu_insn_exec, QEMU_PLUGIN_CB_NO_REGS, insn_store); + qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( + insn, QEMU_PLUGIN_INLINE_STORE_U64, data_insn, + (uintptr_t) insn_store); qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( insn, QEMU_PLUGIN_INLINE_ADD_U64, count_insn_inline, 1); + qemu_plugin_register_vcpu_mem_cb(insn, &vcpu_mem_access, QEMU_PLUGIN_CB_NO_REGS, - QEMU_PLUGIN_MEM_RW, 0); + QEMU_PLUGIN_MEM_RW, mem_store); + qemu_plugin_register_vcpu_mem_inline_per_vcpu( + insn, QEMU_PLUGIN_MEM_RW, + QEMU_PLUGIN_INLINE_STORE_U64, + data_mem, (uintptr_t) mem_store); qemu_plugin_register_vcpu_mem_inline_per_vcpu( insn, QEMU_PLUGIN_MEM_RW, QEMU_PLUGIN_INLINE_ADD_U64, @@ -179,6 +207,11 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info, counts, CPUCount, count_insn_inline); count_mem_inline = qemu_plugin_scoreboard_u64_in_struct( counts, CPUCount, count_mem_inline); + data = qemu_plugin_scoreboard_new(sizeof(CPUData)); + data_insn = qemu_plugin_scoreboard_u64_in_struct(data, CPUData, data_insn); + data_tb = qemu_plugin_scoreboard_u64_in_struct(data, CPUData, data_tb); + data_mem = qemu_plugin_scoreboard_u64_in_struct(data, CPUData, data_mem); + qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); From patchwork Tue Mar 12 07:54:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13589575 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 94B37C54E58 for ; Tue, 12 Mar 2024 07:55:59 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rjwyc-0002Hu-BR; Tue, 12 Mar 2024 03:55:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rjwya-0002Hd-Vv for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:09 -0400 Received: from mail-wr1-x433.google.com ([2a00:1450:4864:20::433]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rjwyV-0003dW-VJ for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:07 -0400 Received: by mail-wr1-x433.google.com with SMTP id ffacd0b85a97d-33e94c12cfaso1734823f8f.3 for ; Tue, 12 Mar 2024 00:55:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710230102; x=1710834902; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=OjQf3Ch17NMYMXaLjAOsCWTQFXbiB1Ixtktx+p4yZ8I=; b=NGY9g12Ee8seUdescko21t30bYmNfZvCLybDFZMhUPr0ebYGR6sDpTJNW9H3CHa/7f BYHtXJIi/k9ziB2/zydQ1+L2ILUKCsA8M7BCUhEb6mAUDVXtENZGJvUfdbbwkGwZSEdZ TDWVB7zWzynGXP0zi+fysnvljfRvNIMwvGHlioLoLM7UE3Q8yuDYMye6xzd9FqY+q1gH QeKRR88WUMZ739KJ+ajZ0wNDGfKcz9+mMbgnr94rjz3vcRmitxiQAoN7JT4iLjAl8kBW MJMN78s6+QIe2rGwLUL/NUatjfBxpkwMAHZPb98S4/RleCyo6tdkpDswH8CjT8iB3Wzh G6Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710230102; x=1710834902; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OjQf3Ch17NMYMXaLjAOsCWTQFXbiB1Ixtktx+p4yZ8I=; b=A/gMZe4SmHPn0qWiDw1mgDSkB/xx5cZpx9inhCDJnH/a8BOt0xS4c2lLydRqj48k+u wR+JcJBcSkSSNsE7yyBuUPkt78SnucXjIy7e/F4B/1itl5INioIODdoiBJdeFfvEq44c FOA1JaaROSSbToxQZLGo4tC18ypOPPRclEqPoP1l0bTp4tSHc6fpGJdL/4eVyO+U3Bam LHo4COsvdf7ozYo6gVjIHdyTj8hygbRrd5ARkXPUPekZwPgJ39gmuW9CUV3BQemTN8cE j4u+w8eb9rs0A7xuX24+BGcAMGBQqAHjsMJwil5R1mGWSuSiuWksyDhRYvYlSTSk59lm Qp0g== X-Gm-Message-State: AOJu0Yw7jxYy5PmC7teXrlwEGGnn8Ap9UImcW4PezJv0aFYAgpKMmY1G o9MMY+pXNx+K6Gm8KBZ4zrsPCdvRmPJA74RnvpzAfRH2TJ7Ef9IQabU0SOEzwkrr9b6kMKmIrHJ Yz50= X-Google-Smtp-Source: AGHT+IHIlKtV32YHxiEjbCEuoKwc21EbNf/fUHxQ6LUDXFKmmd/4MEOekdkfbpB0XtCCQJV0nzC7Kw== X-Received: by 2002:adf:ea45:0:b0:33e:7f5c:732c with SMTP id j5-20020adfea45000000b0033e7f5c732cmr1859432wrn.62.1710230101762; Tue, 12 Mar 2024 00:55:01 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id u12-20020a5d6acc000000b0033e7a499deasm6108795wrw.109.2024.03.12.00.54.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Mar 2024 00:55:01 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Alexandre Iooss , Pierrick Bouvier , Mahmoud Mandour , Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Subject: [PATCH v2 4/5] plugins: conditional callbacks Date: Tue, 12 Mar 2024 11:54:27 +0400 Message-Id: <20240312075428.244210-5-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312075428.244210-1-pierrick.bouvier@linaro.org> References: <20240312075428.244210-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::433; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wr1-x433.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Extend plugins API to support callback called with a given criteria (evaluated inline). Added functions: - qemu_plugin_register_vcpu_tb_exec_cond_cb - qemu_plugin_register_vcpu_insn_exec_cond_cb They expect as parameter a condition, a qemu_plugin_u64_t (op1) and an immediate (op2). Callback is called if op1 |cond| op2 is true. Signed-off-by: Pierrick Bouvier --- include/qemu/plugin.h | 7 ++ include/qemu/qemu-plugin.h | 76 +++++++++++++++ plugins/plugin.h | 8 ++ accel/tcg/plugin-gen.c | 174 ++++++++++++++++++++++++++++++++++- plugins/api.c | 51 ++++++++++ plugins/core.c | 19 ++++ plugins/qemu-plugins.symbols | 2 + 7 files changed, 334 insertions(+), 3 deletions(-) diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index d92d64744e6..056102b2361 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -74,6 +74,8 @@ enum plugin_dyn_cb_type { enum plugin_dyn_cb_subtype { PLUGIN_CB_REGULAR, PLUGIN_CB_REGULAR_R, + PLUGIN_CB_COND, + PLUGIN_CB_COND_R, PLUGIN_CB_INLINE_ADD_U64, PLUGIN_CB_INLINE_STORE_U64, PLUGIN_N_CB_SUBTYPES, @@ -97,6 +99,11 @@ struct qemu_plugin_dyn_cb { enum qemu_plugin_op op; uint64_t imm; } inline_insn; + struct { + qemu_plugin_u64 entry; + enum qemu_plugin_cond cond; + uint64_t imm; + } cond_cb; }; }; diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index c5cac897a0b..337de25ece7 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -262,6 +262,29 @@ enum qemu_plugin_mem_rw { QEMU_PLUGIN_MEM_RW, }; +/** + * enum qemu_plugin_cond - condition to enable callback + * + * @QEMU_PLUGIN_COND_NEVER: false + * @QEMU_PLUGIN_COND_ALWAYS: true + * @QEMU_PLUGIN_COND_EQ: is equal? + * @QEMU_PLUGIN_COND_NE: is not equal? + * @QEMU_PLUGIN_COND_LT: is less than? + * @QEMU_PLUGIN_COND_LE: is less than or equal? + * @QEMU_PLUGIN_COND_GT: is greater than? + * @QEMU_PLUGIN_COND_GE: is greater than or equal? + */ +enum qemu_plugin_cond { + QEMU_PLUGIN_COND_NEVER, + QEMU_PLUGIN_COND_ALWAYS, + QEMU_PLUGIN_COND_EQ, + QEMU_PLUGIN_COND_NE, + QEMU_PLUGIN_COND_LT, + QEMU_PLUGIN_COND_LE, + QEMU_PLUGIN_COND_GT, + QEMU_PLUGIN_COND_GE, +}; + /** * typedef qemu_plugin_vcpu_tb_trans_cb_t - translation callback * @id: unique plugin id @@ -301,6 +324,32 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb, enum qemu_plugin_cb_flags flags, void *userdata); +/** + * qemu_plugin_register_vcpu_tb_exec_cond_cb() - register conditional callback + * @tb: the opaque qemu_plugin_tb handle for the translation + * @cb: callback function + * @cond: condition to enable callback + * @entry: first operand for condition + * @imm: second operand for condition + * @flags: does the plugin read or write the CPU's registers? + * @userdata: any plugin data to pass to the @cb? + * + * The @cb function is called when a translated unit executes if + * entry @cond imm is true. + * If condition is QEMU_PLUGIN_COND_ALWAYS, condition is never interpreted and + * this function is equivalent to qemu_plugin_register_vcpu_tb_exec_cb. + * If condition QEMU_PLUGIN_COND_NEVER, condition is never interpreted and + * callback is never installed. + */ +QEMU_PLUGIN_API +void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb, + qemu_plugin_vcpu_udata_cb_t cb, + enum qemu_plugin_cb_flags flags, + enum qemu_plugin_cond cond, + qemu_plugin_u64 entry, + uint64_t imm, + void *userdata); + /** * enum qemu_plugin_op - describes an inline op * @@ -344,6 +393,33 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, enum qemu_plugin_cb_flags flags, void *userdata); +/** + * qemu_plugin_register_vcpu_insn_exec_cond_cb() - conditional insn execution cb + * @insn: the opaque qemu_plugin_insn handle for an instruction + * @cb: callback function + * @flags: does the plugin read or write the CPU's registers? + * @cond: condition to enable callback + * @entry: first operand for condition + * @imm: second operand for condition + * @userdata: any plugin data to pass to the @cb? + * + * The @cb function is called when an instruction executes if + * entry @cond imm is true. + * If condition is QEMU_PLUGIN_COND_ALWAYS, condition is never interpreted and + * this function is equivalent to qemu_plugin_register_vcpu_insn_exec_cb. + * If condition QEMU_PLUGIN_COND_NEVER, condition is never interpreted and + * callback is never installed. + */ +QEMU_PLUGIN_API +void qemu_plugin_register_vcpu_insn_exec_cond_cb( + struct qemu_plugin_insn *insn, + qemu_plugin_vcpu_udata_cb_t cb, + enum qemu_plugin_cb_flags flags, + enum qemu_plugin_cond cond, + qemu_plugin_u64 entry, + uint64_t imm, + void *userdata); + /** * qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu() - insn exec inline op * @insn: the opaque qemu_plugin_insn handle for an instruction diff --git a/plugins/plugin.h b/plugins/plugin.h index 696b1fa38b0..118cc99bb2a 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -94,6 +94,14 @@ plugin_register_dyn_cb__udata(GArray **arr, qemu_plugin_vcpu_udata_cb_t cb, enum qemu_plugin_cb_flags flags, void *udata); +void +plugin_register_dyn_cond_cb__udata(GArray **arr, + qemu_plugin_vcpu_udata_cb_t cb, + enum qemu_plugin_cb_flags flags, + enum qemu_plugin_cond cond, + qemu_plugin_u64 entry, + uint64_t imm, + void *udata); void plugin_register_vcpu_mem_cb(GArray **arr, void *cb, diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c index 02c894106e2..790d9630dd2 100644 --- a/accel/tcg/plugin-gen.c +++ b/accel/tcg/plugin-gen.c @@ -46,6 +46,7 @@ #include "qemu/plugin.h" #include "cpu.h" #include "tcg/tcg.h" +#include "tcg/tcg-cond.h" #include "tcg/tcg-internal.h" #include "tcg/tcg-op.h" #include "tcg/tcg-temp-internal.h" @@ -82,6 +83,8 @@ enum plugin_gen_from { enum plugin_gen_cb { PLUGIN_GEN_CB_UDATA, PLUGIN_GEN_CB_UDATA_R, + PLUGIN_GEN_CB_COND_UDATA, + PLUGIN_GEN_CB_COND_UDATA_R, PLUGIN_GEN_CB_INLINE_ADD_U64, PLUGIN_GEN_CB_INLINE_STORE_U64, PLUGIN_GEN_CB_MEM, @@ -119,16 +122,58 @@ static void gen_empty_udata_cb(void (*gen_helper)(TCGv_i32, TCGv_ptr)) tcg_temp_free_i32(cpu_index); } +static void gen_empty_cond_udata_cb(void (*gen_helper)(TCGv_i32, TCGv_ptr)) +{ + TCGv_i32 cpu_index = tcg_temp_ebb_new_i32(); + TCGv_i32 cpu_offset = tcg_temp_ebb_new_i32(); + TCGv_ptr cpu_index_as_ptr = tcg_temp_ebb_new_ptr(); + TCGv_i64 val = tcg_temp_ebb_new_i64(); + TCGv_ptr ptr = tcg_temp_ebb_new_ptr(); + TCGv_ptr udata = tcg_temp_ebb_new_ptr(); + TCGLabel *after_cb = gen_new_label(); + + tcg_gen_movi_ptr(udata, 0); + tcg_gen_ld_i32(cpu_index, tcg_env, + -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index)); + /* second operand will be replaced by immediate value */ + tcg_gen_mul_i32(cpu_offset, cpu_index, cpu_index); + tcg_gen_ext_i32_ptr(cpu_index_as_ptr, cpu_offset); + tcg_gen_movi_ptr(ptr, 0); + tcg_gen_add_ptr(ptr, ptr, cpu_index_as_ptr); + tcg_gen_ld_i64(val, ptr, 0); + + tcg_gen_brcondi_i64(TCG_COND_EQ, val, 0, after_cb); + gen_helper(cpu_index, udata); + gen_set_label(after_cb); + + tcg_temp_free_ptr(udata); + tcg_temp_free_ptr(ptr); + tcg_temp_free_i64(val); + tcg_temp_free_ptr(cpu_index_as_ptr); + tcg_temp_free_i32(cpu_offset); + tcg_temp_free_i32(cpu_index); +} + static void gen_empty_udata_cb_no_wg(void) { gen_empty_udata_cb(gen_helper_plugin_vcpu_udata_cb_no_wg); } +static void gen_empty_cond_udata_cb_no_wg(void) +{ + gen_empty_cond_udata_cb(gen_helper_plugin_vcpu_udata_cb_no_wg); +} + static void gen_empty_udata_cb_no_rwg(void) { gen_empty_udata_cb(gen_helper_plugin_vcpu_udata_cb_no_rwg); } +static void gen_empty_cond_udata_cb_no_rwg(void) +{ + gen_empty_cond_udata_cb(gen_helper_plugin_vcpu_udata_cb_no_rwg); +} + static void gen_empty_inline_cb_add_u64(void) { TCGv_i32 cpu_index = tcg_temp_ebb_new_i32(); @@ -248,6 +293,10 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from) gen_empty_inline_cb_store_u64); gen_wrapped(from, PLUGIN_GEN_CB_UDATA, gen_empty_udata_cb_no_rwg); gen_wrapped(from, PLUGIN_GEN_CB_UDATA_R, gen_empty_udata_cb_no_wg); + gen_wrapped(from, PLUGIN_GEN_CB_COND_UDATA, + gen_empty_cond_udata_cb_no_rwg); + gen_wrapped(from, PLUGIN_GEN_CB_COND_UDATA_R, + gen_empty_cond_udata_cb_no_wg); break; default: g_assert_not_reached(); @@ -456,6 +505,29 @@ static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *func, int *cb_idx) return op; } +static TCGOp *copy_brcondi_i64(TCGOp **begin_op, TCGOp *op, TCGCond cond, + uint64_t imm) +{ + if (TCG_TARGET_REG_BITS == 32) { + op = copy_op(begin_op, op, INDEX_op_brcond2_i32); + /* low(arg1), high(arg1), 32(arg2), 32(arg2 >> 32), cond, label */ + op->args[2] = tcgv_i32_arg(tcg_constant_i32(imm)); + op->args[3] = tcgv_i32_arg(tcg_constant_i32(imm >> 32)); + op->args[4] = cond; + } else { + op = copy_op(begin_op, op, INDEX_op_brcond_i64); + /* arg1, arg2, cond, label */ + op->args[1] = tcgv_i64_arg(tcg_constant_i64(imm)); + op->args[2] = cond; + } + return op; +} + +static TCGOp *copy_set_label(TCGOp **begin_op, TCGOp *op) +{ + return copy_op(begin_op, op, INDEX_op_set_label); +} + /* * When we append/replace ops here we are sensitive to changing patterns of * TCGOps generated by the tcg_gen_FOO calls when we generated the @@ -482,6 +554,50 @@ static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb, return op; } +static TCGCond plugin_cond_to_tcgcond(enum qemu_plugin_cond cond) +{ + switch (cond) { + case QEMU_PLUGIN_COND_EQ: + return TCG_COND_EQ; + case QEMU_PLUGIN_COND_NE: + return TCG_COND_NE; + case QEMU_PLUGIN_COND_LT: + return TCG_COND_LTU; + case QEMU_PLUGIN_COND_LE: + return TCG_COND_LEU; + case QEMU_PLUGIN_COND_GT: + return TCG_COND_GTU; + case QEMU_PLUGIN_COND_GE: + return TCG_COND_GEU; + default: + /* ALWAYS and NEVER conditions should never reach */ + g_assert_not_reached(); + } +} + +static TCGOp *append_cond_udata_cb(const struct qemu_plugin_dyn_cb *cb, + TCGOp *begin_op, TCGOp *op, int *cb_idx) +{ + char *ptr = cb->cond_cb.entry.score->data->data; + size_t elem_size = g_array_get_element_size( + cb->cond_cb.entry.score->data); + size_t offset = cb->cond_cb.entry.offset; + /* Condition should be negated, as calling the cb is the "else" path */ + TCGCond cond = tcg_invert_cond(plugin_cond_to_tcgcond(cb->cond_cb.cond)); + + op = copy_const_ptr(&begin_op, op, cb->userp); + op = copy_ld_i32(&begin_op, op); + op = copy_mul_i32(&begin_op, op, elem_size); + op = copy_ext_i32_ptr(&begin_op, op); + op = copy_const_ptr(&begin_op, op, ptr + offset); + op = copy_add_ptr(&begin_op, op); + op = copy_ld_i64(&begin_op, op); + op = copy_brcondi_i64(&begin_op, op, cond, cb->cond_cb.imm); + op = copy_call(&begin_op, op, cb->f.vcpu_udata, cb_idx); + op = copy_set_label(&begin_op, op); + return op; +} + static TCGOp *append_inline_cb_add_u64(const struct qemu_plugin_dyn_cb *cb, TCGOp *begin_op, TCGOp *op, int *unused) @@ -601,6 +717,12 @@ inject_udata_cb(const GArray *cbs, TCGOp *begin_op) inject_cb_type(cbs, begin_op, append_udata_cb, op_ok); } +static void +inject_cond_udata_cb(const GArray *cbs, TCGOp *begin_op) +{ + inject_cb_type(cbs, begin_op, append_cond_udata_cb, op_ok); +} + static void inject_inline_cb_add_u64(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok) { @@ -654,7 +776,7 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb, struct qemu_plugin_insn *plugin_insn, TCGOp *begin_op) { - GArray *cbs[3]; + GArray *cbs[4]; GArray *arr; size_t n_cbs, i; @@ -662,6 +784,7 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb, cbs[0] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_ADD_U64]; cbs[1] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE_STORE_U64]; cbs[2] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR]; + cbs[3] = plugin_insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_COND]; n_cbs = 0; for (i = 0; i < ARRAY_SIZE(cbs); i++) { @@ -727,6 +850,18 @@ static void plugin_gen_tb_udata_r(const struct qemu_plugin_tb *ptb, inject_udata_cb(ptb->cbs[PLUGIN_CB_REGULAR_R], begin_op); } +static void plugin_gen_tb_cond_udata(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op) +{ + inject_cond_udata_cb(ptb->cbs[PLUGIN_CB_COND], begin_op); +} + +static void plugin_gen_tb_cond_udata_r(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op) +{ + inject_cond_udata_cb(ptb->cbs[PLUGIN_CB_COND_R], begin_op); +} + static void plugin_gen_tb_inline_add_u64(const struct qemu_plugin_tb *ptb, TCGOp *begin_op) { @@ -745,7 +880,6 @@ static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb, TCGOp *begin_op, int insn_idx) { struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); - inject_udata_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR], begin_op); } @@ -753,10 +887,23 @@ static void plugin_gen_insn_udata_r(const struct qemu_plugin_tb *ptb, TCGOp *begin_op, int insn_idx) { struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); - inject_udata_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR_R], begin_op); } +static void plugin_gen_insn_cond_udata(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op, int insn_idx) +{ + struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); + inject_cond_udata_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_COND], begin_op); +} + +static void plugin_gen_insn_cond_udata_r(const struct qemu_plugin_tb *ptb, + TCGOp *begin_op, int insn_idx) +{ + struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx); + inject_cond_udata_cb(insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_COND_R], begin_op); +} + static void plugin_gen_insn_inline_add_u64(const struct qemu_plugin_tb *ptb, TCGOp *begin_op, int insn_idx) { @@ -843,6 +990,15 @@ static void pr_ops(void) case PLUGIN_GEN_CB_UDATA: type = "udata"; break; + case PLUGIN_GEN_CB_UDATA_R: + type = "udata (read)"; + break; + case PLUGIN_GEN_CB_COND_UDATA: + type = "cond udata"; + break; + case PLUGIN_GEN_CB_COND_UDATA_R: + type = "cond udata (read)"; + break; case PLUGIN_GEN_CB_INLINE_ADD_U64: type = "inline add u64"; break; @@ -897,6 +1053,12 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_UDATA_R: plugin_gen_tb_udata_r(plugin_tb, op); break; + case PLUGIN_GEN_CB_COND_UDATA: + plugin_gen_tb_cond_udata(plugin_tb, op); + break; + case PLUGIN_GEN_CB_COND_UDATA_R: + plugin_gen_tb_cond_udata_r(plugin_tb, op); + break; case PLUGIN_GEN_CB_INLINE_ADD_U64: plugin_gen_tb_inline_add_u64(plugin_tb, op); break; @@ -919,6 +1081,12 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb) case PLUGIN_GEN_CB_UDATA_R: plugin_gen_insn_udata_r(plugin_tb, op, insn_idx); break; + case PLUGIN_GEN_CB_COND_UDATA: + plugin_gen_insn_cond_udata(plugin_tb, op, insn_idx); + break; + case PLUGIN_GEN_CB_COND_UDATA_R: + plugin_gen_insn_cond_udata_r(plugin_tb, op, insn_idx); + break; case PLUGIN_GEN_CB_INLINE_ADD_U64: plugin_gen_insn_inline_add_u64(plugin_tb, op, insn_idx); break; diff --git a/plugins/api.c b/plugins/api.c index b7feed224a8..fdf6167655e 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -113,6 +113,31 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb, } } +void qemu_plugin_register_vcpu_tb_exec_cond_cb(struct qemu_plugin_tb *tb, + qemu_plugin_vcpu_udata_cb_t cb, + enum qemu_plugin_cb_flags flags, + enum qemu_plugin_cond cond, + qemu_plugin_u64 entry, + uint64_t imm, + void *udata) +{ + if (cond == QEMU_PLUGIN_COND_NEVER || tb->mem_only) { + return; + } + if (cond == QEMU_PLUGIN_COND_ALWAYS) { + qemu_plugin_register_vcpu_tb_exec_cb(tb, cb, flags, udata); + return; + } + int index = flags == QEMU_PLUGIN_CB_R_REGS || + flags == QEMU_PLUGIN_CB_RW_REGS ? + PLUGIN_CB_COND_R : PLUGIN_CB_COND; + + plugin_register_dyn_cond_cb__udata(&tb->cbs[index], + cb, flags, + cond, entry, imm, + udata); +} + void qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( struct qemu_plugin_tb *tb, enum qemu_plugin_op op, @@ -141,6 +166,32 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn, } } +void qemu_plugin_register_vcpu_insn_exec_cond_cb( + struct qemu_plugin_insn *insn, + qemu_plugin_vcpu_udata_cb_t cb, + enum qemu_plugin_cb_flags flags, + enum qemu_plugin_cond cond, + qemu_plugin_u64 entry, + uint64_t imm, + void *udata) +{ + if (cond == QEMU_PLUGIN_COND_NEVER || insn->mem_only) { + return; + } + if (cond == QEMU_PLUGIN_COND_ALWAYS) { + qemu_plugin_register_vcpu_insn_exec_cb(insn, cb, flags, udata); + return; + } + int index = flags == QEMU_PLUGIN_CB_R_REGS || + flags == QEMU_PLUGIN_CB_RW_REGS ? + PLUGIN_CB_COND_R : PLUGIN_CB_COND; + + plugin_register_dyn_cond_cb__udata(&insn->cbs[PLUGIN_CB_INSN][index], + cb, flags, + cond, entry, imm, + udata); +} + void qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( struct qemu_plugin_insn *insn, enum qemu_plugin_op op, diff --git a/plugins/core.c b/plugins/core.c index 11f72594229..82d5f17438e 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -347,6 +347,25 @@ void plugin_register_dyn_cb__udata(GArray **arr, dyn_cb->type = PLUGIN_CB_REGULAR; } +void plugin_register_dyn_cond_cb__udata(GArray **arr, + qemu_plugin_vcpu_udata_cb_t cb, + enum qemu_plugin_cb_flags flags, + enum qemu_plugin_cond cond, + qemu_plugin_u64 entry, + uint64_t imm, + void *udata) +{ + struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr); + + dyn_cb->userp = udata; + /* Note flags are discarded as unused. */ + dyn_cb->f.vcpu_udata = cb; + dyn_cb->type = PLUGIN_CB_COND; + dyn_cb->cond_cb.cond = cond; + dyn_cb->cond_cb.entry = entry; + dyn_cb->cond_cb.imm = imm; +} + void plugin_register_vcpu_mem_cb(GArray **arr, void *cb, enum qemu_plugin_cb_flags flags, diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols index a9fac056c7f..aa0a77a319f 100644 --- a/plugins/qemu-plugins.symbols +++ b/plugins/qemu-plugins.symbols @@ -27,6 +27,7 @@ qemu_plugin_register_vcpu_idle_cb; qemu_plugin_register_vcpu_init_cb; qemu_plugin_register_vcpu_insn_exec_cb; + qemu_plugin_register_vcpu_insn_exec_cond_cb; qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu; qemu_plugin_register_vcpu_mem_cb; qemu_plugin_register_vcpu_mem_inline_per_vcpu; @@ -34,6 +35,7 @@ qemu_plugin_register_vcpu_syscall_cb; qemu_plugin_register_vcpu_syscall_ret_cb; qemu_plugin_register_vcpu_tb_exec_cb; + qemu_plugin_register_vcpu_tb_exec_cond_cb; qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu; qemu_plugin_register_vcpu_tb_trans_cb; qemu_plugin_reset; From patchwork Tue Mar 12 07:54:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierrick Bouvier X-Patchwork-Id: 13589577 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4DBE7C54E58 for ; Tue, 12 Mar 2024 07:56:05 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1rjwyk-0002JE-59; Tue, 12 Mar 2024 03:55:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1rjwyi-0002IV-Ju for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:16 -0400 Received: from mail-wr1-x429.google.com ([2a00:1450:4864:20::429]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1rjwyY-0003p2-DK for qemu-devel@nongnu.org; Tue, 12 Mar 2024 03:55:15 -0400 Received: by mail-wr1-x429.google.com with SMTP id ffacd0b85a97d-33e899ce9e3so1972126f8f.1 for ; Tue, 12 Mar 2024 00:55:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1710230104; x=1710834904; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1MdiWTyvmQ8k+0UnS+4iHEIsnW5J1mS8eY4/rmAJfhc=; b=bfEQsbi/jRcBoLprdcLCMMNY7oix3vHAieC4U7M+8QJVdo6kCBarIxCseNYTo3EoO2 6R71lOpN16lYYK/qAluNf0hHoVUgHu9RlDUTlxXlwf1TUKG83zBoWjXLAOxCBLjdgilW Kn1GPFvuTcR7URVdyVF2NN982x9s4Tz/VeSC8o6tDn11B5AkSIvlRy1I+WkYTBW3RC/G KykyvUZXann+H5aYbdigzxqOe4kicD6uDXzLxZNqXOSoHsCT4A/s7JDpO7nrpdfpW3P5 GYZmPyG8iQtfYm6whISXjS/ZNxVaqAohgb3oDHP/HNrmINWmMUnFo+W+r3B9unzkEF3M V7sA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710230104; x=1710834904; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1MdiWTyvmQ8k+0UnS+4iHEIsnW5J1mS8eY4/rmAJfhc=; b=LdduAF+/ywsOnWKERUZW5xN8N/HpXkIBbKa/YEGyDypUJen8Mz323xlkRNCmnUTzRv 4M/E/lTGRRQfSv+nHeqprf2Nw8Z+p1Sjp49U2h09CH6ZK7v4q9OsA8SQMQzbPhqNqo+3 yFJTLAPUKePn+WhWnkpHCoCGmEZ6hyPyOow84zkt0vWzgPJixxsOb9mkyEQWrLGAfK5R 7lg0ssInPyKvcVu4B6F0Fl8jq+lzdsOvCDVu/hyrsf5iIYMLmPvfMbYeo7+q5Z4c7Mq6 0Cnsrne6Vu5WW3OVaNlZt5YYwvEDJQvkND8r2PSA3hH75YtXvYQwxOw0vuPWvjHVTnaN zOLw== X-Gm-Message-State: AOJu0YztO+2ROBypCHDPsFr9QkCfiO/Ui0X07i6uBjt2XBwoF1CJIy9Y 9PFVqJXW7p5y4uCnkU+yFDCy7RMYetM4tE0Arv/jimjfKO5LWrWGUnqS8htybFURhqlqXFK/9Rl D3B8= X-Google-Smtp-Source: AGHT+IGc68V47gWwOErjzpN++yexTK859vuHSOA4l+Ip6lJvtAMcsdbsUnayyQEuU23sUZ2lPk/LTA== X-Received: by 2002:a5d:58f6:0:b0:33d:e74b:e3e with SMTP id f22-20020a5d58f6000000b0033de74b0e3emr6874596wrd.41.1710230104746; Tue, 12 Mar 2024 00:55:04 -0700 (PDT) Received: from linaro.. ([102.35.208.160]) by smtp.gmail.com with ESMTPSA id u12-20020a5d6acc000000b0033e7a499deasm6108795wrw.109.2024.03.12.00.55.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Mar 2024 00:55:04 -0700 (PDT) From: Pierrick Bouvier To: qemu-devel@nongnu.org Cc: Alexandre Iooss , Pierrick Bouvier , Mahmoud Mandour , Paolo Bonzini , =?utf-8?q?Alex_Benn=C3=A9e?= , Richard Henderson Subject: [PATCH v2 5/5] tests/plugin/inline: add test for condition callback Date: Tue, 12 Mar 2024 11:54:28 +0400 Message-Id: <20240312075428.244210-6-pierrick.bouvier@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240312075428.244210-1-pierrick.bouvier@linaro.org> References: <20240312075428.244210-1-pierrick.bouvier@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::429; envelope-from=pierrick.bouvier@linaro.org; helo=mail-wr1-x429.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Count number of tb and insn executed using a conditional callback. We ensure the callback has been called expected number of time (per vcpu). Signed-off-by: Pierrick Bouvier --- tests/plugin/inline.c | 89 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/tests/plugin/inline.c b/tests/plugin/inline.c index 30acc7a1838..771c246094e 100644 --- a/tests/plugin/inline.c +++ b/tests/plugin/inline.c @@ -20,8 +20,14 @@ typedef struct { uint64_t count_insn_inline; uint64_t count_mem; uint64_t count_mem_inline; + uint64_t tb_cond_num_trigger; + uint64_t tb_cond_track_count; + uint64_t insn_cond_num_trigger; + uint64_t insn_cond_track_count; } CPUCount; +static const uint64_t cond_trigger_limit = 100; + typedef struct { uint64_t data_insn; uint64_t data_tb; @@ -35,6 +41,10 @@ static qemu_plugin_u64 count_insn; static qemu_plugin_u64 count_insn_inline; static qemu_plugin_u64 count_mem; static qemu_plugin_u64 count_mem_inline; +static qemu_plugin_u64 tb_cond_num_trigger; +static qemu_plugin_u64 tb_cond_track_count; +static qemu_plugin_u64 insn_cond_num_trigger; +static qemu_plugin_u64 insn_cond_track_count; static struct qemu_plugin_scoreboard *data; static qemu_plugin_u64 data_insn; static qemu_plugin_u64 data_tb; @@ -56,12 +66,19 @@ static void stats_insn(void) const uint64_t per_vcpu = qemu_plugin_u64_sum(count_insn); const uint64_t inl_per_vcpu = qemu_plugin_u64_sum(count_insn_inline); + const uint64_t cond_num_trigger = + qemu_plugin_u64_sum(insn_cond_num_trigger); + const uint64_t cond_track_left = qemu_plugin_u64_sum(insn_cond_track_count); + const uint64_t conditional = + cond_num_trigger * cond_trigger_limit + cond_track_left; printf("insn: %" PRIu64 "\n", expected); printf("insn: %" PRIu64 " (per vcpu)\n", per_vcpu); printf("insn: %" PRIu64 " (per vcpu inline)\n", inl_per_vcpu); + printf("insn: %" PRIu64 " (cond cb)\n", conditional); g_assert(expected > 0); g_assert(per_vcpu == expected); g_assert(inl_per_vcpu == expected); + g_assert(conditional == expected); } static void stats_tb(void) @@ -70,12 +87,18 @@ static void stats_tb(void) const uint64_t per_vcpu = qemu_plugin_u64_sum(count_tb); const uint64_t inl_per_vcpu = qemu_plugin_u64_sum(count_tb_inline); + const uint64_t cond_num_trigger = qemu_plugin_u64_sum(tb_cond_num_trigger); + const uint64_t cond_track_left = qemu_plugin_u64_sum(tb_cond_track_count); + const uint64_t conditional = + cond_num_trigger * cond_trigger_limit + cond_track_left; printf("tb: %" PRIu64 "\n", expected); printf("tb: %" PRIu64 " (per vcpu)\n", per_vcpu); printf("tb: %" PRIu64 " (per vcpu inline)\n", inl_per_vcpu); + printf("tb: %" PRIu64 " (conditional cb)\n", conditional); g_assert(expected > 0); g_assert(per_vcpu == expected); g_assert(inl_per_vcpu == expected); + g_assert(conditional == expected); } static void stats_mem(void) @@ -104,14 +127,35 @@ static void plugin_exit(qemu_plugin_id_t id, void *udata) const uint64_t insn_inline = qemu_plugin_u64_get(count_insn_inline, i); const uint64_t mem = qemu_plugin_u64_get(count_mem, i); const uint64_t mem_inline = qemu_plugin_u64_get(count_mem_inline, i); - printf("cpu %d: tb (%" PRIu64 ", %" PRIu64 ") | " - "insn (%" PRIu64 ", %" PRIu64 ") | " + const uint64_t tb_cond_trigger = + qemu_plugin_u64_get(tb_cond_num_trigger, i); + const uint64_t tb_cond_left = + qemu_plugin_u64_get(tb_cond_track_count, i); + const uint64_t insn_cond_trigger = + qemu_plugin_u64_get(insn_cond_num_trigger, i); + const uint64_t insn_cond_left = + qemu_plugin_u64_get(insn_cond_track_count, i); + printf("cpu %d: tb (%" PRIu64 ", %" PRIu64 + ", %" PRIu64 " * %" PRIu64 " + %" PRIu64 + ") | " + "insn (%" PRIu64 ", %" PRIu64 + ", %" PRIu64 " * %" PRIu64 " + %" PRIu64 + ") | " "mem (%" PRIu64 ", %" PRIu64 ")" "\n", - i, tb, tb_inline, insn, insn_inline, mem, mem_inline); + i, + tb, tb_inline, + tb_cond_trigger, cond_trigger_limit, tb_cond_left, + insn, insn_inline, + insn_cond_trigger, cond_trigger_limit, insn_cond_left, + mem, mem_inline); g_assert(tb == tb_inline); g_assert(insn == insn_inline); g_assert(mem == mem_inline); + g_assert(tb_cond_trigger == tb / cond_trigger_limit); + g_assert(tb_cond_left == tb % cond_trigger_limit); + g_assert(insn_cond_trigger == insn / cond_trigger_limit); + g_assert(insn_cond_left == insn % cond_trigger_limit); } stats_tb(); @@ -132,6 +176,24 @@ static void vcpu_tb_exec(unsigned int cpu_index, void *udata) g_mutex_unlock(&tb_lock); } +static void vcpu_tb_cond_exec(unsigned int cpu_index, void *udata) +{ + g_assert(qemu_plugin_u64_get(tb_cond_track_count, cpu_index) == + cond_trigger_limit); + g_assert(qemu_plugin_u64_get(data_tb, cpu_index) == (uintptr_t) udata); + qemu_plugin_u64_set(tb_cond_track_count, cpu_index, 0); + qemu_plugin_u64_add(tb_cond_num_trigger, cpu_index, 1); +} + +static void vcpu_insn_cond_exec(unsigned int cpu_index, void *udata) +{ + g_assert(qemu_plugin_u64_get(insn_cond_track_count, cpu_index) == + cond_trigger_limit); + g_assert(qemu_plugin_u64_get(data_insn, cpu_index) == (uintptr_t) udata); + qemu_plugin_u64_set(insn_cond_track_count, cpu_index, 0); + qemu_plugin_u64_add(insn_cond_num_trigger, cpu_index, 1); +} + static void vcpu_insn_exec(unsigned int cpu_index, void *udata) { qemu_plugin_u64_add(count_insn, cpu_index, 1); @@ -163,6 +225,12 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( tb, QEMU_PLUGIN_INLINE_STORE_U64, data_tb, (uintptr_t) tb_store); + qemu_plugin_register_vcpu_tb_exec_inline_per_vcpu( + tb, QEMU_PLUGIN_INLINE_ADD_U64, tb_cond_track_count, 1); + qemu_plugin_register_vcpu_tb_exec_cond_cb( + tb, vcpu_tb_cond_exec, QEMU_PLUGIN_CB_NO_REGS, + QEMU_PLUGIN_COND_EQ, tb_cond_track_count, cond_trigger_limit, tb_store); + for (int idx = 0; idx < qemu_plugin_tb_n_insns(tb); ++idx) { struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, idx); void *insn_store = insn; @@ -176,6 +244,13 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( insn, QEMU_PLUGIN_INLINE_ADD_U64, count_insn_inline, 1); + qemu_plugin_register_vcpu_insn_exec_inline_per_vcpu( + insn, QEMU_PLUGIN_INLINE_ADD_U64, insn_cond_track_count, 1); + qemu_plugin_register_vcpu_insn_exec_cond_cb( + insn, vcpu_insn_cond_exec, QEMU_PLUGIN_CB_NO_REGS, + QEMU_PLUGIN_COND_EQ, insn_cond_track_count, cond_trigger_limit, + insn_store); + qemu_plugin_register_vcpu_mem_cb(insn, &vcpu_mem_access, QEMU_PLUGIN_CB_NO_REGS, QEMU_PLUGIN_MEM_RW, mem_store); @@ -207,6 +282,14 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qemu_info_t *info, counts, CPUCount, count_insn_inline); count_mem_inline = qemu_plugin_scoreboard_u64_in_struct( counts, CPUCount, count_mem_inline); + tb_cond_num_trigger = qemu_plugin_scoreboard_u64_in_struct( + counts, CPUCount, tb_cond_num_trigger); + tb_cond_track_count = qemu_plugin_scoreboard_u64_in_struct( + counts, CPUCount, tb_cond_track_count); + insn_cond_num_trigger = qemu_plugin_scoreboard_u64_in_struct( + counts, CPUCount, insn_cond_num_trigger); + insn_cond_track_count = qemu_plugin_scoreboard_u64_in_struct( + counts, CPUCount, insn_cond_track_count); data = qemu_plugin_scoreboard_new(sizeof(CPUData)); data_insn = qemu_plugin_scoreboard_u64_in_struct(data, CPUData, data_insn); data_tb = qemu_plugin_scoreboard_u64_in_struct(data, CPUData, data_tb);