From: "Emilio G. Cota" <cota@braap.org>
To: "Alex Bennée" <alex.bennee@linaro.org>
Cc: qemu-devel@nongnu.org,
"Pavel Dovgalyuk" <Pavel.Dovgaluk@ispras.ru>,
"Lluís Vilanova" <vilanova@ac.upc.edu>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Stefan Hajnoczi" <stefanha@gmail.com>,
"Richard Henderson" <richard.henderson@linaro.org>
Subject: Re: [Qemu-devel] [RFC 38/48] translator: implement 2-pass translation
Date: Tue, 27 Nov 2018 21:30:20 -0500 [thread overview]
Message-ID: <20181128023020.GA25013@flamenco> (raw)
In-Reply-To: <20181127190657.GB8956@flamenco>
On Tue, Nov 27, 2018 at 14:06:57 -0500, Emilio G. Cota wrote:
> On Tue, Nov 27, 2018 at 14:48:11 +0000, Alex Bennée wrote:
> > With a little tweaking to the TCG we could then insert
> > our instrumentation at the end of the pass with all the knowledge we
> > want to export to the plugin.
>
> After .translate_insn has returned for the last instruction, how
> do we insert the instrumentation that the plugin wants--say, a TB
> callback at the beginning of the TB, memory callbacks for the
> 2nd instruction, and an insn callback before the 3rd instruction
> executes?
>
> I don't see how we could achieve that with "a little tweaking"
> instead of a 2nd pass, but I'd love to be wrong =)
(snip)
> > I don't quite follow. When we've done all our translation into TCG ops
> > haven't we by definition defined the TB?
>
> Yes, that's precisely my point.
>
> The part that's missing is that once the TB is defined, we want to
> insert instrumentation. Unfortunately, the "TCG ops" we get after
> the 1st pass (no instrumentation), are very different from the list
> of "TCG ops" that we get after the 2nd pass (after having injected
> instrumentation). Could we get the same output of the 2nd pass,
> just by using the output of the 1st and the list of injection points?
> It's probably possible, but it seems very hard to do. (Think for
> instance of memory callbacks, and further the complication of when
> they use helpers).
>
> The only reasonable way to do this I think would be to leave behind
> "placeholder" TCG ops, that then we could scan to add further TCG ops.
> But you'll agree with me that the 2nd pass is simpler :P
It might not be that much simpler after all!
I am exploring the approach you suggested, that is IIUC to do a
single pass and then walk the list of Ops, adding (and
reordering) Ops based on what the plugins have requested.
Contrary to what I wrote earlier today (quoted above), this
approach seems quite promising, and certainly less ugly
than doing the 2 passes.
I just wrote some code to go over the list and add TB callbacks,
which go right before the first insn_start Op. The code is hack-ish
in that we first generate the TCG ops we need, which get added to
the end of the ops list, and then we go over those and move them
to where we want them to be (before insn_start, in this case).
But it works and it's less of a hack than doing the whole 2nd pass.
Insn callbacks will be trivial to implement this way; memory
callbacks should be harder because there are several qemu_ld/st
opcodes, but it should be doable; last, memory instrumentation
of helpers might actually be easier than with the 2 passes, because here
we just have to look for a Call TCG op to know whether a guest
instruction uses helpers, and if it does we can wrap the call
with the helpers to generate the setting/resetting of
CPUState.plugin_mem_cbs.
I'll try to do what's in the previous paragraph tomorrow -- I'm
appending what I did so far.
Thanks,
Emilio
---
diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index ee9e179e14..232f645cd4 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -18,6 +18,7 @@
#include "exec/gen-icount.h"
#include "exec/log.h"
#include "exec/translator.h"
+#include "exec/plugin-gen.h"
/* Pairs with tcg_clear_temp_count.
To be called by #TranslatorOps.{translate_insn,tb_stop} if
@@ -142,6 +143,11 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
gen_tb_end(db->tb, db->num_insns - bp_insn);
if (plugin_enabled) {
+ /* collect the plugins' instrumentation */
+ qemu_plugin_tb_trans_cb(cpu, &tcg_ctx->plugin_tb);
+ /* inject instrumentation */
+ qemu_plugin_gen_inject();
+ /* done */
tcg_ctx->plugin_insn = NULL;
}
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 75f182be37..cb5dbadc3c 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
+#include "qemu/queue.h"
#include "cpu.h"
#include "tcg/tcg.h"
#include "tcg/tcg-op.h"
@@ -169,8 +170,61 @@ static void gen_vcpu_udata_cb(struct qemu_plugin_dyn_cb *cb)
tcg_temp_free_i32(cpu_index);
}
-void qemu_plugin_gen_vcpu_udata_callbacks(struct qemu_plugin_dyn_cb_arr *arr)
+/* check that @a comes before @b */
+static inline void ops_check(const TCGOp *a, const TCGOp *b)
{
+ const TCGOp *op;
+ bool seen_a = false;
+ bool seen_b = false;
+
+ tcg_debug_assert(a != b);
+ QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
+ if (op == a) {
+ tcg_debug_assert(!seen_b);
+ seen_a = true;
+ } else if (op == b) {
+ tcg_debug_assert(seen_a);
+ seen_b = true;
+ break;
+ }
+ }
+}
+
+/*
+ * Move ops from @from to @dest.
+ * @from must come after @dest in the list.
+ */
+static void ops_move(TCGOp *dest, TCGOp *from)
+{
+ TCGOp *curr;
+
+#ifdef CONFIG_DEBUG_TCG
+ ops_check(dest, from);
+#endif
+
+ if (QTAILQ_NEXT(dest, link) == from) {
+ /* nothing to do */
+ return;
+ }
+ curr = from;
+ do {
+ TCGOp *next = QTAILQ_NEXT(curr, link);
+
+ /*
+ * This could be done more efficiently since (@from,end) will
+ * remain linked together, but most likely we just have a few
+ * elements, so this is simple enough.
+ */
+ QTAILQ_REMOVE(&tcg_ctx->ops, curr, link);
+ QTAILQ_INSERT_AFTER(&tcg_ctx->ops, dest, curr, link);
+ dest = curr;
+ curr = next;
+ } while (curr);
+}
+
+static void inject_vcpu_udata_callbacks(struct qemu_plugin_dyn_cb_arr *arr, TCGOp *dest)
+{
+ TCGOp *last_op = tcg_last_op();
size_t i;
for (i = 0; i < arr->n; i++) {
@@ -187,6 +241,10 @@ void qemu_plugin_gen_vcpu_udata_callbacks(struct qemu_plugin_dyn_cb_arr *arr)
g_assert_not_reached();
}
}
+ g_assert(tcg_last_op() != last_op);
+ last_op = QTAILQ_NEXT(last_op, link);
+ g_assert(last_op);
+ ops_move(dest, last_op);
}
/*
@@ -228,3 +286,26 @@ void qemu_plugin_gen_disable_mem_helpers(void)
plugin_mem_cbs));
tcg_temp_free_ptr(ptr);
}
+
+void qemu_plugin_gen_inject(void)
+{
+ struct qemu_plugin_tb *plugin_tb = &tcg_ctx->plugin_tb;
+
+ /* TB exec callbacks */
+ if (plugin_tb->cbs.n) {
+ TCGOp *op;
+
+ /* Insert the callbacks right before the first insn_start */
+ QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
+ if (op->opc == INDEX_op_insn_start) {
+ break;
+ }
+ }
+ /* a TB without insn_start? Something went wrong */
+ g_assert(op);
+ op = QTAILQ_PREV(op, TCGOpHead, link);
+ /* we should have called gen_tb_start before the 1st insn */
+ g_assert(op);
+ inject_vcpu_udata_callbacks(&plugin_tb->cbs, op);
+ }
+}
next prev parent reply other threads:[~2018-11-28 2:30 UTC|newest]
Thread overview: 132+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-25 17:20 [Qemu-devel] [RFC 00/48] Plugin support Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 01/48] cpu: introduce run_on_cpu_no_bql Emilio G. Cota
2018-11-14 11:30 ` Alex Bennée
2018-11-14 17:08 ` Emilio G. Cota
2018-11-14 18:23 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 02/48] trace: expand mem_info:size_shift to 3 bits Emilio G. Cota
2018-11-14 13:03 ` Alex Bennée
2018-11-14 17:17 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 03/48] tcg/README: fix typo s/afterwise/afterwards/ Emilio G. Cota
2018-11-14 13:03 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 04/48] exec: introduce qemu_xxhash{2,4,5,6,7} Emilio G. Cota
2018-11-14 13:04 ` [Qemu-devel] [RFC 04/48] exec: introduce qemu_xxhash{2, 4, 5, 6, 7} Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 05/48] include: move exec/tb-hash-xx.h to qemu/xxhash.h Emilio G. Cota
2018-11-14 13:05 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 06/48] tcg: use QHT for helper_table Emilio G. Cota
2018-11-14 14:41 ` Alex Bennée
2018-11-14 17:50 ` Emilio G. Cota
2018-11-14 16:11 ` Alex Bennée
2018-11-14 17:52 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 07/48] tcg: export TCGHelperInfo Emilio G. Cota
2018-11-14 16:12 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 08/48] tcg: export tcg_gen_runtime_helper Emilio G. Cota
2018-11-14 16:44 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 09/48] tcg: reset runtime helpers when flushing the code cache Emilio G. Cota
2018-11-14 17:01 ` Alex Bennée
2018-11-14 17:59 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 10/48] exec: export do_tb_flush Emilio G. Cota
2018-11-22 17:09 ` Alex Bennée
2018-11-23 23:19 ` Emilio G. Cota
2018-11-26 11:11 ` Alex Bennée
2018-11-26 23:56 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 11/48] atomic_template: fix indentation in GEN_ATOMIC_HELPER Emilio G. Cota
2018-11-22 17:09 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 12/48] atomic_template: define pre/post macros Emilio G. Cota
2018-11-22 17:12 ` Alex Bennée
2018-11-24 0:09 ` Emilio G. Cota
2018-11-26 11:21 ` Alex Bennée
2018-11-27 1:16 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 13/48] xxhash: add qemu_xxhash8 Emilio G. Cota
2018-11-22 17:15 ` Alex Bennée
2018-11-23 22:34 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 14/48] plugin: preliminary user-facing API Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 15/48] plugin: add core code Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 16/48] tcg: add plugin_mask to TB hash Emilio G. Cota
2018-11-23 16:52 ` Alex Bennée
2018-11-24 0:02 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 17/48] plugin-gen: add TCG code generation helpers Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 18/48] tcg: add memory callbacks for plugins (WIP) Emilio G. Cota
2018-11-23 16:55 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 19/48] translate-all: notify plugin code of tb_flush Emilio G. Cota
2018-11-23 17:00 ` Alex Bennée
2018-11-23 23:15 ` Emilio G. Cota
2018-11-26 11:02 ` Alex Bennée
2018-11-26 21:53 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 20/48] *-user: notify plugin of exit Emilio G. Cota
2018-11-23 17:01 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 21/48] *-user: plugin syscalls Emilio G. Cota
2018-11-23 17:04 ` Alex Bennée
2018-11-24 0:03 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 22/48] cpu: hook plugin vcpu events Emilio G. Cota
2018-11-23 17:10 ` Alex Bennée
2018-11-23 23:48 ` Emilio G. Cota
2018-11-26 11:17 ` Alex Bennée
2018-11-27 1:25 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 23/48] translator: add plugin_insn argument to translate_insn Emilio G. Cota
2018-11-26 14:52 ` Alex Bennée
2018-11-26 18:27 ` Richard Henderson
2018-11-26 18:56 ` Alex Bennée
2018-11-26 19:19 ` Richard Henderson
2018-11-26 19:07 ` Emilio G. Cota
2018-11-26 19:30 ` Richard Henderson
2018-11-27 1:38 ` Emilio G. Cota
2018-11-28 0:54 ` Emilio G. Cota
2018-11-28 1:12 ` Emilio G. Cota
2018-11-28 12:40 ` Alex Bennée
2018-11-28 14:43 ` Emilio G. Cota
2018-11-27 13:08 ` Pavel Dovgalyuk
2018-10-25 17:20 ` [Qemu-devel] [RFC 24/48] translator: add .ctx_base_offset and .ctx_size to TranslatorOps Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 25/48] target/arm: prepare for 2-pass translation Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 26/48] target/ppc: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 27/48] target/sh4: prepare for 2-pass translation (WIP) Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 28/48] target/i386: prepare for 2-pass translation Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 29/48] target/hppa: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 30/48] target/m68k: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 31/48] target/mips: prepare for 2-pass translation (WIP) Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 32/48] target/alpha: prepare for 2-pass translation Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 33/48] target/riscv: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 34/48] target/s390x: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 35/48] target/sparc: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 36/48] target/xtensa: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 37/48] target/openrisc: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 38/48] translator: implement " Emilio G. Cota
2018-11-26 15:16 ` Alex Bennée
2018-11-27 2:16 ` Emilio G. Cota
2018-11-27 14:48 ` Alex Bennée
2018-11-27 19:06 ` Emilio G. Cota
2018-11-28 2:30 ` Emilio G. Cota [this message]
2018-11-28 12:50 ` Alex Bennée
2018-11-28 15:03 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 39/48] plugin: add API symbols to qemu-plugins.symbols Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 40/48] plugin: let plugins control the virtual clock Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 41/48] configure: add --enable-plugins Emilio G. Cota
2018-11-27 12:11 ` Alex Bennée
2018-11-27 17:08 ` Emilio G. Cota
2018-11-27 12:43 ` Roman Bolshakov
2018-11-27 23:13 ` Emilio G. Cota
2018-11-28 10:43 ` Roman Bolshakov
2018-11-28 17:23 ` Emilio G. Cota
2018-11-29 9:57 ` Roman Bolshakov
2018-11-29 17:00 ` Emilio G. Cota
2018-11-29 17:49 ` Emilio G. Cota
2018-11-29 19:34 ` Roman Bolshakov
2018-10-25 17:20 ` [Qemu-devel] [RFC 42/48] vl: support -plugin option Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 43/48] linux-user: " Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 44/48] cpus: lockstep execution support Emilio G. Cota
2018-11-14 16:43 ` Alex Bennée
2018-11-14 18:33 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 45/48] plugin: " Emilio G. Cota
2018-11-27 18:20 ` Alex Bennée
2018-11-27 19:19 ` Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 46/48] plugin: add plugin-chan PCI device Emilio G. Cota
2018-10-25 17:20 ` [Qemu-devel] [RFC 47/48] plugin: support guest hooks Emilio G. Cota
2018-11-27 18:28 ` Alex Bennée
2018-10-25 17:20 ` [Qemu-devel] [RFC 48/48] plugin: add a couple of very simple examples Emilio G. Cota
2018-10-29 10:59 ` Pavel Dovgalyuk
2018-10-29 16:38 ` Emilio G. Cota
2018-11-28 11:28 ` Alex Bennée
2018-11-28 14:48 ` Emilio G. Cota
2018-11-29 20:45 ` Roman Bolshakov
2018-12-08 23:32 ` Emilio G. Cota
2018-10-29 9:48 ` [Qemu-devel] [RFC 00/48] Plugin support Pavel Dovgalyuk
2018-10-29 16:45 ` Emilio G. Cota
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181128023020.GA25013@flamenco \
--to=cota@braap.org \
--cc=Pavel.Dovgaluk@ispras.ru \
--cc=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=stefanha@gmail.com \
--cc=vilanova@ac.upc.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).