plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
/*
|
|
|
|
* plugin-gen.c - TCG-related bits of plugin infrastructure
|
|
|
|
*
|
|
|
|
* Copyright (C) 2018, Emilio G. Cota <cota@braap.org>
|
|
|
|
* License: GNU GPL, version 2 or later.
|
|
|
|
* See the COPYING file in the top-level directory.
|
|
|
|
*
|
|
|
|
* We support instrumentation at an instruction granularity. That is,
|
|
|
|
* if a plugin wants to instrument the memory accesses performed by a
|
|
|
|
* particular instruction, it can just do that instead of instrumenting
|
|
|
|
* all memory accesses. Thus, in order to do this we first have to
|
|
|
|
* translate a TB, so that plugins can decide what/where to instrument.
|
|
|
|
*
|
|
|
|
* Injecting the desired instrumentation could be done with a second
|
|
|
|
* translation pass that combined the instrumentation requests, but that
|
|
|
|
* would be ugly and inefficient since we would decode the guest code twice.
|
|
|
|
* Instead, during TB translation we add "empty" instrumentation calls for all
|
|
|
|
* possible instrumentation events, and then once we collect the instrumentation
|
|
|
|
* requests from plugins, we either "fill in" those empty events or remove them
|
|
|
|
* if they have no requests.
|
|
|
|
*
|
|
|
|
* When "filling in" an event we first copy the empty callback's TCG ops. This
|
|
|
|
* might seem unnecessary, but it is done to support an arbitrary number
|
|
|
|
* of callbacks per event. Take for example a regular instruction callback.
|
|
|
|
* We first generate a callback to an empty helper function. Then, if two
|
|
|
|
* plugins register one callback each for this instruction, we make two copies
|
|
|
|
* of the TCG ops generated for the empty callback, substituting the function
|
|
|
|
* pointer that points to the empty helper function with the plugins' desired
|
|
|
|
* callback functions. After that we remove the empty callback's ops.
|
|
|
|
*
|
|
|
|
* Note that the location in TCGOp.args[] of the pointer to a helper function
|
|
|
|
* varies across different guest and host architectures. Instead of duplicating
|
|
|
|
* the logic that figures this out, we rely on the fact that the empty
|
|
|
|
* callbacks point to empty functions that are unique pointers in the program.
|
|
|
|
* Thus, to find the right location we just have to look for a match in
|
|
|
|
* TCGOp.args[]. This is the main reason why we first copy an empty callback's
|
|
|
|
* TCG ops and then fill them in; regardless of whether we have one or many
|
|
|
|
* callbacks for that event, the logic to add all of them is the same.
|
|
|
|
*
|
|
|
|
* When generating more than one callback per event, we make a small
|
|
|
|
* optimization to avoid generating redundant operations. For instance, for the
|
|
|
|
* second and all subsequent callbacks of an event, we do not need to reload the
|
|
|
|
* CPU's index into a TCG temp, since the first callback did it already.
|
|
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
2024-02-27 14:43:28 +00:00
|
|
|
#include "qemu/plugin.h"
|
2024-03-15 20:33:49 +00:00
|
|
|
#include "qemu/log.h"
|
2023-04-02 04:22:06 +00:00
|
|
|
#include "cpu.h"
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
#include "tcg/tcg.h"
|
2023-02-25 08:45:43 +00:00
|
|
|
#include "tcg/tcg-temp-internal.h"
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
#include "tcg/tcg-op.h"
|
|
|
|
#include "exec/exec-all.h"
|
|
|
|
#include "exec/plugin-gen.h"
|
|
|
|
#include "exec/translator.h"
|
|
|
|
|
|
|
|
enum plugin_gen_from {
|
|
|
|
PLUGIN_GEN_FROM_TB,
|
|
|
|
PLUGIN_GEN_FROM_INSN,
|
|
|
|
PLUGIN_GEN_AFTER_INSN,
|
2024-03-15 09:47:07 +00:00
|
|
|
PLUGIN_GEN_AFTER_TB,
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
};
|
|
|
|
|
2021-03-19 19:01:32 +00:00
|
|
|
static void plugin_gen_empty_callback(enum plugin_gen_from from)
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
{
|
|
|
|
switch (from) {
|
|
|
|
case PLUGIN_GEN_AFTER_INSN:
|
2024-03-14 20:18:00 +00:00
|
|
|
case PLUGIN_GEN_FROM_TB:
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
case PLUGIN_GEN_FROM_INSN:
|
2024-03-14 21:27:35 +00:00
|
|
|
tcg_gen_plugin_cb(from);
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
|
|
|
|
void plugin_gen_disable_mem_helpers(void)
|
|
|
|
{
|
2024-03-15 09:47:07 +00:00
|
|
|
if (tcg_ctx->plugin_insn) {
|
|
|
|
tcg_gen_plugin_cb(PLUGIN_GEN_AFTER_TB);
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-14 21:27:35 +00:00
|
|
|
static void gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
|
|
|
|
struct qemu_plugin_insn *insn)
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
{
|
2024-03-14 21:27:35 +00:00
|
|
|
GArray *arr;
|
2024-03-15 02:02:19 +00:00
|
|
|
size_t len;
|
2024-03-14 21:27:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Tracking memory accesses performed from helpers requires extra work.
|
|
|
|
* If an instruction is emulated with helpers, we do two things:
|
|
|
|
* (1) copy the CB descriptors, and keep track of it so that they can be
|
|
|
|
* freed later on, and (2) point CPUState.plugin_mem_cbs to the
|
|
|
|
* descriptors, so that we can read them at run-time
|
|
|
|
* (i.e. when the helper executes).
|
|
|
|
* This run-time access is performed from qemu_plugin_vcpu_mem_cb.
|
|
|
|
*
|
|
|
|
* Note that plugin_gen_disable_mem_helpers undoes (2). Since it
|
|
|
|
* is possible that the code we generate after the instruction is
|
|
|
|
* dead, we also add checks before generating tb_exit etc.
|
|
|
|
*/
|
|
|
|
if (!insn->calls_helpers) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-15 02:02:19 +00:00
|
|
|
if (!insn->mem_cbs || !insn->mem_cbs->len) {
|
2024-03-14 21:27:35 +00:00
|
|
|
insn->mem_helper = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
insn->mem_helper = true;
|
|
|
|
ptb->mem_helper = true;
|
|
|
|
|
2024-03-15 02:02:19 +00:00
|
|
|
/*
|
|
|
|
* TODO: It seems like we should be able to use ref/unref
|
|
|
|
* to avoid needing to actually copy this array.
|
|
|
|
* Alternately, perhaps we could allocate new memory adjacent
|
|
|
|
* to the TranslationBlock itself, so that we do not have to
|
|
|
|
* actively manage the lifetime after this.
|
|
|
|
*/
|
|
|
|
len = insn->mem_cbs->len;
|
2024-03-14 21:27:35 +00:00
|
|
|
arr = g_array_sized_new(false, false,
|
2024-03-15 02:02:19 +00:00
|
|
|
sizeof(struct qemu_plugin_dyn_cb), len);
|
|
|
|
memcpy(arr->data, insn->mem_cbs->data,
|
|
|
|
len * sizeof(struct qemu_plugin_dyn_cb));
|
2024-03-14 21:27:35 +00:00
|
|
|
qemu_plugin_add_dyn_cb_arr(arr);
|
|
|
|
|
|
|
|
tcg_gen_st_ptr(tcg_constant_ptr((intptr_t)arr), tcg_env,
|
|
|
|
offsetof(CPUState, plugin_mem_cbs) -
|
|
|
|
offsetof(ArchCPU, env));
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
}
|
|
|
|
|
2024-03-15 09:47:07 +00:00
|
|
|
static void gen_disable_mem_helper(void)
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
{
|
2024-03-15 09:47:07 +00:00
|
|
|
tcg_gen_st_ptr(tcg_constant_ptr(0), tcg_env,
|
|
|
|
offsetof(CPUState, plugin_mem_cbs) -
|
|
|
|
offsetof(ArchCPU, env));
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
}
|
|
|
|
|
2024-03-14 20:18:00 +00:00
|
|
|
static void gen_udata_cb(struct qemu_plugin_dyn_cb *cb)
|
|
|
|
{
|
|
|
|
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
|
|
|
|
|
|
|
|
tcg_gen_ld_i32(cpu_index, tcg_env,
|
|
|
|
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
|
|
|
|
tcg_gen_call2(cb->regular.f.vcpu_udata, cb->regular.info, NULL,
|
|
|
|
tcgv_i32_temp(cpu_index),
|
|
|
|
tcgv_ptr_temp(tcg_constant_ptr(cb->userp)));
|
|
|
|
tcg_temp_free_i32(cpu_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void gen_inline_cb(struct qemu_plugin_dyn_cb *cb)
|
|
|
|
{
|
|
|
|
GArray *arr = cb->inline_insn.entry.score->data;
|
|
|
|
size_t offset = cb->inline_insn.entry.offset;
|
|
|
|
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
|
|
|
|
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));
|
|
|
|
tcg_gen_muli_i32(cpu_index, cpu_index, g_array_get_element_size(arr));
|
|
|
|
tcg_gen_ext_i32_ptr(ptr, cpu_index);
|
|
|
|
tcg_temp_free_i32(cpu_index);
|
|
|
|
|
|
|
|
tcg_gen_addi_ptr(ptr, ptr, (intptr_t)arr->data);
|
|
|
|
tcg_gen_ld_i64(val, ptr, offset);
|
|
|
|
tcg_gen_addi_i64(val, val, cb->inline_insn.imm);
|
|
|
|
tcg_gen_st_i64(val, ptr, offset);
|
|
|
|
|
|
|
|
tcg_temp_free_i64(val);
|
|
|
|
tcg_temp_free_ptr(ptr);
|
|
|
|
}
|
|
|
|
|
2024-03-14 23:02:32 +00:00
|
|
|
static void gen_mem_cb(struct qemu_plugin_dyn_cb *cb,
|
|
|
|
qemu_plugin_meminfo_t meminfo, TCGv_i64 addr)
|
|
|
|
{
|
|
|
|
TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
|
|
|
|
|
|
|
|
tcg_gen_ld_i32(cpu_index, tcg_env,
|
|
|
|
-offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
|
|
|
|
tcg_gen_call4(cb->regular.f.vcpu_mem, cb->regular.info, NULL,
|
|
|
|
tcgv_i32_temp(cpu_index),
|
|
|
|
tcgv_i32_temp(tcg_constant_i32(meminfo)),
|
|
|
|
tcgv_i64_temp(addr),
|
|
|
|
tcgv_ptr_temp(tcg_constant_ptr(cb->userp)));
|
|
|
|
tcg_temp_free_i32(cpu_index);
|
|
|
|
}
|
|
|
|
|
2024-03-15 21:06:57 +00:00
|
|
|
static void inject_cb(struct qemu_plugin_dyn_cb *cb)
|
|
|
|
|
|
|
|
{
|
|
|
|
switch (cb->type) {
|
|
|
|
case PLUGIN_CB_REGULAR:
|
|
|
|
gen_udata_cb(cb);
|
|
|
|
break;
|
|
|
|
case PLUGIN_CB_INLINE:
|
|
|
|
gen_inline_cb(cb);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void inject_mem_cb(struct qemu_plugin_dyn_cb *cb,
|
|
|
|
enum qemu_plugin_mem_rw rw,
|
|
|
|
qemu_plugin_meminfo_t meminfo, TCGv_i64 addr)
|
|
|
|
{
|
|
|
|
if (cb->rw & rw) {
|
|
|
|
switch (cb->type) {
|
|
|
|
case PLUGIN_CB_MEM_REGULAR:
|
|
|
|
gen_mem_cb(cb, meminfo, addr);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
inject_cb(cb);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-24 18:01:23 +00:00
|
|
|
static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
{
|
2024-03-14 17:09:57 +00:00
|
|
|
TCGOp *op, *next;
|
2021-09-17 16:23:32 +00:00
|
|
|
int insn_idx = -1;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
|
2024-03-15 20:33:49 +00:00
|
|
|
if (unlikely(qemu_loglevel_mask(LOG_TB_OP_PLUGIN)
|
|
|
|
&& qemu_log_in_addr_range(plugin_tb->vaddr))) {
|
|
|
|
FILE *logfile = qemu_log_trylock();
|
|
|
|
if (logfile) {
|
|
|
|
fprintf(logfile, "OP before plugin injection:\n");
|
|
|
|
tcg_dump_ops(tcg_ctx, logfile, false);
|
|
|
|
fprintf(logfile, "\n");
|
|
|
|
qemu_log_unlock(logfile);
|
|
|
|
}
|
|
|
|
}
|
2021-09-17 16:23:32 +00:00
|
|
|
|
2024-03-14 17:09:57 +00:00
|
|
|
/*
|
|
|
|
* While injecting code, we cannot afford to reuse any ebb temps
|
|
|
|
* that might be live within the existing opcode stream.
|
|
|
|
* The simplest solution is to release them all and create new.
|
|
|
|
*/
|
|
|
|
memset(tcg_ctx->free_temps, 0, sizeof(tcg_ctx->free_temps));
|
|
|
|
|
|
|
|
QTAILQ_FOREACH_SAFE(op, &tcg_ctx->ops, link, next) {
|
2021-09-17 16:23:32 +00:00
|
|
|
switch (op->opc) {
|
|
|
|
case INDEX_op_insn_start:
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
insn_idx++;
|
2021-09-17 16:23:32 +00:00
|
|
|
break;
|
2024-03-14 17:09:57 +00:00
|
|
|
|
|
|
|
case INDEX_op_plugin_cb:
|
|
|
|
{
|
|
|
|
enum plugin_gen_from from = op->args[0];
|
|
|
|
struct qemu_plugin_insn *insn = NULL;
|
2024-03-14 20:18:00 +00:00
|
|
|
const GArray *cbs;
|
|
|
|
int i, n;
|
2024-03-14 17:09:57 +00:00
|
|
|
|
|
|
|
if (insn_idx >= 0) {
|
|
|
|
insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
tcg_ctx->emit_before_op = op;
|
|
|
|
|
|
|
|
switch (from) {
|
2024-03-15 09:47:07 +00:00
|
|
|
case PLUGIN_GEN_AFTER_TB:
|
|
|
|
if (plugin_tb->mem_helper) {
|
|
|
|
gen_disable_mem_helper();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2024-03-14 17:09:57 +00:00
|
|
|
case PLUGIN_GEN_AFTER_INSN:
|
|
|
|
assert(insn != NULL);
|
2024-03-15 09:47:07 +00:00
|
|
|
if (insn->mem_helper) {
|
|
|
|
gen_disable_mem_helper();
|
|
|
|
}
|
2024-03-14 17:09:57 +00:00
|
|
|
break;
|
2024-03-14 20:18:00 +00:00
|
|
|
|
|
|
|
case PLUGIN_GEN_FROM_TB:
|
|
|
|
assert(insn == NULL);
|
|
|
|
|
2024-03-15 02:02:19 +00:00
|
|
|
cbs = plugin_tb->cbs;
|
2024-03-14 20:18:00 +00:00
|
|
|
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
|
2024-03-15 21:06:57 +00:00
|
|
|
inject_cb(
|
|
|
|
&g_array_index(cbs, struct qemu_plugin_dyn_cb, i));
|
2024-03-14 20:18:00 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2024-03-14 21:27:35 +00:00
|
|
|
case PLUGIN_GEN_FROM_INSN:
|
|
|
|
assert(insn != NULL);
|
|
|
|
|
|
|
|
gen_enable_mem_helper(plugin_tb, insn);
|
|
|
|
|
2024-03-15 02:02:19 +00:00
|
|
|
cbs = insn->insn_cbs;
|
2024-03-14 21:27:35 +00:00
|
|
|
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
|
2024-03-15 21:06:57 +00:00
|
|
|
inject_cb(
|
|
|
|
&g_array_index(cbs, struct qemu_plugin_dyn_cb, i));
|
2024-03-14 21:27:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2024-03-14 17:09:57 +00:00
|
|
|
default:
|
|
|
|
g_assert_not_reached();
|
|
|
|
}
|
|
|
|
|
|
|
|
tcg_ctx->emit_before_op = NULL;
|
|
|
|
tcg_op_remove(tcg_ctx, op);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-03-14 23:02:32 +00:00
|
|
|
case INDEX_op_plugin_mem_cb:
|
2021-09-17 16:23:32 +00:00
|
|
|
{
|
2024-03-14 23:02:32 +00:00
|
|
|
TCGv_i64 addr = temp_tcgv_i64(arg_temp(op->args[0]));
|
|
|
|
qemu_plugin_meminfo_t meminfo = op->args[1];
|
2024-03-15 21:06:57 +00:00
|
|
|
enum qemu_plugin_mem_rw rw =
|
|
|
|
(qemu_plugin_mem_is_store(meminfo)
|
|
|
|
? QEMU_PLUGIN_MEM_W : QEMU_PLUGIN_MEM_R);
|
2024-03-14 23:02:32 +00:00
|
|
|
struct qemu_plugin_insn *insn;
|
|
|
|
const GArray *cbs;
|
2024-03-15 21:06:57 +00:00
|
|
|
int i, n;
|
2021-09-17 16:23:32 +00:00
|
|
|
|
2024-03-14 23:02:32 +00:00
|
|
|
assert(insn_idx >= 0);
|
|
|
|
insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
|
2021-09-17 16:23:32 +00:00
|
|
|
|
2024-03-14 23:02:32 +00:00
|
|
|
tcg_ctx->emit_before_op = op;
|
|
|
|
|
2024-03-15 02:02:19 +00:00
|
|
|
cbs = insn->mem_cbs;
|
2024-03-14 23:02:32 +00:00
|
|
|
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
|
2024-03-15 21:06:57 +00:00
|
|
|
inject_mem_cb(&g_array_index(cbs, struct qemu_plugin_dyn_cb, i),
|
|
|
|
rw, meminfo, addr);
|
2021-09-17 16:23:32 +00:00
|
|
|
}
|
2024-03-14 23:02:32 +00:00
|
|
|
|
|
|
|
tcg_ctx->emit_before_op = NULL;
|
|
|
|
tcg_op_remove(tcg_ctx, op);
|
2021-09-17 16:23:32 +00:00
|
|
|
break;
|
|
|
|
}
|
2024-03-14 23:02:32 +00:00
|
|
|
|
2021-09-17 16:23:32 +00:00
|
|
|
default:
|
|
|
|
/* plugins don't care about any other ops */
|
|
|
|
break;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-12 16:15:15 +00:00
|
|
|
bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
|
|
|
|
bool mem_only)
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
{
|
|
|
|
bool ret = false;
|
|
|
|
|
2024-02-27 14:43:28 +00:00
|
|
|
if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_state->event_mask)) {
|
2022-02-04 20:43:35 +00:00
|
|
|
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
|
|
|
|
|
|
|
/* reset callbacks */
|
2024-03-15 02:02:19 +00:00
|
|
|
if (ptb->cbs) {
|
|
|
|
g_array_set_size(ptb->cbs, 0);
|
2022-02-04 20:43:35 +00:00
|
|
|
}
|
|
|
|
ptb->n = 0;
|
|
|
|
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
ret = true;
|
|
|
|
|
2022-08-12 16:15:15 +00:00
|
|
|
ptb->vaddr = db->pc_first;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
ptb->vaddr2 = -1;
|
2022-08-12 16:15:15 +00:00
|
|
|
ptb->haddr1 = db->host_addr[0];
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
ptb->haddr2 = NULL;
|
2021-02-13 13:03:22 +00:00
|
|
|
ptb->mem_only = mem_only;
|
2023-01-24 18:01:23 +00:00
|
|
|
ptb->mem_helper = false;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
|
|
|
|
plugin_gen_empty_callback(PLUGIN_GEN_FROM_TB);
|
|
|
|
}
|
2022-02-04 20:43:35 +00:00
|
|
|
|
|
|
|
tcg_ctx->plugin_insn = NULL;
|
|
|
|
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void plugin_gen_insn_start(CPUState *cpu, const DisasContextBase *db)
|
|
|
|
{
|
|
|
|
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
2024-03-15 05:27:28 +00:00
|
|
|
struct qemu_plugin_insn *insn;
|
|
|
|
size_t n = db->num_insns;
|
|
|
|
vaddr pc;
|
|
|
|
|
|
|
|
assert(n >= 1);
|
|
|
|
ptb->n = n;
|
|
|
|
if (n <= ptb->insns->len) {
|
|
|
|
insn = g_ptr_array_index(ptb->insns, n - 1);
|
|
|
|
g_byte_array_set_size(insn->data, 0);
|
|
|
|
} else {
|
|
|
|
assert(n - 1 == ptb->insns->len);
|
|
|
|
insn = g_new0(struct qemu_plugin_insn, 1);
|
|
|
|
insn->data = g_byte_array_sized_new(4);
|
|
|
|
g_ptr_array_add(ptb->insns, insn);
|
|
|
|
}
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
|
2024-03-15 05:27:28 +00:00
|
|
|
tcg_ctx->plugin_insn = insn;
|
|
|
|
insn->calls_helpers = false;
|
|
|
|
insn->mem_helper = false;
|
|
|
|
if (insn->insn_cbs) {
|
|
|
|
g_array_set_size(insn->insn_cbs, 0);
|
|
|
|
}
|
|
|
|
if (insn->mem_cbs) {
|
|
|
|
g_array_set_size(insn->mem_cbs, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
pc = db->pc_next;
|
|
|
|
insn->vaddr = pc;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Detect page crossing to get the new host address.
|
|
|
|
* Note that we skip this when haddr1 == NULL, e.g. when we're
|
|
|
|
* fetching instructions from a region not backed by RAM.
|
|
|
|
*/
|
2022-08-12 16:15:15 +00:00
|
|
|
if (ptb->haddr1 == NULL) {
|
2024-03-15 05:27:28 +00:00
|
|
|
insn->haddr = NULL;
|
2022-08-12 16:15:15 +00:00
|
|
|
} else if (is_same_page(db, db->pc_next)) {
|
2024-03-15 05:27:28 +00:00
|
|
|
insn->haddr = ptb->haddr1 + pc - ptb->vaddr;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
} else {
|
2022-08-12 16:15:15 +00:00
|
|
|
if (ptb->vaddr2 == -1) {
|
|
|
|
ptb->vaddr2 = TARGET_PAGE_ALIGN(db->pc_first);
|
2023-09-14 00:22:49 +00:00
|
|
|
get_page_addr_code_hostp(cpu_env(cpu), ptb->vaddr2, &ptb->haddr2);
|
2022-08-12 16:15:15 +00:00
|
|
|
}
|
2024-03-15 05:27:28 +00:00
|
|
|
insn->haddr = ptb->haddr2 + pc - ptb->vaddr2;
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
}
|
2024-03-15 05:27:28 +00:00
|
|
|
|
|
|
|
plugin_gen_empty_callback(PLUGIN_GEN_FROM_INSN);
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void plugin_gen_insn_end(void)
|
|
|
|
{
|
|
|
|
plugin_gen_empty_callback(PLUGIN_GEN_AFTER_INSN);
|
|
|
|
}
|
|
|
|
|
2022-02-04 20:43:35 +00:00
|
|
|
/*
|
|
|
|
* There are cases where we never get to finalise a translation - for
|
|
|
|
* example a page fault during translation. As a result we shouldn't
|
|
|
|
* do any clean-up here and make sure things are reset in
|
|
|
|
* plugin_gen_tb_start.
|
|
|
|
*/
|
2023-10-09 16:41:01 +00:00
|
|
|
void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
{
|
|
|
|
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
|
|
|
|
|
2023-10-09 16:41:01 +00:00
|
|
|
/* translator may have removed instructions, update final count */
|
|
|
|
g_assert(num_insns <= ptb->n);
|
|
|
|
ptb->n = num_insns;
|
|
|
|
|
plugin-gen: add module for TCG-related code
We first inject empty instrumentation from translator_loop.
After translation, we go through the plugins to see what
they want to register for, filling in the empty instrumentation.
If if turns out that some instrumentation remains unused, we
remove it.
This approach supports the following features:
- Inlining TCG code for simple operations. Note that we do not
export TCG ops to plugins. Instead, we give them a C API to
insert inlined ops. So far we only support adding an immediate
to a u64, e.g. to count events.
- "Direct" callbacks. These are callbacks that do not go via
a helper. Instead, the helper is defined at run-time, so that
the plugin code is directly called from TCG. This makes direct
callbacks as efficient as possible; they are therefore used
for very frequent events, e.g. memory callbacks.
- Passing the host address to memory callbacks. Most of this
is implemented in a later patch though.
- Instrumentation of memory accesses performed from helpers.
See the corresponding comment, as well as a later patch.
Signed-off-by: Emilio G. Cota <cota@braap.org>
[AJB: add alloc_tcg_plugin_context, use glib, rm hwaddr]
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
2018-12-07 20:33:56 +00:00
|
|
|
/* collect instrumentation requests */
|
|
|
|
qemu_plugin_tb_trans_cb(cpu, ptb);
|
|
|
|
|
|
|
|
/* inject the instrumentation at the appropriate places */
|
|
|
|
plugin_gen_inject(ptb);
|
|
|
|
}
|