* [PATCH v3 00/20] Rewrite plugin code generation
@ 2024-04-24 23:02 Richard Henderson
2024-04-24 23:02 ` [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained Richard Henderson
` (19 more replies)
0 siblings, 20 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel
Patches 6 & 7 still lack review.
Changes for v3:
- Rebase.
r~
Richard Henderson (20):
tcg: Make tcg/helper-info.h self-contained
tcg: Pass function pointer to tcg_gen_call*
plugins: Zero new qemu_plugin_dyn_cb entries
plugins: Move function pointer in qemu_plugin_dyn_cb
plugins: Create TCGHelperInfo for all out-of-line callbacks
plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN
plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB
plugins: Add PLUGIN_GEN_AFTER_TB
plugins: Use emit_before_op for PLUGIN_GEN_FROM_INSN
plugins: Use emit_before_op for PLUGIN_GEN_FROM_MEM
plugins: Remove plugin helpers
tcg: Remove TCG_CALL_PLUGIN
tcg: Remove INDEX_op_plugin_cb_{start,end}
plugins: Simplify callback queues
plugins: Introduce PLUGIN_CB_MEM_REGULAR
plugins: Replace pr_ops with a proper debug dump flag
plugins: Split out common cb expanders
plugins: Merge qemu_plugin_tb_insn_get to plugin-gen.c
plugins: Inline plugin_gen_empty_callback
plugins: Update the documentation block for plugin-gen.c
accel/tcg/plugin-helpers.h | 5 -
include/exec/helper-gen-common.h | 4 -
include/exec/helper-proto-common.h | 4 -
include/exec/plugin-gen.h | 4 -
include/qemu/log.h | 1 +
include/qemu/plugin.h | 67 +-
include/tcg/helper-info.h | 3 +
include/tcg/tcg-op-common.h | 4 +-
include/tcg/tcg-opc.h | 4 +-
include/tcg/tcg.h | 26 +-
include/exec/helper-gen.h.inc | 24 +-
accel/tcg/plugin-gen.c | 1007 +++++++---------------------
plugins/api.c | 26 +-
plugins/core.c | 61 +-
tcg/tcg-op-ldst.c | 6 +-
tcg/tcg-op.c | 8 +-
tcg/tcg.c | 78 ++-
tcg/tci.c | 1 +
util/log.c | 4 +
19 files changed, 399 insertions(+), 938 deletions(-)
delete mode 100644 accel/tcg/plugin-helpers.h
--
2.34.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-29 10:57 ` Philippe Mathieu-Daudé
2024-04-24 23:02 ` [PATCH v3 02/20] tcg: Pass function pointer to tcg_gen_call* Richard Henderson
` (18 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
Move MAX_CALL_IARGS from tcg.h and include for
the define of TCG_TARGET_REG_BITS.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/helper-info.h | 3 +++
include/tcg/tcg.h | 2 --
tcg/tci.c | 1 +
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/tcg/helper-info.h b/include/tcg/helper-info.h
index 7c27d6164a..909fe73afa 100644
--- a/include/tcg/helper-info.h
+++ b/include/tcg/helper-info.h
@@ -12,6 +12,9 @@
#ifdef CONFIG_TCG_INTERPRETER
#include <ffi.h>
#endif
+#include "tcg-target-reg-bits.h"
+
+#define MAX_CALL_IARGS 7
/*
* Describe the calling convention of a given argument type.
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 05a1912f8a..e4c598428d 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -39,8 +39,6 @@
/* XXX: make safe guess about sizes */
#define MAX_OP_PER_INSTR 266
-#define MAX_CALL_IARGS 7
-
#define CPU_TEMP_BUF_NLONGS 128
#define TCG_STATIC_FRAME_SIZE (CPU_TEMP_BUF_NLONGS * sizeof(long))
diff --git a/tcg/tci.c b/tcg/tci.c
index 39adcb7d82..3afb223528 100644
--- a/tcg/tci.c
+++ b/tcg/tci.c
@@ -19,6 +19,7 @@
#include "qemu/osdep.h"
#include "tcg/tcg.h"
+#include "tcg/helper-info.h"
#include "tcg/tcg-ldst.h"
#include <ffi.h>
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 02/20] tcg: Pass function pointer to tcg_gen_call*
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
2024-04-24 23:02 ` [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-29 11:00 ` Philippe Mathieu-Daudé
2024-04-24 23:02 ` [PATCH v3 03/20] plugins: Zero new qemu_plugin_dyn_cb entries Richard Henderson
` (17 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
For normal helpers, read the function pointer from the
structure earlier. For plugins, this will allow the
function pointer to come from elsewhere.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg.h | 21 +++++++++-------
include/exec/helper-gen.h.inc | 24 ++++++++++++-------
tcg/tcg.c | 45 +++++++++++++++++++----------------
3 files changed, 52 insertions(+), 38 deletions(-)
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index e4c598428d..8d9f6585ff 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -852,19 +852,22 @@ typedef struct TCGTargetOpDef {
bool tcg_op_supported(TCGOpcode op);
-void tcg_gen_call0(TCGHelperInfo *, TCGTemp *ret);
-void tcg_gen_call1(TCGHelperInfo *, TCGTemp *ret, TCGTemp *);
-void tcg_gen_call2(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *);
-void tcg_gen_call3(TCGHelperInfo *, TCGTemp *ret, TCGTemp *,
+void tcg_gen_call0(void *func, TCGHelperInfo *, TCGTemp *ret);
+void tcg_gen_call1(void *func, TCGHelperInfo *, TCGTemp *ret, TCGTemp *);
+void tcg_gen_call2(void *func, TCGHelperInfo *, TCGTemp *ret,
TCGTemp *, TCGTemp *);
-void tcg_gen_call4(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
- TCGTemp *, TCGTemp *);
-void tcg_gen_call5(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
+void tcg_gen_call3(void *func, TCGHelperInfo *, TCGTemp *ret,
TCGTemp *, TCGTemp *, TCGTemp *);
-void tcg_gen_call6(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
+void tcg_gen_call4(void *func, TCGHelperInfo *, TCGTemp *ret,
TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *);
-void tcg_gen_call7(TCGHelperInfo *, TCGTemp *ret, TCGTemp *, TCGTemp *,
+void tcg_gen_call5(void *func, TCGHelperInfo *, TCGTemp *ret,
TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *);
+void tcg_gen_call6(void *func, TCGHelperInfo *, TCGTemp *ret,
+ TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *,
+ TCGTemp *, TCGTemp *);
+void tcg_gen_call7(void *func, TCGHelperInfo *, TCGTemp *ret,
+ TCGTemp *, TCGTemp *, TCGTemp *, TCGTemp *,
+ TCGTemp *, TCGTemp *, TCGTemp *);
TCGOp *tcg_emit_op(TCGOpcode opc, unsigned nargs);
void tcg_op_remove(TCGContext *s, TCGOp *op);
diff --git a/include/exec/helper-gen.h.inc b/include/exec/helper-gen.h.inc
index c009641517..f7eb59b6c1 100644
--- a/include/exec/helper-gen.h.inc
+++ b/include/exec/helper-gen.h.inc
@@ -14,7 +14,8 @@
extern TCGHelperInfo glue(helper_info_, name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl0(ret)) \
{ \
- tcg_gen_call0(&glue(helper_info_, name), dh_retvar(ret)); \
+ tcg_gen_call0(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret)); \
}
#define DEF_HELPER_FLAGS_1(name, flags, ret, t1) \
@@ -22,7 +23,8 @@ extern TCGHelperInfo glue(helper_info_, name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1)) \
{ \
- tcg_gen_call1(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call1(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1)); \
}
@@ -31,7 +33,8 @@ extern TCGHelperInfo glue(helper_info_, name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2)) \
{ \
- tcg_gen_call2(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call2(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2)); \
}
@@ -40,7 +43,8 @@ extern TCGHelperInfo glue(helper_info_, name); \
static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3)) \
{ \
- tcg_gen_call3(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call3(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3)); \
}
@@ -50,7 +54,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), \
dh_arg_decl(t3, 3), dh_arg_decl(t4, 4)) \
{ \
- tcg_gen_call4(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call4(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), \
dh_arg(t3, 3), dh_arg(t4, 4)); \
}
@@ -61,7 +66,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5)) \
{ \
- tcg_gen_call5(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call5(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
dh_arg(t4, 4), dh_arg(t5, 5)); \
}
@@ -72,7 +78,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t1, 1), dh_arg_decl(t2, 2), dh_arg_decl(t3, 3), \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6)) \
{ \
- tcg_gen_call6(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call6(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6)); \
}
@@ -84,7 +91,8 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl(ret) \
dh_arg_decl(t4, 4), dh_arg_decl(t5, 5), dh_arg_decl(t6, 6), \
dh_arg_decl(t7, 7)) \
{ \
- tcg_gen_call7(&glue(helper_info_, name), dh_retvar(ret), \
+ tcg_gen_call7(glue(helper_info_,name).func, \
+ &glue(helper_info_,name), dh_retvar(ret), \
dh_arg(t1, 1), dh_arg(t2, 2), dh_arg(t3, 3), \
dh_arg(t4, 4), dh_arg(t5, 5), dh_arg(t6, 6), \
dh_arg(t7, 7)); \
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0c0bb9d169..0bf218314b 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2251,7 +2251,8 @@ bool tcg_op_supported(TCGOpcode op)
static TCGOp *tcg_op_alloc(TCGOpcode opc, unsigned nargs);
-static void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, TCGTemp **args)
+static void tcg_gen_callN(void *func, TCGHelperInfo *info,
+ TCGTemp *ret, TCGTemp **args)
{
TCGv_i64 extend_free[MAX_CALL_IARGS];
int n_extend = 0;
@@ -2329,7 +2330,7 @@ static void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, TCGTemp **args)
g_assert_not_reached();
}
}
- op->args[pi++] = (uintptr_t)info->func;
+ op->args[pi++] = (uintptr_t)func;
op->args[pi++] = (uintptr_t)info;
tcg_debug_assert(pi == total_args);
@@ -2345,56 +2346,58 @@ static void tcg_gen_callN(TCGHelperInfo *info, TCGTemp *ret, TCGTemp **args)
}
}
-void tcg_gen_call0(TCGHelperInfo *info, TCGTemp *ret)
+void tcg_gen_call0(void *func, TCGHelperInfo *info, TCGTemp *ret)
{
- tcg_gen_callN(info, ret, NULL);
+ tcg_gen_callN(func, info, ret, NULL);
}
-void tcg_gen_call1(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1)
+void tcg_gen_call1(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1)
{
- tcg_gen_callN(info, ret, &t1);
+ tcg_gen_callN(func, info, ret, &t1);
}
-void tcg_gen_call2(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, TCGTemp *t2)
+void tcg_gen_call2(void *func, TCGHelperInfo *info, TCGTemp *ret,
+ TCGTemp *t1, TCGTemp *t2)
{
TCGTemp *args[2] = { t1, t2 };
- tcg_gen_callN(info, ret, args);
+ tcg_gen_callN(func, info, ret, args);
}
-void tcg_gen_call3(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
- TCGTemp *t2, TCGTemp *t3)
+void tcg_gen_call3(void *func, TCGHelperInfo *info, TCGTemp *ret,
+ TCGTemp *t1, TCGTemp *t2, TCGTemp *t3)
{
TCGTemp *args[3] = { t1, t2, t3 };
- tcg_gen_callN(info, ret, args);
+ tcg_gen_callN(func, info, ret, args);
}
-void tcg_gen_call4(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
- TCGTemp *t2, TCGTemp *t3, TCGTemp *t4)
+void tcg_gen_call4(void *func, TCGHelperInfo *info, TCGTemp *ret,
+ TCGTemp *t1, TCGTemp *t2, TCGTemp *t3, TCGTemp *t4)
{
TCGTemp *args[4] = { t1, t2, t3, t4 };
- tcg_gen_callN(info, ret, args);
+ tcg_gen_callN(func, info, ret, args);
}
-void tcg_gen_call5(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
+void tcg_gen_call5(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
TCGTemp *t2, TCGTemp *t3, TCGTemp *t4, TCGTemp *t5)
{
TCGTemp *args[5] = { t1, t2, t3, t4, t5 };
- tcg_gen_callN(info, ret, args);
+ tcg_gen_callN(func, info, ret, args);
}
-void tcg_gen_call6(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1, TCGTemp *t2,
- TCGTemp *t3, TCGTemp *t4, TCGTemp *t5, TCGTemp *t6)
+void tcg_gen_call6(void *func, TCGHelperInfo *info, TCGTemp *ret,
+ TCGTemp *t1, TCGTemp *t2, TCGTemp *t3,
+ TCGTemp *t4, TCGTemp *t5, TCGTemp *t6)
{
TCGTemp *args[6] = { t1, t2, t3, t4, t5, t6 };
- tcg_gen_callN(info, ret, args);
+ tcg_gen_callN(func, info, ret, args);
}
-void tcg_gen_call7(TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
+void tcg_gen_call7(void *func, TCGHelperInfo *info, TCGTemp *ret, TCGTemp *t1,
TCGTemp *t2, TCGTemp *t3, TCGTemp *t4,
TCGTemp *t5, TCGTemp *t6, TCGTemp *t7)
{
TCGTemp *args[7] = { t1, t2, t3, t4, t5, t6, t7 };
- tcg_gen_callN(info, ret, args);
+ tcg_gen_callN(func, info, ret, args);
}
static void tcg_reg_alloc_start(TCGContext *s)
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 03/20] plugins: Zero new qemu_plugin_dyn_cb entries
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
2024-04-24 23:02 ` [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained Richard Henderson
2024-04-24 23:02 ` [PATCH v3 02/20] tcg: Pass function pointer to tcg_gen_call* Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 04/20] plugins: Move function pointer in qemu_plugin_dyn_cb Richard Henderson
` (16 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
plugins/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugins/core.c b/plugins/core.c
index 11ca20e626..4487cb7c48 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -307,7 +307,7 @@ static struct qemu_plugin_dyn_cb *plugin_get_dyn_cb(GArray **arr)
GArray *cbs = *arr;
if (!cbs) {
- cbs = g_array_sized_new(false, false,
+ cbs = g_array_sized_new(false, true,
sizeof(struct qemu_plugin_dyn_cb), 1);
*arr = cbs;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 04/20] plugins: Move function pointer in qemu_plugin_dyn_cb
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (2 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 03/20] plugins: Zero new qemu_plugin_dyn_cb entries Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-29 10:58 ` Philippe Mathieu-Daudé
2024-04-24 23:02 ` [PATCH v3 05/20] plugins: Create TCGHelperInfo for all out-of-line callbacks Richard Henderson
` (15 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
The out-of-line function pointer is mutually exclusive
with inline expansion, so move it into the union.
Wrap the pointer in a structure named 'regular' to match
PLUGIN_CB_REGULAR.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/plugin.h | 4 +++-
accel/tcg/plugin-gen.c | 4 ++--
plugins/core.c | 8 ++++----
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 12a96cea2a..143262dca8 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -84,13 +84,15 @@ enum plugin_dyn_cb_subtype {
* instance of a callback to be called upon the execution of a particular TB.
*/
struct qemu_plugin_dyn_cb {
- union qemu_plugin_cb_sig f;
void *userp;
enum plugin_dyn_cb_subtype type;
/* @rw applies to mem callbacks only (both regular and inline) */
enum qemu_plugin_mem_rw rw;
/* fields specific to each dyn_cb type go here */
union {
+ struct {
+ union qemu_plugin_cb_sig f;
+ } regular;
struct {
qemu_plugin_u64 entry;
enum qemu_plugin_op op;
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index cd78ef94a1..4b488943ff 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -425,7 +425,7 @@ static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb,
}
/* call */
- op = copy_call(&begin_op, op, cb->f.vcpu_udata, cb_idx);
+ op = copy_call(&begin_op, op, cb->regular.f.vcpu_udata, cb_idx);
return op;
}
@@ -473,7 +473,7 @@ static TCGOp *append_mem_cb(const struct qemu_plugin_dyn_cb *cb,
if (type == PLUGIN_GEN_CB_MEM) {
/* call */
- op = copy_call(&begin_op, op, cb->f.vcpu_udata, cb_idx);
+ op = copy_call(&begin_op, op, cb->regular.f.vcpu_udata, cb_idx);
}
return op;
diff --git a/plugins/core.c b/plugins/core.c
index 4487cb7c48..837c373690 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -342,7 +342,7 @@ void plugin_register_dyn_cb__udata(GArray **arr,
dyn_cb->userp = udata;
/* Note flags are discarded as unused. */
- dyn_cb->f.vcpu_udata = cb;
+ dyn_cb->regular.f.vcpu_udata = cb;
dyn_cb->type = PLUGIN_CB_REGULAR;
}
@@ -359,7 +359,7 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
/* Note flags are discarded as unused. */
dyn_cb->type = PLUGIN_CB_REGULAR;
dyn_cb->rw = rw;
- dyn_cb->f.generic = cb;
+ dyn_cb->regular.f.vcpu_mem = cb;
}
/*
@@ -511,8 +511,8 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
}
switch (cb->type) {
case PLUGIN_CB_REGULAR:
- cb->f.vcpu_mem(cpu->cpu_index, make_plugin_meminfo(oi, rw),
- vaddr, cb->userp);
+ cb->regular.f.vcpu_mem(cpu->cpu_index, make_plugin_meminfo(oi, rw),
+ vaddr, cb->userp);
break;
case PLUGIN_CB_INLINE:
exec_inline_op(cb, cpu->cpu_index);
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 05/20] plugins: Create TCGHelperInfo for all out-of-line callbacks
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (3 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 04/20] plugins: Move function pointer in qemu_plugin_dyn_cb Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 06/20] plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN Richard Henderson
` (14 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
TCGHelperInfo includes the ABI for every function call.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/plugin.h | 1 +
plugins/core.c | 51 ++++++++++++++++++++++++++++++++++++++-----
2 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 143262dca8..793c44f1f2 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -92,6 +92,7 @@ struct qemu_plugin_dyn_cb {
union {
struct {
union qemu_plugin_cb_sig f;
+ TCGHelperInfo *info;
} regular;
struct {
qemu_plugin_u64 entry;
diff --git a/plugins/core.c b/plugins/core.c
index 837c373690..b0a2e80874 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -338,12 +338,26 @@ void plugin_register_dyn_cb__udata(GArray **arr,
enum qemu_plugin_cb_flags flags,
void *udata)
{
- struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
+ static TCGHelperInfo info[3] = {
+ [QEMU_PLUGIN_CB_NO_REGS].flags = TCG_CALL_NO_RWG | TCG_CALL_PLUGIN,
+ [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG | TCG_CALL_PLUGIN,
+ [QEMU_PLUGIN_CB_RW_REGS].flags = TCG_CALL_PLUGIN,
+ /*
+ * Match qemu_plugin_vcpu_udata_cb_t:
+ * void (*)(uint32_t, void *)
+ */
+ [0 ... 2].typemask = (dh_typemask(void, 0) |
+ dh_typemask(i32, 1) |
+ dh_typemask(ptr, 2))
+ };
+ struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
dyn_cb->userp = udata;
- /* Note flags are discarded as unused. */
- dyn_cb->regular.f.vcpu_udata = cb;
dyn_cb->type = PLUGIN_CB_REGULAR;
+ dyn_cb->regular.f.vcpu_udata = cb;
+
+ assert((unsigned)flags < ARRAY_SIZE(info));
+ dyn_cb->regular.info = &info[flags];
}
void plugin_register_vcpu_mem_cb(GArray **arr,
@@ -352,14 +366,39 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
enum qemu_plugin_mem_rw rw,
void *udata)
{
- struct qemu_plugin_dyn_cb *dyn_cb;
+ /*
+ * Expect that the underlying type for enum qemu_plugin_meminfo_t
+ * is either int32_t or uint32_t, aka int or unsigned int.
+ */
+ QEMU_BUILD_BUG_ON(
+ !__builtin_types_compatible_p(qemu_plugin_meminfo_t, uint32_t) &&
+ !__builtin_types_compatible_p(qemu_plugin_meminfo_t, int32_t));
- dyn_cb = plugin_get_dyn_cb(arr);
+ static TCGHelperInfo info[3] = {
+ [QEMU_PLUGIN_CB_NO_REGS].flags = TCG_CALL_NO_RWG | TCG_CALL_PLUGIN,
+ [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG | TCG_CALL_PLUGIN,
+ [QEMU_PLUGIN_CB_RW_REGS].flags = TCG_CALL_PLUGIN,
+ /*
+ * Match qemu_plugin_vcpu_mem_cb_t:
+ * void (*)(uint32_t, qemu_plugin_meminfo_t, uint64_t, void *)
+ */
+ [0 ... 2].typemask =
+ (dh_typemask(void, 0) |
+ dh_typemask(i32, 1) |
+ (__builtin_types_compatible_p(qemu_plugin_meminfo_t, uint32_t)
+ ? dh_typemask(i32, 2) : dh_typemask(s32, 2)) |
+ dh_typemask(i64, 3) |
+ dh_typemask(ptr, 4))
+ };
+
+ struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
dyn_cb->userp = udata;
- /* Note flags are discarded as unused. */
dyn_cb->type = PLUGIN_CB_REGULAR;
dyn_cb->rw = rw;
dyn_cb->regular.f.vcpu_mem = cb;
+
+ assert((unsigned)flags < ARRAY_SIZE(info));
+ dyn_cb->regular.info = &info[flags];
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 06/20] plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (4 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 05/20] plugins: Create TCGHelperInfo for all out-of-line callbacks Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-29 19:56 ` Pierrick Bouvier
2024-04-24 23:02 ` [PATCH v3 07/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB Richard Henderson
` (13 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel
Introduce a new plugin_cb op and migrate one operation.
By using emit_before_op, we do not need to emit opcodes
early and modify them later -- we can simply emit the
final set of opcodes once.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg-op-common.h | 1 +
include/tcg/tcg-opc.h | 1 +
accel/tcg/plugin-gen.c | 74 +++++++++++++++++++++----------------
tcg/tcg-op.c | 5 +++
4 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
index 2d932a515e..9de5a7f280 100644
--- a/include/tcg/tcg-op-common.h
+++ b/include/tcg/tcg-op-common.h
@@ -74,6 +74,7 @@ void tcg_gen_goto_tb(unsigned idx);
*/
void tcg_gen_lookup_and_goto_ptr(void);
+void tcg_gen_plugin_cb(unsigned from);
void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr);
void tcg_gen_plugin_cb_end(void);
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
index b80227fa1c..3b7cb2bce1 100644
--- a/include/tcg/tcg-opc.h
+++ b/include/tcg/tcg-opc.h
@@ -197,6 +197,7 @@ DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
+DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(plugin_cb_start, 0, 0, 3, TCG_OPF_NOT_PRESENT)
DEF(plugin_cb_end, 0, 0, 0, TCG_OPF_NOT_PRESENT)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 4b488943ff..4b02c0bfbf 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -201,8 +201,7 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
{
switch (from) {
case PLUGIN_GEN_AFTER_INSN:
- gen_wrapped(from, PLUGIN_GEN_DISABLE_MEM_HELPER,
- gen_empty_mem_helper);
+ tcg_gen_plugin_cb(from);
break;
case PLUGIN_GEN_FROM_INSN:
/*
@@ -608,16 +607,6 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb,
inject_mem_helper(begin_op, arr);
}
-static void inject_mem_disable_helper(struct qemu_plugin_insn *plugin_insn,
- TCGOp *begin_op)
-{
- if (likely(!plugin_insn->mem_helper)) {
- rm_ops(begin_op);
- return;
- }
- inject_mem_helper(begin_op, NULL);
-}
-
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
void plugin_gen_disable_mem_helpers(void)
{
@@ -703,11 +692,14 @@ static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
inject_mem_enable_helper(ptb, insn, begin_op);
}
-static void plugin_gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
- TCGOp *begin_op, int insn_idx)
+static void gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
+ struct qemu_plugin_insn *insn)
{
- struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
- inject_mem_disable_helper(insn, begin_op);
+ if (insn->mem_helper) {
+ tcg_gen_st_ptr(tcg_constant_ptr(0), tcg_env,
+ offsetof(CPUState, plugin_mem_cbs) -
+ offsetof(ArchCPU, env));
+ }
}
/* #define DEBUG_PLUGIN_GEN_OPS */
@@ -766,16 +758,49 @@ static void pr_ops(void)
static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
{
- TCGOp *op;
+ TCGOp *op, *next;
int insn_idx = -1;
pr_ops();
- QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
+ /*
+ * 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) {
switch (op->opc) {
case INDEX_op_insn_start:
insn_idx++;
break;
+
+ case INDEX_op_plugin_cb:
+ {
+ enum plugin_gen_from from = op->args[0];
+ struct qemu_plugin_insn *insn = NULL;
+
+ if (insn_idx >= 0) {
+ insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
+ }
+
+ tcg_ctx->emit_before_op = op;
+
+ switch (from) {
+ case PLUGIN_GEN_AFTER_INSN:
+ assert(insn != NULL);
+ gen_disable_mem_helper(plugin_tb, insn);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ tcg_ctx->emit_before_op = NULL;
+ tcg_op_remove(tcg_ctx, op);
+ break;
+ }
+
case INDEX_op_plugin_cb_start:
{
enum plugin_gen_from from = op->args[0];
@@ -840,19 +865,6 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
break;
}
- case PLUGIN_GEN_AFTER_INSN:
- {
- g_assert(insn_idx >= 0);
-
- switch (type) {
- case PLUGIN_GEN_DISABLE_MEM_HELPER:
- plugin_gen_disable_mem_helper(plugin_tb, op, insn_idx);
- break;
- default:
- g_assert_not_reached();
- }
- break;
- }
default:
g_assert_not_reached();
}
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index aa6bc6f57d..0f2026c91c 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -312,6 +312,11 @@ void tcg_gen_mb(TCGBar mb_type)
}
}
+void tcg_gen_plugin_cb(unsigned from)
+{
+ tcg_gen_op1(INDEX_op_plugin_cb, from);
+}
+
void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr)
{
tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 07/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (5 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 06/20] plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-29 19:57 ` Pierrick Bouvier
2024-04-24 23:02 ` [PATCH v3 08/20] plugins: Add PLUGIN_GEN_AFTER_TB Richard Henderson
` (12 subsequent siblings)
19 siblings, 1 reply; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel
By having the qemu_plugin_cb_flags be recorded in the TCGHelperInfo,
we no longer need to distinguish PLUGIN_CB_REGULAR from
PLUGIN_CB_REGULAR_R, so place all TB callbacks in the same queue.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-gen.c | 96 +++++++++++++++++++++++++-----------------
plugins/api.c | 6 +--
2 files changed, 58 insertions(+), 44 deletions(-)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 4b02c0bfbf..c803fe8e96 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -201,6 +201,7 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
{
switch (from) {
case PLUGIN_GEN_AFTER_INSN:
+ case PLUGIN_GEN_FROM_TB:
tcg_gen_plugin_cb(from);
break;
case PLUGIN_GEN_FROM_INSN:
@@ -210,8 +211,6 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
*/
gen_wrapped(from, PLUGIN_GEN_ENABLE_MEM_HELPER,
gen_empty_mem_helper);
- /* fall through */
- case PLUGIN_GEN_FROM_TB:
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);
@@ -626,24 +625,6 @@ void plugin_gen_disable_mem_helpers(void)
offsetof(CPUState, plugin_mem_cbs) - offsetof(ArchCPU, env));
}
-static void plugin_gen_tb_udata(const struct qemu_plugin_tb *ptb,
- TCGOp *begin_op)
-{
- inject_udata_cb(ptb->cbs[PLUGIN_CB_REGULAR], begin_op);
-}
-
-static void plugin_gen_tb_udata_r(const struct qemu_plugin_tb *ptb,
- TCGOp *begin_op)
-{
- 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)
-{
- inject_inline_cb(ptb->cbs[PLUGIN_CB_INLINE], begin_op, op_ok);
-}
-
static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb,
TCGOp *begin_op, int insn_idx)
{
@@ -702,6 +683,41 @@ static void gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
}
}
+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);
+}
+
/* #define DEBUG_PLUGIN_GEN_OPS */
static void pr_ops(void)
{
@@ -780,6 +796,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
{
enum plugin_gen_from from = op->args[0];
struct qemu_plugin_insn *insn = NULL;
+ const GArray *cbs;
+ int i, n;
if (insn_idx >= 0) {
insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
@@ -792,6 +810,25 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
assert(insn != NULL);
gen_disable_mem_helper(plugin_tb, insn);
break;
+
+ case PLUGIN_GEN_FROM_TB:
+ assert(insn == NULL);
+
+ cbs = plugin_tb->cbs[PLUGIN_CB_REGULAR];
+ for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
+ struct qemu_plugin_dyn_cb *cb =
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
+ gen_udata_cb(cb);
+ }
+
+ cbs = plugin_tb->cbs[PLUGIN_CB_INLINE];
+ for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
+ struct qemu_plugin_dyn_cb *cb =
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
+ gen_inline_cb(cb);
+ }
+ break;
+
default:
g_assert_not_reached();
}
@@ -807,25 +844,6 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
enum plugin_gen_cb type = op->args[1];
switch (from) {
- case PLUGIN_GEN_FROM_TB:
- {
- g_assert(insn_idx == -1);
-
- switch (type) {
- case PLUGIN_GEN_CB_UDATA:
- plugin_gen_tb_udata(plugin_tb, op);
- break;
- 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);
- break;
- default:
- g_assert_not_reached();
- }
- break;
- }
case PLUGIN_GEN_FROM_INSN:
{
g_assert(insn_idx >= 0);
diff --git a/plugins/api.c b/plugins/api.c
index 8fa5a600ac..5d119e8049 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -92,11 +92,7 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
void *udata)
{
if (!tb->mem_only) {
- int index = flags == QEMU_PLUGIN_CB_R_REGS ||
- flags == QEMU_PLUGIN_CB_RW_REGS ?
- PLUGIN_CB_REGULAR_R : PLUGIN_CB_REGULAR;
-
- plugin_register_dyn_cb__udata(&tb->cbs[index],
+ plugin_register_dyn_cb__udata(&tb->cbs[PLUGIN_CB_REGULAR],
cb, flags, udata);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 08/20] plugins: Add PLUGIN_GEN_AFTER_TB
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (6 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 07/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 09/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_INSN Richard Henderson
` (11 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Delay test of plugin_tb->mem_helper until the inject pass.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-gen.c | 37 ++++++++++++++++---------------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index c803fe8e96..1faa49cb8f 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -69,6 +69,7 @@ enum plugin_gen_from {
PLUGIN_GEN_FROM_INSN,
PLUGIN_GEN_FROM_MEM,
PLUGIN_GEN_AFTER_INSN,
+ PLUGIN_GEN_AFTER_TB,
PLUGIN_GEN_N_FROMS,
};
@@ -609,20 +610,9 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb,
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
void plugin_gen_disable_mem_helpers(void)
{
- /*
- * We could emit the clearing unconditionally and be done. However, this can
- * be wasteful if for instance plugins don't track memory accesses, or if
- * most TBs don't use helpers. Instead, emit the clearing iff the TB calls
- * helpers that might access guest memory.
- *
- * Note: we do not reset plugin_tb->mem_helper here; a TB might have several
- * exit points, and we want to emit the clearing from all of them.
- */
- if (!tcg_ctx->plugin_tb->mem_helper) {
- return;
+ if (tcg_ctx->plugin_insn) {
+ tcg_gen_plugin_cb(PLUGIN_GEN_AFTER_TB);
}
- tcg_gen_st_ptr(tcg_constant_ptr(NULL), tcg_env,
- offsetof(CPUState, plugin_mem_cbs) - offsetof(ArchCPU, env));
}
static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb,
@@ -673,14 +663,11 @@ static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
inject_mem_enable_helper(ptb, insn, begin_op);
}
-static void gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
- struct qemu_plugin_insn *insn)
+static void gen_disable_mem_helper(void)
{
- if (insn->mem_helper) {
- tcg_gen_st_ptr(tcg_constant_ptr(0), tcg_env,
- offsetof(CPUState, plugin_mem_cbs) -
- offsetof(ArchCPU, env));
- }
+ tcg_gen_st_ptr(tcg_constant_ptr(0), tcg_env,
+ offsetof(CPUState, plugin_mem_cbs) -
+ offsetof(ArchCPU, env));
}
static void gen_udata_cb(struct qemu_plugin_dyn_cb *cb)
@@ -806,9 +793,17 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
tcg_ctx->emit_before_op = op;
switch (from) {
+ case PLUGIN_GEN_AFTER_TB:
+ if (plugin_tb->mem_helper) {
+ gen_disable_mem_helper();
+ }
+ break;
+
case PLUGIN_GEN_AFTER_INSN:
assert(insn != NULL);
- gen_disable_mem_helper(plugin_tb, insn);
+ if (insn->mem_helper) {
+ gen_disable_mem_helper();
+ }
break;
case PLUGIN_GEN_FROM_TB:
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 09/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_INSN
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (7 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 08/20] plugins: Add PLUGIN_GEN_AFTER_TB Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 10/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_MEM Richard Henderson
` (10 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/plugin.h | 1 -
accel/tcg/plugin-gen.c | 286 ++++++++++-------------------------------
plugins/api.c | 8 +-
3 files changed, 67 insertions(+), 228 deletions(-)
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 793c44f1f2..ee1c1b174a 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -73,7 +73,6 @@ enum plugin_dyn_cb_type {
enum plugin_dyn_cb_subtype {
PLUGIN_CB_REGULAR,
- PLUGIN_CB_REGULAR_R,
PLUGIN_CB_INLINE,
PLUGIN_N_CB_SUBTYPES,
};
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 1faa49cb8f..a3dd82df4b 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -98,30 +98,6 @@ void HELPER(plugin_vcpu_mem_cb)(unsigned int vcpu_index,
void *userdata)
{ }
-static void gen_empty_udata_cb(void (*gen_helper)(TCGv_i32, TCGv_ptr))
-{
- TCGv_i32 cpu_index = tcg_temp_ebb_new_i32();
- TCGv_ptr udata = tcg_temp_ebb_new_ptr();
-
- tcg_gen_movi_ptr(udata, 0);
- tcg_gen_ld_i32(cpu_index, tcg_env,
- -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
- gen_helper(cpu_index, udata);
-
- tcg_temp_free_ptr(udata);
- 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_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.
@@ -170,51 +146,19 @@ static void gen_empty_mem_cb(TCGv_i64 addr, uint32_t info)
tcg_temp_free_i32(cpu_index);
}
-/*
- * Share the same function for enable/disable. When enabling, the NULL
- * pointer will be overwritten later.
- */
-static void gen_empty_mem_helper(void)
-{
- TCGv_ptr ptr = tcg_temp_ebb_new_ptr();
-
- tcg_gen_movi_ptr(ptr, 0);
- tcg_gen_st_ptr(ptr, tcg_env, offsetof(CPUState, plugin_mem_cbs) -
- offsetof(ArchCPU, env));
- tcg_temp_free_ptr(ptr);
-}
-
static void gen_plugin_cb_start(enum plugin_gen_from from,
enum plugin_gen_cb type, unsigned wr)
{
tcg_gen_plugin_cb_start(from, type, wr);
}
-static void gen_wrapped(enum plugin_gen_from from,
- enum plugin_gen_cb type, void (*func)(void))
-{
- gen_plugin_cb_start(from, type, 0);
- func();
- tcg_gen_plugin_cb_end();
-}
-
static void plugin_gen_empty_callback(enum plugin_gen_from from)
{
switch (from) {
case PLUGIN_GEN_AFTER_INSN:
case PLUGIN_GEN_FROM_TB:
- tcg_gen_plugin_cb(from);
- break;
case PLUGIN_GEN_FROM_INSN:
- /*
- * Note: plugin_gen_inject() relies on ENABLE_MEM_HELPER being
- * the first callback of an instruction
- */
- gen_wrapped(from, PLUGIN_GEN_ENABLE_MEM_HELPER,
- gen_empty_mem_helper);
- 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);
+ tcg_gen_plugin_cb(from);
break;
default:
g_assert_not_reached();
@@ -368,18 +312,6 @@ static TCGOp *copy_mul_i32(TCGOp **begin_op, TCGOp *op, uint32_t v)
return op;
}
-static TCGOp *copy_st_ptr(TCGOp **begin_op, TCGOp *op)
-{
- if (UINTPTR_MAX == UINT32_MAX) {
- /* st_i32 */
- op = copy_op(begin_op, op, INDEX_op_st_i32);
- } else {
- /* st_i64 */
- op = copy_st_i64(begin_op, op);
- }
- return op;
-}
-
static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *func, int *cb_idx)
{
TCGOp *old_op;
@@ -403,32 +335,6 @@ static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *func, int *cb_idx)
return op;
}
-/*
- * 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
- * empty callbacks. This will assert very quickly in a debug build as
- * we assert the ops we are replacing are the correct ones.
- */
-static TCGOp *append_udata_cb(const struct qemu_plugin_dyn_cb *cb,
- TCGOp *begin_op, TCGOp *op, int *cb_idx)
-{
- /* const_ptr */
- op = copy_const_ptr(&begin_op, op, cb->userp);
-
- /* copy the ld_i32, but note that we only have to copy it once */
- if (*cb_idx == -1) {
- op = copy_op(&begin_op, op, INDEX_op_ld_i32);
- } else {
- begin_op = QTAILQ_NEXT(begin_op, link);
- tcg_debug_assert(begin_op && begin_op->opc == INDEX_op_ld_i32);
- }
-
- /* call */
- op = copy_call(&begin_op, op, cb->regular.f.vcpu_udata, cb_idx);
-
- return op;
-}
-
static TCGOp *append_inline_cb(const struct qemu_plugin_dyn_cb *cb,
TCGOp *begin_op, TCGOp *op,
int *unused)
@@ -482,11 +388,6 @@ typedef TCGOp *(*inject_fn)(const struct qemu_plugin_dyn_cb *cb,
TCGOp *begin_op, TCGOp *op, int *intp);
typedef bool (*op_ok_fn)(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb);
-static bool op_ok(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
-{
- return true;
-}
-
static bool op_rw(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
{
int w;
@@ -524,12 +425,6 @@ static void inject_cb_type(const GArray *cbs, TCGOp *begin_op,
rm_ops_range(begin_op, end_op);
}
-static void
-inject_udata_cb(const GArray *cbs, TCGOp *begin_op)
-{
- inject_cb_type(cbs, begin_op, append_udata_cb, op_ok);
-}
-
static void
inject_inline_cb(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok)
{
@@ -542,71 +437,6 @@ inject_mem_cb(const GArray *cbs, TCGOp *begin_op)
inject_cb_type(cbs, begin_op, append_mem_cb, op_rw);
}
-/* we could change the ops in place, but we can reuse more code by copying */
-static void inject_mem_helper(TCGOp *begin_op, GArray *arr)
-{
- TCGOp *orig_op = begin_op;
- TCGOp *end_op;
- TCGOp *op;
-
- end_op = find_op(begin_op, INDEX_op_plugin_cb_end);
- tcg_debug_assert(end_op);
-
- /* const ptr */
- op = copy_const_ptr(&begin_op, end_op, arr);
-
- /* st_ptr */
- op = copy_st_ptr(&begin_op, op);
-
- rm_ops_range(orig_op, end_op);
-}
-
-/*
- * 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.
- */
-static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb,
- struct qemu_plugin_insn *plugin_insn,
- TCGOp *begin_op)
-{
- GArray *cbs[2];
- 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];
-
- n_cbs = 0;
- for (i = 0; i < ARRAY_SIZE(cbs); i++) {
- n_cbs += cbs[i]->len;
- }
-
- plugin_insn->mem_helper = plugin_insn->calls_helpers && n_cbs;
- if (likely(!plugin_insn->mem_helper)) {
- rm_ops(begin_op);
- return;
- }
- ptb->mem_helper = true;
-
- arr = g_array_sized_new(false, false,
- sizeof(struct qemu_plugin_dyn_cb), n_cbs);
-
- for (i = 0; i < ARRAY_SIZE(cbs); i++) {
- g_array_append_vals(arr, cbs[i]->data, cbs[i]->len);
- }
-
- qemu_plugin_add_dyn_cb_arr(arr);
- inject_mem_helper(begin_op, arr);
-}
-
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
void plugin_gen_disable_mem_helpers(void)
{
@@ -615,30 +445,6 @@ void plugin_gen_disable_mem_helpers(void)
}
}
-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);
-}
-
-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_inline(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);
-}
-
static void plugin_gen_mem_regular(const struct qemu_plugin_tb *ptb,
TCGOp *begin_op, int insn_idx)
{
@@ -656,11 +462,51 @@ static void plugin_gen_mem_inline(const struct qemu_plugin_tb *ptb,
inject_inline_cb(cbs, begin_op, op_rw);
}
-static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
- TCGOp *begin_op, int insn_idx)
+static void gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
+ struct qemu_plugin_insn *insn)
{
- struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
- inject_mem_enable_helper(ptb, insn, begin_op);
+ GArray *cbs[2];
+ GArray *arr;
+ size_t n_cbs;
+
+ /*
+ * 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;
+ }
+
+ cbs[0] = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR];
+ cbs[1] = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE];
+ n_cbs = cbs[0]->len + cbs[1]->len;
+
+ if (n_cbs == 0) {
+ insn->mem_helper = false;
+ return;
+ }
+ insn->mem_helper = true;
+ ptb->mem_helper = true;
+
+ arr = g_array_sized_new(false, false,
+ sizeof(struct qemu_plugin_dyn_cb), n_cbs);
+ g_array_append_vals(arr, cbs[0]->data, cbs[0]->len);
+ g_array_append_vals(arr, cbs[1]->data, cbs[1]->len);
+
+ 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));
}
static void gen_disable_mem_helper(void)
@@ -824,6 +670,26 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
}
break;
+ case PLUGIN_GEN_FROM_INSN:
+ assert(insn != NULL);
+
+ gen_enable_mem_helper(plugin_tb, insn);
+
+ cbs = insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR];
+ for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
+ struct qemu_plugin_dyn_cb *cb =
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
+ gen_udata_cb(cb);
+ }
+
+ cbs = insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE];
+ for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
+ struct qemu_plugin_dyn_cb *cb =
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
+ gen_inline_cb(cb);
+ }
+ break;
+
default:
g_assert_not_reached();
}
@@ -839,28 +705,6 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
enum plugin_gen_cb type = op->args[1];
switch (from) {
- case PLUGIN_GEN_FROM_INSN:
- {
- g_assert(insn_idx >= 0);
-
- switch (type) {
- case PLUGIN_GEN_CB_UDATA:
- plugin_gen_insn_udata(plugin_tb, op, insn_idx);
- break;
- 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);
- break;
- case PLUGIN_GEN_ENABLE_MEM_HELPER:
- plugin_gen_enable_mem_helper(plugin_tb, op, insn_idx);
- break;
- default:
- g_assert_not_reached();
- }
- break;
- }
case PLUGIN_GEN_FROM_MEM:
{
g_assert(insn_idx >= 0);
diff --git a/plugins/api.c b/plugins/api.c
index 5d119e8049..29cce2d97c 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -115,12 +115,8 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
void *udata)
{
if (!insn->mem_only) {
- int index = flags == QEMU_PLUGIN_CB_R_REGS ||
- flags == QEMU_PLUGIN_CB_RW_REGS ?
- PLUGIN_CB_REGULAR_R : PLUGIN_CB_REGULAR;
-
- plugin_register_dyn_cb__udata(&insn->cbs[PLUGIN_CB_INSN][index],
- cb, flags, udata);
+ plugin_register_dyn_cb__udata(
+ &insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR], cb, flags, udata);
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 10/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_MEM
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (8 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 09/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_INSN Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 11/20] plugins: Remove plugin helpers Richard Henderson
` (9 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Introduce a new plugin_mem_cb op to hold the address temp
and meminfo computed by tcg-op-ldst.c. Because this now
has its own opcode, we no longer need PLUGIN_GEN_FROM_MEM.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/exec/plugin-gen.h | 4 -
include/tcg/tcg-op-common.h | 1 +
include/tcg/tcg-opc.h | 1 +
accel/tcg/plugin-gen.c | 408 ++++--------------------------------
tcg/tcg-op-ldst.c | 6 +-
tcg/tcg-op.c | 5 +
6 files changed, 54 insertions(+), 371 deletions(-)
diff --git a/include/exec/plugin-gen.h b/include/exec/plugin-gen.h
index c4552b5061..f333f33198 100644
--- a/include/exec/plugin-gen.h
+++ b/include/exec/plugin-gen.h
@@ -25,7 +25,6 @@ void plugin_gen_insn_start(CPUState *cpu, const struct DisasContextBase *db);
void plugin_gen_insn_end(void);
void plugin_gen_disable_mem_helpers(void);
-void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info);
#else /* !CONFIG_PLUGIN */
@@ -48,9 +47,6 @@ static inline void plugin_gen_tb_end(CPUState *cpu, size_t num_insns)
static inline void plugin_gen_disable_mem_helpers(void)
{ }
-static inline void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info)
-{ }
-
#endif /* CONFIG_PLUGIN */
#endif /* QEMU_PLUGIN_GEN_H */
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
index 9de5a7f280..72b80b20d0 100644
--- a/include/tcg/tcg-op-common.h
+++ b/include/tcg/tcg-op-common.h
@@ -75,6 +75,7 @@ void tcg_gen_goto_tb(unsigned idx);
void tcg_gen_lookup_and_goto_ptr(void);
void tcg_gen_plugin_cb(unsigned from);
+void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo);
void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr);
void tcg_gen_plugin_cb_end(void);
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
index 3b7cb2bce1..be9e36e386 100644
--- a/include/tcg/tcg-opc.h
+++ b/include/tcg/tcg-opc.h
@@ -198,6 +198,7 @@ DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
+DEF(plugin_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
DEF(plugin_cb_start, 0, 0, 3, TCG_OPF_NOT_PRESENT)
DEF(plugin_cb_end, 0, 0, 0, TCG_OPF_NOT_PRESENT)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index a3dd82df4b..8f8ae156b6 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -67,7 +67,6 @@
enum plugin_gen_from {
PLUGIN_GEN_FROM_TB,
PLUGIN_GEN_FROM_INSN,
- PLUGIN_GEN_FROM_MEM,
PLUGIN_GEN_AFTER_INSN,
PLUGIN_GEN_AFTER_TB,
PLUGIN_GEN_N_FROMS,
@@ -98,60 +97,6 @@ void HELPER(plugin_vcpu_mem_cb)(unsigned int vcpu_index,
void *userdata)
{ }
-/*
- * 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)
-{
- 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_ld_i64(val, ptr, 0);
- /* second operand will be replaced by immediate value */
- tcg_gen_add_i64(val, val, val);
-
- 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();
- TCGv_i32 meminfo = tcg_temp_ebb_new_i32();
- TCGv_ptr udata = tcg_temp_ebb_new_ptr();
-
- tcg_gen_movi_i32(meminfo, info);
- tcg_gen_movi_ptr(udata, 0);
- tcg_gen_ld_i32(cpu_index, tcg_env,
- -offsetof(ArchCPU, env) + offsetof(CPUState, cpu_index));
-
- gen_helper_plugin_vcpu_mem_cb(cpu_index, meminfo, addr, udata);
-
- tcg_temp_free_ptr(udata);
- tcg_temp_free_i32(meminfo);
- tcg_temp_free_i32(cpu_index);
-}
-
-static void gen_plugin_cb_start(enum plugin_gen_from from,
- enum plugin_gen_cb type, unsigned wr)
-{
- tcg_gen_plugin_cb_start(from, type, wr);
-}
-
static void plugin_gen_empty_callback(enum plugin_gen_from from)
{
switch (from) {
@@ -165,278 +110,6 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
}
}
-void plugin_gen_empty_mem_callback(TCGv_i64 addr, uint32_t info)
-{
- enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info);
-
- 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)
-{
- while (op) {
- if (op->opc == opc) {
- return op;
- }
- op = QTAILQ_NEXT(op, link);
- }
- return NULL;
-}
-
-static TCGOp *rm_ops_range(TCGOp *begin, TCGOp *end)
-{
- TCGOp *ret = QTAILQ_NEXT(end, link);
-
- QTAILQ_REMOVE_SEVERAL(&tcg_ctx->ops, begin, end, link);
- return ret;
-}
-
-/* remove all ops until (and including) plugin_cb_end */
-static TCGOp *rm_ops(TCGOp *op)
-{
- TCGOp *end_op = find_op(op, INDEX_op_plugin_cb_end);
-
- tcg_debug_assert(end_op);
- return rm_ops_range(op, end_op);
-}
-
-static TCGOp *copy_op_nocheck(TCGOp **begin_op, TCGOp *op)
-{
- TCGOp *old_op = QTAILQ_NEXT(*begin_op, link);
- unsigned nargs = old_op->nargs;
-
- *begin_op = old_op;
- op = tcg_op_insert_after(tcg_ctx, op, old_op->opc, nargs);
- memcpy(op->args, old_op->args, sizeof(op->args[0]) * nargs);
-
- return op;
-}
-
-static TCGOp *copy_op(TCGOp **begin_op, TCGOp *op, TCGOpcode opc)
-{
- op = copy_op_nocheck(begin_op, op);
- tcg_debug_assert((*begin_op)->opc == opc);
- return op;
-}
-
-static TCGOp *copy_const_ptr(TCGOp **begin_op, TCGOp *op, void *ptr)
-{
- if (UINTPTR_MAX == UINT32_MAX) {
- /* mov_i32 */
- op = copy_op(begin_op, op, INDEX_op_mov_i32);
- op->args[1] = tcgv_i32_arg(tcg_constant_i32((uintptr_t)ptr));
- } else {
- /* mov_i64 */
- op = copy_op(begin_op, op, INDEX_op_mov_i64);
- op->args[1] = tcgv_i64_arg(tcg_constant_i64((uintptr_t)ptr));
- }
- return op;
-}
-
-static TCGOp *copy_ld_i32(TCGOp **begin_op, TCGOp *op)
-{
- return copy_op(begin_op, op, INDEX_op_ld_i32);
-}
-
-static TCGOp *copy_ext_i32_ptr(TCGOp **begin_op, TCGOp *op)
-{
- if (UINTPTR_MAX == UINT32_MAX) {
- op = copy_op(begin_op, op, INDEX_op_mov_i32);
- } else {
- op = copy_op(begin_op, op, INDEX_op_ext_i32_i64);
- }
- return op;
-}
-
-static TCGOp *copy_add_ptr(TCGOp **begin_op, TCGOp *op)
-{
- if (UINTPTR_MAX == UINT32_MAX) {
- op = copy_op(begin_op, op, INDEX_op_add_i32);
- } else {
- op = copy_op(begin_op, op, INDEX_op_add_i64);
- }
- return op;
-}
-
-static TCGOp *copy_ld_i64(TCGOp **begin_op, TCGOp *op)
-{
- if (TCG_TARGET_REG_BITS == 32) {
- /* 2x ld_i32 */
- op = copy_ld_i32(begin_op, op);
- op = copy_ld_i32(begin_op, op);
- } else {
- /* ld_i64 */
- op = copy_op(begin_op, op, INDEX_op_ld_i64);
- }
- return op;
-}
-
-static TCGOp *copy_st_i64(TCGOp **begin_op, TCGOp *op)
-{
- if (TCG_TARGET_REG_BITS == 32) {
- /* 2x st_i32 */
- op = copy_op(begin_op, op, INDEX_op_st_i32);
- op = copy_op(begin_op, op, INDEX_op_st_i32);
- } else {
- /* st_i64 */
- op = copy_op(begin_op, op, INDEX_op_st_i64);
- }
- return op;
-}
-
-static TCGOp *copy_add_i64(TCGOp **begin_op, TCGOp *op, uint64_t v)
-{
- if (TCG_TARGET_REG_BITS == 32) {
- /* all 32-bit backends must implement add2_i32 */
- g_assert(TCG_TARGET_HAS_add2_i32);
- op = copy_op(begin_op, op, INDEX_op_add2_i32);
- op->args[4] = tcgv_i32_arg(tcg_constant_i32(v));
- op->args[5] = tcgv_i32_arg(tcg_constant_i32(v >> 32));
- } else {
- op = copy_op(begin_op, op, INDEX_op_add_i64);
- op->args[2] = tcgv_i64_arg(tcg_constant_i64(v));
- }
- return op;
-}
-
-static TCGOp *copy_mul_i32(TCGOp **begin_op, TCGOp *op, uint32_t v)
-{
- op = copy_op(begin_op, op, INDEX_op_mul_i32);
- op->args[2] = tcgv_i32_arg(tcg_constant_i32(v));
- return op;
-}
-
-static TCGOp *copy_call(TCGOp **begin_op, TCGOp *op, void *func, int *cb_idx)
-{
- TCGOp *old_op;
- int func_idx;
-
- /* copy all ops until the call */
- do {
- op = copy_op_nocheck(begin_op, op);
- } while (op->opc != INDEX_op_call);
-
- /* fill in the op call */
- old_op = *begin_op;
- TCGOP_CALLI(op) = TCGOP_CALLI(old_op);
- TCGOP_CALLO(op) = TCGOP_CALLO(old_op);
- tcg_debug_assert(op->life == 0);
-
- func_idx = TCGOP_CALLO(op) + TCGOP_CALLI(op);
- *cb_idx = func_idx;
- op->args[func_idx] = (uintptr_t)func;
-
- return op;
-}
-
-static TCGOp *append_inline_cb(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_ld_i64(&begin_op, op);
- op = copy_add_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)
-{
- enum plugin_gen_cb type = begin_op->args[1];
-
- tcg_debug_assert(type == PLUGIN_GEN_CB_MEM);
-
- /* const_i32 == mov_i32 ("info", so it remains as is) */
- op = copy_op(&begin_op, op, INDEX_op_mov_i32);
-
- /* const_ptr */
- op = copy_const_ptr(&begin_op, op, cb->userp);
-
- /* copy the ld_i32, but note that we only have to copy it once */
- if (*cb_idx == -1) {
- op = copy_op(&begin_op, op, INDEX_op_ld_i32);
- } else {
- begin_op = QTAILQ_NEXT(begin_op, link);
- tcg_debug_assert(begin_op && begin_op->opc == INDEX_op_ld_i32);
- }
-
- if (type == PLUGIN_GEN_CB_MEM) {
- /* call */
- op = copy_call(&begin_op, op, cb->regular.f.vcpu_udata, cb_idx);
- }
-
- return op;
-}
-
-typedef TCGOp *(*inject_fn)(const struct qemu_plugin_dyn_cb *cb,
- TCGOp *begin_op, TCGOp *op, int *intp);
-typedef bool (*op_ok_fn)(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb);
-
-static bool op_rw(const TCGOp *op, const struct qemu_plugin_dyn_cb *cb)
-{
- int w;
-
- w = op->args[2];
- return !!(cb->rw & (w + 1));
-}
-
-static void inject_cb_type(const GArray *cbs, TCGOp *begin_op,
- inject_fn inject, op_ok_fn ok)
-{
- TCGOp *end_op;
- TCGOp *op;
- int cb_idx = -1;
- int i;
-
- if (!cbs || cbs->len == 0) {
- rm_ops(begin_op);
- return;
- }
-
- end_op = find_op(begin_op, INDEX_op_plugin_cb_end);
- tcg_debug_assert(end_op);
-
- op = end_op;
- for (i = 0; i < cbs->len; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
-
- if (!ok(begin_op, cb)) {
- continue;
- }
- op = inject(cb, begin_op, op, &cb_idx);
- }
- rm_ops_range(begin_op, end_op);
-}
-
-static void
-inject_inline_cb(const GArray *cbs, TCGOp *begin_op, op_ok_fn ok)
-{
- inject_cb_type(cbs, begin_op, append_inline_cb, ok);
-}
-
-static void
-inject_mem_cb(const GArray *cbs, TCGOp *begin_op)
-{
- inject_cb_type(cbs, begin_op, append_mem_cb, op_rw);
-}
-
/* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
void plugin_gen_disable_mem_helpers(void)
{
@@ -445,23 +118,6 @@ void plugin_gen_disable_mem_helpers(void)
}
}
-static void plugin_gen_mem_regular(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_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)
-{
- 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);
-}
-
static void gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
struct qemu_plugin_insn *insn)
{
@@ -551,6 +207,21 @@ static void gen_inline_cb(struct qemu_plugin_dyn_cb *cb)
tcg_temp_free_ptr(ptr);
}
+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);
+}
+
/* #define DEBUG_PLUGIN_GEN_OPS */
static void pr_ops(void)
{
@@ -699,34 +370,43 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
break;
}
- case INDEX_op_plugin_cb_start:
+ case INDEX_op_plugin_mem_cb:
{
- enum plugin_gen_from from = op->args[0];
- enum plugin_gen_cb type = op->args[1];
+ TCGv_i64 addr = temp_tcgv_i64(arg_temp(op->args[0]));
+ qemu_plugin_meminfo_t meminfo = op->args[1];
+ struct qemu_plugin_insn *insn;
+ const GArray *cbs;
+ int i, n, rw;
- switch (from) {
- case PLUGIN_GEN_FROM_MEM:
- {
- g_assert(insn_idx >= 0);
+ assert(insn_idx >= 0);
+ insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
+ rw = qemu_plugin_mem_is_store(meminfo) ? 2 : 1;
- switch (type) {
- 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);
- break;
- default:
- g_assert_not_reached();
+ tcg_ctx->emit_before_op = op;
+
+ cbs = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR];
+ for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
+ struct qemu_plugin_dyn_cb *cb =
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
+ if (cb->rw & rw) {
+ gen_mem_cb(cb, meminfo, addr);
}
+ }
- break;
- }
- default:
- g_assert_not_reached();
+ cbs = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE];
+ for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
+ struct qemu_plugin_dyn_cb *cb =
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
+ if (cb->rw & rw) {
+ gen_inline_cb(cb);
+ }
}
+
+ tcg_ctx->emit_before_op = NULL;
+ tcg_op_remove(tcg_ctx, op);
break;
}
+
default:
/* plugins don't care about any other ops */
break;
diff --git a/tcg/tcg-op-ldst.c b/tcg/tcg-op-ldst.c
index f11043b449..8510160258 100644
--- a/tcg/tcg-op-ldst.c
+++ b/tcg/tcg-op-ldst.c
@@ -161,14 +161,14 @@ plugin_gen_mem_callbacks(TCGv_i64 copy_addr, TCGTemp *orig_addr, MemOpIdx oi,
copy_addr = tcg_temp_ebb_new_i64();
tcg_gen_extu_i32_i64(copy_addr, temp_tcgv_i32(orig_addr));
}
- plugin_gen_empty_mem_callback(copy_addr, info);
+ tcg_gen_plugin_mem_cb(copy_addr, info);
tcg_temp_free_i64(copy_addr);
} else {
if (copy_addr) {
- plugin_gen_empty_mem_callback(copy_addr, info);
+ tcg_gen_plugin_mem_cb(copy_addr, info);
tcg_temp_free_i64(copy_addr);
} else {
- plugin_gen_empty_mem_callback(temp_tcgv_i64(orig_addr), info);
+ tcg_gen_plugin_mem_cb(temp_tcgv_i64(orig_addr), info);
}
}
}
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 0f2026c91c..0ae12fa49d 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -317,6 +317,11 @@ void tcg_gen_plugin_cb(unsigned from)
tcg_gen_op1(INDEX_op_plugin_cb, from);
}
+void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo)
+{
+ tcg_gen_op2(INDEX_op_plugin_mem_cb, tcgv_i64_arg(addr), meminfo);
+}
+
void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr)
{
tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 11/20] plugins: Remove plugin helpers
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (9 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 10/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_MEM Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 12/20] tcg: Remove TCG_CALL_PLUGIN Richard Henderson
` (8 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
These placeholder helpers are no longer required.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-helpers.h | 5 -----
include/exec/helper-gen-common.h | 4 ----
include/exec/helper-proto-common.h | 4 ----
accel/tcg/plugin-gen.c | 20 --------------------
4 files changed, 33 deletions(-)
delete mode 100644 accel/tcg/plugin-helpers.h
diff --git a/accel/tcg/plugin-helpers.h b/accel/tcg/plugin-helpers.h
deleted file mode 100644
index 11796436f3..0000000000
--- a/accel/tcg/plugin-helpers.h
+++ /dev/null
@@ -1,5 +0,0 @@
-#ifdef CONFIG_PLUGIN
-DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb_no_wg, TCG_CALL_NO_WG | TCG_CALL_PLUGIN, void, i32, ptr)
-DEF_HELPER_FLAGS_2(plugin_vcpu_udata_cb_no_rwg, TCG_CALL_NO_RWG | TCG_CALL_PLUGIN, void, i32, ptr)
-DEF_HELPER_FLAGS_4(plugin_vcpu_mem_cb, TCG_CALL_NO_RWG | TCG_CALL_PLUGIN, void, i32, i32, i64, ptr)
-#endif
diff --git a/include/exec/helper-gen-common.h b/include/exec/helper-gen-common.h
index 5d6d78a625..834590dc4e 100644
--- a/include/exec/helper-gen-common.h
+++ b/include/exec/helper-gen-common.h
@@ -11,8 +11,4 @@
#include "exec/helper-gen.h.inc"
#undef HELPER_H
-#define HELPER_H "accel/tcg/plugin-helpers.h"
-#include "exec/helper-gen.h.inc"
-#undef HELPER_H
-
#endif /* HELPER_GEN_COMMON_H */
diff --git a/include/exec/helper-proto-common.h b/include/exec/helper-proto-common.h
index 8b67170a22..16782ef46c 100644
--- a/include/exec/helper-proto-common.h
+++ b/include/exec/helper-proto-common.h
@@ -13,8 +13,4 @@
#include "exec/helper-proto.h.inc"
#undef HELPER_H
-#define HELPER_H "accel/tcg/plugin-helpers.h"
-#include "exec/helper-proto.h.inc"
-#undef HELPER_H
-
#endif /* HELPER_PROTO_COMMON_H */
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 8f8ae156b6..fb77585ac0 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -51,11 +51,6 @@
#include "exec/exec-all.h"
#include "exec/plugin-gen.h"
#include "exec/translator.h"
-#include "exec/helper-proto-common.h"
-
-#define HELPER_H "accel/tcg/plugin-helpers.h"
-#include "exec/helper-info.c.inc"
-#undef HELPER_H
/*
* plugin_cb_start TCG op args[]:
@@ -82,21 +77,6 @@ enum plugin_gen_cb {
PLUGIN_GEN_N_CBS,
};
-/*
- * These helpers are stubs that get dynamically switched out for calls
- * direct to the plugin if they are subscribed to.
- */
-void HELPER(plugin_vcpu_udata_cb_no_wg)(uint32_t cpu_index, void *udata)
-{ }
-
-void HELPER(plugin_vcpu_udata_cb_no_rwg)(uint32_t cpu_index, void *udata)
-{ }
-
-void HELPER(plugin_vcpu_mem_cb)(unsigned int vcpu_index,
- qemu_plugin_meminfo_t info, uint64_t vaddr,
- void *userdata)
-{ }
-
static void plugin_gen_empty_callback(enum plugin_gen_from from)
{
switch (from) {
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 12/20] tcg: Remove TCG_CALL_PLUGIN
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (10 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 11/20] plugins: Remove plugin helpers Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 13/20] tcg: Remove INDEX_op_plugin_cb_{start,end} Richard Henderson
` (7 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Since we no longer emit plugin helpers during the initial code
translation phase, we don't need to specially mark plugin helpers.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg.h | 2 --
plugins/core.c | 10 ++++------
tcg/tcg.c | 4 +---
3 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 8d9f6585ff..196e3b7ba1 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -353,8 +353,6 @@ typedef TCGv_ptr TCGv_env;
#define TCG_CALL_NO_SIDE_EFFECTS 0x0004
/* Helper is G_NORETURN. */
#define TCG_CALL_NO_RETURN 0x0008
-/* Helper is part of Plugins. */
-#define TCG_CALL_PLUGIN 0x0010
/* convenience version of most used call flags */
#define TCG_CALL_NO_RWG TCG_CALL_NO_READ_GLOBALS
diff --git a/plugins/core.c b/plugins/core.c
index b0a2e80874..b0615f1e7f 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -339,9 +339,8 @@ void plugin_register_dyn_cb__udata(GArray **arr,
void *udata)
{
static TCGHelperInfo info[3] = {
- [QEMU_PLUGIN_CB_NO_REGS].flags = TCG_CALL_NO_RWG | TCG_CALL_PLUGIN,
- [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG | TCG_CALL_PLUGIN,
- [QEMU_PLUGIN_CB_RW_REGS].flags = TCG_CALL_PLUGIN,
+ [QEMU_PLUGIN_CB_NO_REGS].flags = TCG_CALL_NO_RWG,
+ [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG,
/*
* Match qemu_plugin_vcpu_udata_cb_t:
* void (*)(uint32_t, void *)
@@ -375,9 +374,8 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
!__builtin_types_compatible_p(qemu_plugin_meminfo_t, int32_t));
static TCGHelperInfo info[3] = {
- [QEMU_PLUGIN_CB_NO_REGS].flags = TCG_CALL_NO_RWG | TCG_CALL_PLUGIN,
- [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG | TCG_CALL_PLUGIN,
- [QEMU_PLUGIN_CB_RW_REGS].flags = TCG_CALL_PLUGIN,
+ [QEMU_PLUGIN_CB_NO_REGS].flags = TCG_CALL_NO_RWG,
+ [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG,
/*
* Match qemu_plugin_vcpu_mem_cb_t:
* void (*)(uint32_t, qemu_plugin_meminfo_t, uint64_t, void *)
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0bf218314b..363a065e28 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2269,9 +2269,7 @@ static void tcg_gen_callN(void *func, TCGHelperInfo *info,
#ifdef CONFIG_PLUGIN
/* Flag helpers that may affect guest state */
- if (tcg_ctx->plugin_insn &&
- !(info->flags & TCG_CALL_PLUGIN) &&
- !(info->flags & TCG_CALL_NO_SIDE_EFFECTS)) {
+ if (tcg_ctx->plugin_insn && !(info->flags & TCG_CALL_NO_SIDE_EFFECTS)) {
tcg_ctx->plugin_insn->calls_helpers = true;
}
#endif
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 13/20] tcg: Remove INDEX_op_plugin_cb_{start,end}
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (11 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 12/20] tcg: Remove TCG_CALL_PLUGIN Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 14/20] plugins: Simplify callback queues Richard Henderson
` (6 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
These opcodes are no longer used.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/tcg/tcg-op-common.h | 2 --
include/tcg/tcg-opc.h | 2 --
accel/tcg/plugin-gen.c | 18 ------------------
tcg/tcg-op.c | 10 ----------
4 files changed, 32 deletions(-)
diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
index 72b80b20d0..009e2778c5 100644
--- a/include/tcg/tcg-op-common.h
+++ b/include/tcg/tcg-op-common.h
@@ -76,8 +76,6 @@ void tcg_gen_lookup_and_goto_ptr(void);
void tcg_gen_plugin_cb(unsigned from);
void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo);
-void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr);
-void tcg_gen_plugin_cb_end(void);
/* 32 bit ops */
diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
index be9e36e386..546eb49c11 100644
--- a/include/tcg/tcg-opc.h
+++ b/include/tcg/tcg-opc.h
@@ -199,8 +199,6 @@ DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
DEF(plugin_mem_cb, 0, 1, 1, TCG_OPF_NOT_PRESENT)
-DEF(plugin_cb_start, 0, 0, 3, TCG_OPF_NOT_PRESENT)
-DEF(plugin_cb_end, 0, 0, 0, TCG_OPF_NOT_PRESENT)
/* Replicate ld/st ops for 32 and 64-bit guest addresses. */
DEF(qemu_ld_a32_i32, 1, 1, 1,
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index fb77585ac0..d9ee9bb2ec 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -52,29 +52,11 @@
#include "exec/plugin-gen.h"
#include "exec/translator.h"
-/*
- * plugin_cb_start TCG op args[]:
- * 0: enum plugin_gen_from
- * 1: enum plugin_gen_cb
- * 2: set to 1 for mem callback that is a write, 0 otherwise.
- */
-
enum plugin_gen_from {
PLUGIN_GEN_FROM_TB,
PLUGIN_GEN_FROM_INSN,
PLUGIN_GEN_AFTER_INSN,
PLUGIN_GEN_AFTER_TB,
- PLUGIN_GEN_N_FROMS,
-};
-
-enum plugin_gen_cb {
- PLUGIN_GEN_CB_UDATA,
- PLUGIN_GEN_CB_UDATA_R,
- PLUGIN_GEN_CB_INLINE,
- PLUGIN_GEN_CB_MEM,
- PLUGIN_GEN_ENABLE_MEM_HELPER,
- PLUGIN_GEN_DISABLE_MEM_HELPER,
- PLUGIN_GEN_N_CBS,
};
static void plugin_gen_empty_callback(enum plugin_gen_from from)
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 0ae12fa49d..eff3728622 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -322,16 +322,6 @@ void tcg_gen_plugin_mem_cb(TCGv_i64 addr, unsigned meminfo)
tcg_gen_op2(INDEX_op_plugin_mem_cb, tcgv_i64_arg(addr), meminfo);
}
-void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr)
-{
- tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
-}
-
-void tcg_gen_plugin_cb_end(void)
-{
- tcg_emit_op(INDEX_op_plugin_cb_end, 0);
-}
-
/* 32 bit ops */
void tcg_gen_discard_i32(TCGv_i32 arg)
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 14/20] plugins: Simplify callback queues
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (12 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 13/20] tcg: Remove INDEX_op_plugin_cb_{start,end} Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 15/20] plugins: Introduce PLUGIN_CB_MEM_REGULAR Richard Henderson
` (5 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
We have qemu_plugin_dyn_cb.type to differentiate the various
callback types, so we do not need to keep them in separate queues.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/plugin.h | 35 ++++++----------
accel/tcg/plugin-gen.c | 90 ++++++++++++++++++++++--------------------
plugins/api.c | 18 +++------
3 files changed, 65 insertions(+), 78 deletions(-)
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index ee1c1b174a..cf9758be55 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -66,15 +66,8 @@ union qemu_plugin_cb_sig {
};
enum plugin_dyn_cb_type {
- PLUGIN_CB_INSN,
- PLUGIN_CB_MEM,
- PLUGIN_N_CB_TYPES,
-};
-
-enum plugin_dyn_cb_subtype {
PLUGIN_CB_REGULAR,
PLUGIN_CB_INLINE,
- PLUGIN_N_CB_SUBTYPES,
};
/*
@@ -84,7 +77,7 @@ enum plugin_dyn_cb_subtype {
*/
struct qemu_plugin_dyn_cb {
void *userp;
- enum plugin_dyn_cb_subtype type;
+ enum plugin_dyn_cb_type type;
/* @rw applies to mem callbacks only (both regular and inline) */
enum qemu_plugin_mem_rw rw;
/* fields specific to each dyn_cb type go here */
@@ -106,7 +99,8 @@ struct qemu_plugin_insn {
GByteArray *data;
uint64_t vaddr;
void *haddr;
- GArray *cbs[PLUGIN_N_CB_TYPES][PLUGIN_N_CB_SUBTYPES];
+ GArray *insn_cbs;
+ GArray *mem_cbs;
bool calls_helpers;
/* if set, the instruction calls helpers that might access guest memory */
@@ -135,16 +129,9 @@ static inline void qemu_plugin_insn_cleanup_fn(gpointer data)
static inline struct qemu_plugin_insn *qemu_plugin_insn_alloc(void)
{
- int i, j;
struct qemu_plugin_insn *insn = g_new0(struct qemu_plugin_insn, 1);
- insn->data = g_byte_array_sized_new(4);
- for (i = 0; i < PLUGIN_N_CB_TYPES; i++) {
- for (j = 0; j < PLUGIN_N_CB_SUBTYPES; j++) {
- insn->cbs[i][j] = g_array_new(false, false,
- sizeof(struct qemu_plugin_dyn_cb));
- }
- }
+ insn->data = g_byte_array_sized_new(4);
return insn;
}
@@ -161,7 +148,7 @@ struct qemu_plugin_tb {
/* if set, the TB calls helpers that might access guest memory */
bool mem_helper;
- GArray *cbs[PLUGIN_N_CB_SUBTYPES];
+ GArray *cbs;
};
/**
@@ -174,22 +161,22 @@ struct qemu_plugin_insn *qemu_plugin_tb_insn_get(struct qemu_plugin_tb *tb,
uint64_t pc)
{
struct qemu_plugin_insn *insn;
- int i, j;
if (unlikely(tb->n == tb->insns->len)) {
struct qemu_plugin_insn *new_insn = qemu_plugin_insn_alloc();
g_ptr_array_add(tb->insns, new_insn);
}
+
insn = g_ptr_array_index(tb->insns, tb->n++);
g_byte_array_set_size(insn->data, 0);
insn->calls_helpers = false;
insn->mem_helper = false;
insn->vaddr = pc;
-
- for (i = 0; i < PLUGIN_N_CB_TYPES; i++) {
- for (j = 0; j < PLUGIN_N_CB_SUBTYPES; j++) {
- g_array_set_size(insn->cbs[i][j], 0);
- }
+ if (insn->insn_cbs) {
+ g_array_set_size(insn->insn_cbs, 0);
+ }
+ if (insn->mem_cbs) {
+ g_array_set_size(insn->mem_cbs, 0);
}
return insn;
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index d9ee9bb2ec..e77ff2a565 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -83,9 +83,8 @@ void plugin_gen_disable_mem_helpers(void)
static void gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
struct qemu_plugin_insn *insn)
{
- GArray *cbs[2];
GArray *arr;
- size_t n_cbs;
+ size_t len;
/*
* Tracking memory accesses performed from helpers requires extra work.
@@ -104,22 +103,25 @@ static void gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
return;
}
- cbs[0] = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR];
- cbs[1] = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE];
- n_cbs = cbs[0]->len + cbs[1]->len;
-
- if (n_cbs == 0) {
+ if (!insn->mem_cbs || !insn->mem_cbs->len) {
insn->mem_helper = false;
return;
}
insn->mem_helper = true;
ptb->mem_helper = true;
+ /*
+ * 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;
arr = g_array_sized_new(false, false,
- sizeof(struct qemu_plugin_dyn_cb), n_cbs);
- g_array_append_vals(arr, cbs[0]->data, cbs[0]->len);
- g_array_append_vals(arr, cbs[1]->data, cbs[1]->len);
-
+ sizeof(struct qemu_plugin_dyn_cb), len);
+ memcpy(arr->data, insn->mem_cbs->data,
+ len * sizeof(struct qemu_plugin_dyn_cb));
qemu_plugin_add_dyn_cb_arr(arr);
tcg_gen_st_ptr(tcg_constant_ptr((intptr_t)arr), tcg_env,
@@ -288,18 +290,21 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
case PLUGIN_GEN_FROM_TB:
assert(insn == NULL);
- cbs = plugin_tb->cbs[PLUGIN_CB_REGULAR];
+ cbs = plugin_tb->cbs;
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
struct qemu_plugin_dyn_cb *cb =
&g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
- gen_udata_cb(cb);
- }
- cbs = plugin_tb->cbs[PLUGIN_CB_INLINE];
- for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
- gen_inline_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();
+ }
}
break;
@@ -308,18 +313,21 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
gen_enable_mem_helper(plugin_tb, insn);
- cbs = insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR];
+ cbs = insn->insn_cbs;
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
struct qemu_plugin_dyn_cb *cb =
&g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
- gen_udata_cb(cb);
- }
- cbs = insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_INLINE];
- for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
- gen_inline_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();
+ }
}
break;
@@ -346,21 +354,22 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
tcg_ctx->emit_before_op = op;
- cbs = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR];
+ cbs = insn->mem_cbs;
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
struct qemu_plugin_dyn_cb *cb =
&g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
- if (cb->rw & rw) {
- gen_mem_cb(cb, meminfo, addr);
- }
- }
- cbs = insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE];
- for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
if (cb->rw & rw) {
- gen_inline_cb(cb);
+ switch (cb->type) {
+ case PLUGIN_CB_REGULAR:
+ gen_mem_cb(cb, meminfo, addr);
+ break;
+ case PLUGIN_CB_INLINE:
+ gen_inline_cb(cb);
+ break;
+ default:
+ g_assert_not_reached();
+ }
}
}
@@ -384,13 +393,10 @@ bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
if (test_bit(QEMU_PLUGIN_EV_VCPU_TB_TRANS, cpu->plugin_state->event_mask)) {
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
- int i;
/* reset callbacks */
- for (i = 0; i < PLUGIN_N_CB_SUBTYPES; i++) {
- if (ptb->cbs[i]) {
- g_array_set_size(ptb->cbs[i], 0);
- }
+ if (ptb->cbs) {
+ g_array_set_size(ptb->cbs, 0);
}
ptb->n = 0;
diff --git a/plugins/api.c b/plugins/api.c
index 29cce2d97c..3912c9cc8f 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -92,8 +92,7 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
void *udata)
{
if (!tb->mem_only) {
- plugin_register_dyn_cb__udata(&tb->cbs[PLUGIN_CB_REGULAR],
- cb, flags, udata);
+ plugin_register_dyn_cb__udata(&tb->cbs, cb, flags, udata);
}
}
@@ -104,8 +103,7 @@ 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);
+ plugin_register_inline_op_on_entry(&tb->cbs, 0, op, entry, imm);
}
}
@@ -115,8 +113,7 @@ void qemu_plugin_register_vcpu_insn_exec_cb(struct qemu_plugin_insn *insn,
void *udata)
{
if (!insn->mem_only) {
- plugin_register_dyn_cb__udata(
- &insn->cbs[PLUGIN_CB_INSN][PLUGIN_CB_REGULAR], cb, flags, udata);
+ plugin_register_dyn_cb__udata(&insn->insn_cbs, cb, flags, udata);
}
}
@@ -127,8 +124,7 @@ 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);
+ plugin_register_inline_op_on_entry(&insn->insn_cbs, 0, op, entry, imm);
}
}
@@ -143,8 +139,7 @@ void qemu_plugin_register_vcpu_mem_cb(struct qemu_plugin_insn *insn,
enum qemu_plugin_mem_rw rw,
void *udata)
{
- plugin_register_vcpu_mem_cb(&insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_REGULAR],
- cb, flags, rw, udata);
+ plugin_register_vcpu_mem_cb(&insn->mem_cbs, cb, flags, rw, udata);
}
void qemu_plugin_register_vcpu_mem_inline_per_vcpu(
@@ -154,8 +149,7 @@ void qemu_plugin_register_vcpu_mem_inline_per_vcpu(
qemu_plugin_u64 entry,
uint64_t imm)
{
- plugin_register_inline_op_on_entry(
- &insn->cbs[PLUGIN_CB_MEM][PLUGIN_CB_INLINE], rw, op, entry, imm);
+ plugin_register_inline_op_on_entry(&insn->mem_cbs, rw, op, entry, imm);
}
void qemu_plugin_register_vcpu_tb_trans_cb(qemu_plugin_id_t id,
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 15/20] plugins: Introduce PLUGIN_CB_MEM_REGULAR
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (13 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 14/20] plugins: Simplify callback queues Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 16/20] plugins: Replace pr_ops with a proper debug dump flag Richard Henderson
` (4 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Use different enumerators for vcpu_udata and vcpu_mem callbacks.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/plugin.h | 1 +
accel/tcg/plugin-gen.c | 2 +-
plugins/core.c | 4 ++--
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index cf9758be55..34498da717 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -67,6 +67,7 @@ union qemu_plugin_cb_sig {
enum plugin_dyn_cb_type {
PLUGIN_CB_REGULAR,
+ PLUGIN_CB_MEM_REGULAR,
PLUGIN_CB_INLINE,
};
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index e77ff2a565..c545303956 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -361,7 +361,7 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
if (cb->rw & rw) {
switch (cb->type) {
- case PLUGIN_CB_REGULAR:
+ case PLUGIN_CB_MEM_REGULAR:
gen_mem_cb(cb, meminfo, addr);
break;
case PLUGIN_CB_INLINE:
diff --git a/plugins/core.c b/plugins/core.c
index b0615f1e7f..0213513ec6 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -391,7 +391,7 @@ void plugin_register_vcpu_mem_cb(GArray **arr,
struct qemu_plugin_dyn_cb *dyn_cb = plugin_get_dyn_cb(arr);
dyn_cb->userp = udata;
- dyn_cb->type = PLUGIN_CB_REGULAR;
+ dyn_cb->type = PLUGIN_CB_MEM_REGULAR;
dyn_cb->rw = rw;
dyn_cb->regular.f.vcpu_mem = cb;
@@ -547,7 +547,7 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
break;
}
switch (cb->type) {
- case PLUGIN_CB_REGULAR:
+ case PLUGIN_CB_MEM_REGULAR:
cb->regular.f.vcpu_mem(cpu->cpu_index, make_plugin_meminfo(oi, rw),
vaddr, cb->userp);
break;
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 16/20] plugins: Replace pr_ops with a proper debug dump flag
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (14 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 15/20] plugins: Introduce PLUGIN_CB_MEM_REGULAR Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 17/20] plugins: Split out common cb expanders Richard Henderson
` (3 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
The DEBUG_PLUGIN_GEN_OPS ifdef is replaced with "-d op_plugin".
The second pr_ops call can be obtained with "-d op".
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/log.h | 1 +
include/tcg/tcg.h | 1 +
accel/tcg/plugin-gen.c | 67 +++++++-----------------------------------
tcg/tcg.c | 29 +++++++++++++++++-
util/log.c | 4 +++
5 files changed, 45 insertions(+), 57 deletions(-)
diff --git a/include/qemu/log.h b/include/qemu/log.h
index df59bfabcd..e10e24cd4f 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -36,6 +36,7 @@ bool qemu_log_separate(void);
#define LOG_STRACE (1 << 19)
#define LOG_PER_THREAD (1 << 20)
#define CPU_LOG_TB_VPU (1 << 21)
+#define LOG_TB_OP_PLUGIN (1 << 22)
/* Lock/unlock output. */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 196e3b7ba1..135e36d729 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -1070,5 +1070,6 @@ static inline const TCGOpcode *tcg_swap_vecop_list(const TCGOpcode *n)
}
bool tcg_can_emit_vecop_list(const TCGOpcode *, TCGType, unsigned);
+void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs);
#endif /* TCG_H */
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index c545303956..49d9b07438 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -44,6 +44,7 @@
*/
#include "qemu/osdep.h"
#include "qemu/plugin.h"
+#include "qemu/log.h"
#include "cpu.h"
#include "tcg/tcg.h"
#include "tcg/tcg-temp-internal.h"
@@ -186,66 +187,21 @@ static void gen_mem_cb(struct qemu_plugin_dyn_cb *cb,
tcg_temp_free_i32(cpu_index);
}
-/* #define DEBUG_PLUGIN_GEN_OPS */
-static void pr_ops(void)
-{
-#ifdef DEBUG_PLUGIN_GEN_OPS
- TCGOp *op;
- int i = 0;
-
- QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
- const char *name = "";
- const char *type = "";
-
- if (op->opc == INDEX_op_plugin_cb_start) {
- switch (op->args[0]) {
- case PLUGIN_GEN_FROM_TB:
- name = "tb";
- break;
- case PLUGIN_GEN_FROM_INSN:
- name = "insn";
- break;
- case PLUGIN_GEN_FROM_MEM:
- name = "mem";
- break;
- case PLUGIN_GEN_AFTER_INSN:
- name = "after insn";
- break;
- default:
- break;
- }
- switch (op->args[1]) {
- case PLUGIN_GEN_CB_UDATA:
- type = "udata";
- break;
- case PLUGIN_GEN_CB_INLINE:
- type = "inline";
- break;
- case PLUGIN_GEN_CB_MEM:
- type = "mem";
- break;
- case PLUGIN_GEN_ENABLE_MEM_HELPER:
- type = "enable mem helper";
- break;
- case PLUGIN_GEN_DISABLE_MEM_HELPER:
- type = "disable mem helper";
- break;
- default:
- break;
- }
- }
- printf("op[%2i]: %s %s %s\n", i, tcg_op_defs[op->opc].name, name, type);
- i++;
- }
-#endif
-}
-
static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
{
TCGOp *op, *next;
int insn_idx = -1;
- pr_ops();
+ 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);
+ }
+ }
/*
* While injecting code, we cannot afford to reuse any ebb temps
@@ -383,7 +339,6 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
break;
}
}
- pr_ops();
}
bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 363a065e28..d248c52e96 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2540,6 +2540,15 @@ static const char bswap_flag_name[][6] = {
[TCG_BSWAP_IZ | TCG_BSWAP_OS] = "iz,os",
};
+#ifdef CONFIG_PLUGIN
+static const char * const plugin_from_name[] = {
+ "from-tb",
+ "from-insn",
+ "after-insn",
+ "after-tb",
+};
+#endif
+
static inline bool tcg_regset_single(TCGRegSet d)
{
return (d & (d - 1)) == 0;
@@ -2558,7 +2567,7 @@ static inline TCGReg tcg_regset_first(TCGRegSet d)
#define ne_fprintf(...) \
({ int ret_ = fprintf(__VA_ARGS__); ret_ >= 0 ? ret_ : 0; })
-static void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
+void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
{
char buf[128];
TCGOp *op;
@@ -2714,6 +2723,24 @@ static void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs)
i = k = 1;
}
break;
+#ifdef CONFIG_PLUGIN
+ case INDEX_op_plugin_cb:
+ {
+ TCGArg from = op->args[k++];
+ const char *name = NULL;
+
+ if (from < ARRAY_SIZE(plugin_from_name)) {
+ name = plugin_from_name[from];
+ }
+ if (name) {
+ col += ne_fprintf(f, "%s", name);
+ } else {
+ col += ne_fprintf(f, "$0x%" TCG_PRIlx, from);
+ }
+ i = 1;
+ }
+ break;
+#endif
default:
i = 0;
break;
diff --git a/util/log.c b/util/log.c
index d36c98da0b..6219819855 100644
--- a/util/log.c
+++ b/util/log.c
@@ -466,6 +466,10 @@ const QEMULogItem qemu_log_items[] = {
"show micro ops after optimization" },
{ CPU_LOG_TB_OP_IND, "op_ind",
"show micro ops before indirect lowering" },
+#ifdef CONFIG_PLUGIN
+ { LOG_TB_OP_PLUGIN, "op_plugin",
+ "show micro ops before plugin injection" },
+#endif
{ CPU_LOG_INT, "int",
"show interrupts/exceptions in short format" },
{ CPU_LOG_EXEC, "exec",
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 17/20] plugins: Split out common cb expanders
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (15 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 16/20] plugins: Replace pr_ops with a proper debug dump flag Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 18/20] plugins: Merge qemu_plugin_tb_insn_get to plugin-gen.c Richard Henderson
` (2 subsequent siblings)
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-gen.c | 84 +++++++++++++++++++++---------------------
1 file changed, 41 insertions(+), 43 deletions(-)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 49d9b07438..5b63b93114 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -187,6 +187,37 @@ static void gen_mem_cb(struct qemu_plugin_dyn_cb *cb,
tcg_temp_free_i32(cpu_index);
}
+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;
+ }
+ }
+}
+
static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
{
TCGOp *op, *next;
@@ -248,19 +279,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
cbs = plugin_tb->cbs;
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
-
- 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();
- }
+ inject_cb(
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i));
}
break;
@@ -271,19 +291,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
cbs = insn->insn_cbs;
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
-
- 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();
- }
+ inject_cb(
+ &g_array_index(cbs, struct qemu_plugin_dyn_cb, i));
}
break;
@@ -300,33 +309,22 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
{
TCGv_i64 addr = temp_tcgv_i64(arg_temp(op->args[0]));
qemu_plugin_meminfo_t meminfo = op->args[1];
+ enum qemu_plugin_mem_rw rw =
+ (qemu_plugin_mem_is_store(meminfo)
+ ? QEMU_PLUGIN_MEM_W : QEMU_PLUGIN_MEM_R);
struct qemu_plugin_insn *insn;
const GArray *cbs;
- int i, n, rw;
+ int i, n;
assert(insn_idx >= 0);
insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
- rw = qemu_plugin_mem_is_store(meminfo) ? 2 : 1;
tcg_ctx->emit_before_op = op;
cbs = insn->mem_cbs;
for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
- struct qemu_plugin_dyn_cb *cb =
- &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
-
- if (cb->rw & rw) {
- switch (cb->type) {
- case PLUGIN_CB_MEM_REGULAR:
- gen_mem_cb(cb, meminfo, addr);
- break;
- case PLUGIN_CB_INLINE:
- gen_inline_cb(cb);
- break;
- default:
- g_assert_not_reached();
- }
- }
+ inject_mem_cb(&g_array_index(cbs, struct qemu_plugin_dyn_cb, i),
+ rw, meminfo, addr);
}
tcg_ctx->emit_before_op = NULL;
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 18/20] plugins: Merge qemu_plugin_tb_insn_get to plugin-gen.c
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (16 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 17/20] plugins: Split out common cb expanders Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 19/20] plugins: Inline plugin_gen_empty_callback Richard Henderson
2024-04-24 23:02 ` [PATCH v3 20/20] plugins: Update the documentation block for plugin-gen.c Richard Henderson
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Merge qemu_plugin_insn_alloc and qemu_plugin_tb_insn_get into
plugin_gen_insn_start, since it is used nowhere else.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/plugin.h | 39 ---------------------------------------
accel/tcg/plugin-gen.c | 39 ++++++++++++++++++++++++++++++++-------
2 files changed, 32 insertions(+), 46 deletions(-)
diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h
index 34498da717..07b1755990 100644
--- a/include/qemu/plugin.h
+++ b/include/qemu/plugin.h
@@ -128,14 +128,6 @@ static inline void qemu_plugin_insn_cleanup_fn(gpointer data)
g_byte_array_free(insn->data, true);
}
-static inline struct qemu_plugin_insn *qemu_plugin_insn_alloc(void)
-{
- struct qemu_plugin_insn *insn = g_new0(struct qemu_plugin_insn, 1);
-
- insn->data = g_byte_array_sized_new(4);
- return insn;
-}
-
/* Internal context for this TranslationBlock */
struct qemu_plugin_tb {
GPtrArray *insns;
@@ -152,37 +144,6 @@ struct qemu_plugin_tb {
GArray *cbs;
};
-/**
- * qemu_plugin_tb_insn_get(): get next plugin record for translation.
- * @tb: the internal tb context
- * @pc: address of instruction
- */
-static inline
-struct qemu_plugin_insn *qemu_plugin_tb_insn_get(struct qemu_plugin_tb *tb,
- uint64_t pc)
-{
- struct qemu_plugin_insn *insn;
-
- if (unlikely(tb->n == tb->insns->len)) {
- struct qemu_plugin_insn *new_insn = qemu_plugin_insn_alloc();
- g_ptr_array_add(tb->insns, new_insn);
- }
-
- insn = g_ptr_array_index(tb->insns, tb->n++);
- g_byte_array_set_size(insn->data, 0);
- insn->calls_helpers = false;
- insn->mem_helper = false;
- insn->vaddr = pc;
- if (insn->insn_cbs) {
- g_array_set_size(insn->insn_cbs, 0);
- }
- if (insn->mem_cbs) {
- g_array_set_size(insn->mem_cbs, 0);
- }
-
- return insn;
-}
-
/**
* struct CPUPluginState - per-CPU state for plugins
* @event_mask: plugin event bitmap. Modified only via async work.
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index 5b63b93114..c0cbc26984 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -373,11 +373,34 @@ bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
void plugin_gen_insn_start(CPUState *cpu, const DisasContextBase *db)
{
struct qemu_plugin_tb *ptb = tcg_ctx->plugin_tb;
- struct qemu_plugin_insn *pinsn;
+ struct qemu_plugin_insn *insn;
+ size_t n = db->num_insns;
+ vaddr pc;
- pinsn = qemu_plugin_tb_insn_get(ptb, db->pc_next);
- tcg_ctx->plugin_insn = pinsn;
- plugin_gen_empty_callback(PLUGIN_GEN_FROM_INSN);
+ 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);
+ }
+
+ 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;
/*
* Detect page crossing to get the new host address.
@@ -385,16 +408,18 @@ void plugin_gen_insn_start(CPUState *cpu, const DisasContextBase *db)
* fetching instructions from a region not backed by RAM.
*/
if (ptb->haddr1 == NULL) {
- pinsn->haddr = NULL;
+ insn->haddr = NULL;
} else if (is_same_page(db, db->pc_next)) {
- pinsn->haddr = ptb->haddr1 + pinsn->vaddr - ptb->vaddr;
+ insn->haddr = ptb->haddr1 + pc - ptb->vaddr;
} else {
if (ptb->vaddr2 == -1) {
ptb->vaddr2 = TARGET_PAGE_ALIGN(db->pc_first);
get_page_addr_code_hostp(cpu_env(cpu), ptb->vaddr2, &ptb->haddr2);
}
- pinsn->haddr = ptb->haddr2 + pinsn->vaddr - ptb->vaddr2;
+ insn->haddr = ptb->haddr2 + pc - ptb->vaddr2;
}
+
+ plugin_gen_empty_callback(PLUGIN_GEN_FROM_INSN);
}
void plugin_gen_insn_end(void)
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 19/20] plugins: Inline plugin_gen_empty_callback
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (17 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 18/20] plugins: Merge qemu_plugin_tb_insn_get to plugin-gen.c Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
2024-04-24 23:02 ` [PATCH v3 20/20] plugins: Update the documentation block for plugin-gen.c Richard Henderson
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Alex Bennée
Each caller can use tcg_gen_plugin_cb directly.
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-gen.c | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index c0cbc26984..d914d64de0 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -60,19 +60,6 @@ enum plugin_gen_from {
PLUGIN_GEN_AFTER_TB,
};
-static void plugin_gen_empty_callback(enum plugin_gen_from from)
-{
- switch (from) {
- case PLUGIN_GEN_AFTER_INSN:
- case PLUGIN_GEN_FROM_TB:
- case PLUGIN_GEN_FROM_INSN:
- tcg_gen_plugin_cb(from);
- 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)
{
@@ -362,7 +349,7 @@ bool plugin_gen_tb_start(CPUState *cpu, const DisasContextBase *db,
ptb->mem_only = mem_only;
ptb->mem_helper = false;
- plugin_gen_empty_callback(PLUGIN_GEN_FROM_TB);
+ tcg_gen_plugin_cb(PLUGIN_GEN_FROM_TB);
}
tcg_ctx->plugin_insn = NULL;
@@ -419,12 +406,12 @@ void plugin_gen_insn_start(CPUState *cpu, const DisasContextBase *db)
insn->haddr = ptb->haddr2 + pc - ptb->vaddr2;
}
- plugin_gen_empty_callback(PLUGIN_GEN_FROM_INSN);
+ tcg_gen_plugin_cb(PLUGIN_GEN_FROM_INSN);
}
void plugin_gen_insn_end(void)
{
- plugin_gen_empty_callback(PLUGIN_GEN_AFTER_INSN);
+ tcg_gen_plugin_cb(PLUGIN_GEN_AFTER_INSN);
}
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH v3 20/20] plugins: Update the documentation block for plugin-gen.c
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
` (18 preceding siblings ...)
2024-04-24 23:02 ` [PATCH v3 19/20] plugins: Inline plugin_gen_empty_callback Richard Henderson
@ 2024-04-24 23:02 ` Richard Henderson
19 siblings, 0 replies; 26+ messages in thread
From: Richard Henderson @ 2024-04-24 23:02 UTC (permalink / raw)
To: qemu-devel; +Cc: Pierrick Bouvier
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/plugin-gen.c | 31 ++++---------------------------
1 file changed, 4 insertions(+), 27 deletions(-)
diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
index d914d64de0..3db74ae9bf 100644
--- a/accel/tcg/plugin-gen.c
+++ b/accel/tcg/plugin-gen.c
@@ -14,33 +14,10 @@
* 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.
+ * Instead, during TB translation we add "plugin_cb" marker opcodes
+ * for all possible instrumentation events, and then once we collect the
+ * instrumentation requests from plugins, we generate code for those markers
+ * or remove them if they have no requests.
*/
#include "qemu/osdep.h"
#include "qemu/plugin.h"
--
2.34.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained
2024-04-24 23:02 ` [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained Richard Henderson
@ 2024-04-29 10:57 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-29 10:57 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Alex Bennée
On 25/4/24 01:02, Richard Henderson wrote:
> Move MAX_CALL_IARGS from tcg.h and include for
> the define of TCG_TARGET_REG_BITS.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/tcg/helper-info.h | 3 +++
> include/tcg/tcg.h | 2 --
> tcg/tci.c | 1 +
> 3 files changed, 4 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 04/20] plugins: Move function pointer in qemu_plugin_dyn_cb
2024-04-24 23:02 ` [PATCH v3 04/20] plugins: Move function pointer in qemu_plugin_dyn_cb Richard Henderson
@ 2024-04-29 10:58 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-29 10:58 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Alex Bennée
On 25/4/24 01:02, Richard Henderson wrote:
> The out-of-line function pointer is mutually exclusive
> with inline expansion, so move it into the union.
> Wrap the pointer in a structure named 'regular' to match
> PLUGIN_CB_REGULAR.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/qemu/plugin.h | 4 +++-
> accel/tcg/plugin-gen.c | 4 ++--
> plugins/core.c | 8 ++++----
> 3 files changed, 9 insertions(+), 7 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 02/20] tcg: Pass function pointer to tcg_gen_call*
2024-04-24 23:02 ` [PATCH v3 02/20] tcg: Pass function pointer to tcg_gen_call* Richard Henderson
@ 2024-04-29 11:00 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 26+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-04-29 11:00 UTC (permalink / raw)
To: Richard Henderson, qemu-devel; +Cc: Alex Bennée
On 25/4/24 01:02, Richard Henderson wrote:
> For normal helpers, read the function pointer from the
> structure earlier. For plugins, this will allow the
> function pointer to come from elsewhere.
>
> Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/tcg/tcg.h | 21 +++++++++-------
> include/exec/helper-gen.h.inc | 24 ++++++++++++-------
> tcg/tcg.c | 45 +++++++++++++++++++----------------
> 3 files changed, 52 insertions(+), 38 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 06/20] plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN
2024-04-24 23:02 ` [PATCH v3 06/20] plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN Richard Henderson
@ 2024-04-29 19:56 ` Pierrick Bouvier
0 siblings, 0 replies; 26+ messages in thread
From: Pierrick Bouvier @ 2024-04-29 19:56 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 4/24/24 16:02, Richard Henderson wrote:
> Introduce a new plugin_cb op and migrate one operation.
> By using emit_before_op, we do not need to emit opcodes
> early and modify them later -- we can simply emit the
> final set of opcodes once.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> include/tcg/tcg-op-common.h | 1 +
> include/tcg/tcg-opc.h | 1 +
> accel/tcg/plugin-gen.c | 74 +++++++++++++++++++++----------------
> tcg/tcg-op.c | 5 +++
> 4 files changed, 50 insertions(+), 31 deletions(-)
>
> diff --git a/include/tcg/tcg-op-common.h b/include/tcg/tcg-op-common.h
> index 2d932a515e..9de5a7f280 100644
> --- a/include/tcg/tcg-op-common.h
> +++ b/include/tcg/tcg-op-common.h
> @@ -74,6 +74,7 @@ void tcg_gen_goto_tb(unsigned idx);
> */
> void tcg_gen_lookup_and_goto_ptr(void);
>
> +void tcg_gen_plugin_cb(unsigned from);
> void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr);
> void tcg_gen_plugin_cb_end(void);
>
> diff --git a/include/tcg/tcg-opc.h b/include/tcg/tcg-opc.h
> index b80227fa1c..3b7cb2bce1 100644
> --- a/include/tcg/tcg-opc.h
> +++ b/include/tcg/tcg-opc.h
> @@ -197,6 +197,7 @@ DEF(exit_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
> DEF(goto_tb, 0, 0, 1, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
> DEF(goto_ptr, 0, 1, 0, TCG_OPF_BB_EXIT | TCG_OPF_BB_END)
>
> +DEF(plugin_cb, 0, 0, 1, TCG_OPF_NOT_PRESENT)
> DEF(plugin_cb_start, 0, 0, 3, TCG_OPF_NOT_PRESENT)
> DEF(plugin_cb_end, 0, 0, 0, TCG_OPF_NOT_PRESENT)
>
> diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
> index 4b488943ff..4b02c0bfbf 100644
> --- a/accel/tcg/plugin-gen.c
> +++ b/accel/tcg/plugin-gen.c
> @@ -201,8 +201,7 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
> {
> switch (from) {
> case PLUGIN_GEN_AFTER_INSN:
> - gen_wrapped(from, PLUGIN_GEN_DISABLE_MEM_HELPER,
> - gen_empty_mem_helper);
> + tcg_gen_plugin_cb(from);
> break;
> case PLUGIN_GEN_FROM_INSN:
> /*
> @@ -608,16 +607,6 @@ static void inject_mem_enable_helper(struct qemu_plugin_tb *ptb,
> inject_mem_helper(begin_op, arr);
> }
>
> -static void inject_mem_disable_helper(struct qemu_plugin_insn *plugin_insn,
> - TCGOp *begin_op)
> -{
> - if (likely(!plugin_insn->mem_helper)) {
> - rm_ops(begin_op);
> - return;
> - }
> - inject_mem_helper(begin_op, NULL);
> -}
> -
> /* called before finishing a TB with exit_tb, goto_tb or goto_ptr */
> void plugin_gen_disable_mem_helpers(void)
> {
> @@ -703,11 +692,14 @@ static void plugin_gen_enable_mem_helper(struct qemu_plugin_tb *ptb,
> inject_mem_enable_helper(ptb, insn, begin_op);
> }
>
> -static void plugin_gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
> - TCGOp *begin_op, int insn_idx)
> +static void gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
> + struct qemu_plugin_insn *insn)
> {
> - struct qemu_plugin_insn *insn = g_ptr_array_index(ptb->insns, insn_idx);
> - inject_mem_disable_helper(insn, begin_op);
> + if (insn->mem_helper) {
> + tcg_gen_st_ptr(tcg_constant_ptr(0), tcg_env,
> + offsetof(CPUState, plugin_mem_cbs) -
> + offsetof(ArchCPU, env));
> + }
> }
>
> /* #define DEBUG_PLUGIN_GEN_OPS */
> @@ -766,16 +758,49 @@ static void pr_ops(void)
>
> static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
> {
> - TCGOp *op;
> + TCGOp *op, *next;
> int insn_idx = -1;
>
> pr_ops();
>
> - QTAILQ_FOREACH(op, &tcg_ctx->ops, link) {
> + /*
> + * 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) {
> switch (op->opc) {
> case INDEX_op_insn_start:
> insn_idx++;
> break;
> +
> + case INDEX_op_plugin_cb:
> + {
> + enum plugin_gen_from from = op->args[0];
> + struct qemu_plugin_insn *insn = NULL;
> +
> + if (insn_idx >= 0) {
> + insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
> + }
> +
> + tcg_ctx->emit_before_op = op;
> +
> + switch (from) {
> + case PLUGIN_GEN_AFTER_INSN:
> + assert(insn != NULL);
> + gen_disable_mem_helper(plugin_tb, insn);
> + break;
> + default:
> + g_assert_not_reached();
> + }
> +
> + tcg_ctx->emit_before_op = NULL;
> + tcg_op_remove(tcg_ctx, op);
> + break;
> + }
> +
> case INDEX_op_plugin_cb_start:
> {
> enum plugin_gen_from from = op->args[0];
> @@ -840,19 +865,6 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
>
> break;
> }
> - case PLUGIN_GEN_AFTER_INSN:
> - {
> - g_assert(insn_idx >= 0);
> -
> - switch (type) {
> - case PLUGIN_GEN_DISABLE_MEM_HELPER:
> - plugin_gen_disable_mem_helper(plugin_tb, op, insn_idx);
> - break;
> - default:
> - g_assert_not_reached();
> - }
> - break;
> - }
> default:
> g_assert_not_reached();
> }
> diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
> index aa6bc6f57d..0f2026c91c 100644
> --- a/tcg/tcg-op.c
> +++ b/tcg/tcg-op.c
> @@ -312,6 +312,11 @@ void tcg_gen_mb(TCGBar mb_type)
> }
> }
>
> +void tcg_gen_plugin_cb(unsigned from)
> +{
> + tcg_gen_op1(INDEX_op_plugin_cb, from);
> +}
> +
> void tcg_gen_plugin_cb_start(unsigned from, unsigned type, unsigned wr)
> {
> tcg_gen_op3(INDEX_op_plugin_cb_start, from, type, wr);
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH v3 07/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB
2024-04-24 23:02 ` [PATCH v3 07/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB Richard Henderson
@ 2024-04-29 19:57 ` Pierrick Bouvier
0 siblings, 0 replies; 26+ messages in thread
From: Pierrick Bouvier @ 2024-04-29 19:57 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 4/24/24 16:02, Richard Henderson wrote:
> By having the qemu_plugin_cb_flags be recorded in the TCGHelperInfo,
> we no longer need to distinguish PLUGIN_CB_REGULAR from
> PLUGIN_CB_REGULAR_R, so place all TB callbacks in the same queue.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
> accel/tcg/plugin-gen.c | 96 +++++++++++++++++++++++++-----------------
> plugins/api.c | 6 +--
> 2 files changed, 58 insertions(+), 44 deletions(-)
>
> diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c
> index 4b02c0bfbf..c803fe8e96 100644
> --- a/accel/tcg/plugin-gen.c
> +++ b/accel/tcg/plugin-gen.c
> @@ -201,6 +201,7 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
> {
> switch (from) {
> case PLUGIN_GEN_AFTER_INSN:
> + case PLUGIN_GEN_FROM_TB:
> tcg_gen_plugin_cb(from);
> break;
> case PLUGIN_GEN_FROM_INSN:
> @@ -210,8 +211,6 @@ static void plugin_gen_empty_callback(enum plugin_gen_from from)
> */
> gen_wrapped(from, PLUGIN_GEN_ENABLE_MEM_HELPER,
> gen_empty_mem_helper);
> - /* fall through */
> - case PLUGIN_GEN_FROM_TB:
> 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);
> @@ -626,24 +625,6 @@ void plugin_gen_disable_mem_helpers(void)
> offsetof(CPUState, plugin_mem_cbs) - offsetof(ArchCPU, env));
> }
>
> -static void plugin_gen_tb_udata(const struct qemu_plugin_tb *ptb,
> - TCGOp *begin_op)
> -{
> - inject_udata_cb(ptb->cbs[PLUGIN_CB_REGULAR], begin_op);
> -}
> -
> -static void plugin_gen_tb_udata_r(const struct qemu_plugin_tb *ptb,
> - TCGOp *begin_op)
> -{
> - 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)
> -{
> - inject_inline_cb(ptb->cbs[PLUGIN_CB_INLINE], begin_op, op_ok);
> -}
> -
> static void plugin_gen_insn_udata(const struct qemu_plugin_tb *ptb,
> TCGOp *begin_op, int insn_idx)
> {
> @@ -702,6 +683,41 @@ static void gen_disable_mem_helper(struct qemu_plugin_tb *ptb,
> }
> }
>
> +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);
> +}
> +
> /* #define DEBUG_PLUGIN_GEN_OPS */
> static void pr_ops(void)
> {
> @@ -780,6 +796,8 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
> {
> enum plugin_gen_from from = op->args[0];
> struct qemu_plugin_insn *insn = NULL;
> + const GArray *cbs;
> + int i, n;
>
> if (insn_idx >= 0) {
> insn = g_ptr_array_index(plugin_tb->insns, insn_idx);
> @@ -792,6 +810,25 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
> assert(insn != NULL);
> gen_disable_mem_helper(plugin_tb, insn);
> break;
> +
> + case PLUGIN_GEN_FROM_TB:
> + assert(insn == NULL);
> +
> + cbs = plugin_tb->cbs[PLUGIN_CB_REGULAR];
> + for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
> + struct qemu_plugin_dyn_cb *cb =
> + &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
> + gen_udata_cb(cb);
> + }
> +
> + cbs = plugin_tb->cbs[PLUGIN_CB_INLINE];
> + for (i = 0, n = (cbs ? cbs->len : 0); i < n; i++) {
> + struct qemu_plugin_dyn_cb *cb =
> + &g_array_index(cbs, struct qemu_plugin_dyn_cb, i);
> + gen_inline_cb(cb);
> + }
> + break;
> +
> default:
> g_assert_not_reached();
> }
> @@ -807,25 +844,6 @@ static void plugin_gen_inject(struct qemu_plugin_tb *plugin_tb)
> enum plugin_gen_cb type = op->args[1];
>
> switch (from) {
> - case PLUGIN_GEN_FROM_TB:
> - {
> - g_assert(insn_idx == -1);
> -
> - switch (type) {
> - case PLUGIN_GEN_CB_UDATA:
> - plugin_gen_tb_udata(plugin_tb, op);
> - break;
> - 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);
> - break;
> - default:
> - g_assert_not_reached();
> - }
> - break;
> - }
> case PLUGIN_GEN_FROM_INSN:
> {
> g_assert(insn_idx >= 0);
> diff --git a/plugins/api.c b/plugins/api.c
> index 8fa5a600ac..5d119e8049 100644
> --- a/plugins/api.c
> +++ b/plugins/api.c
> @@ -92,11 +92,7 @@ void qemu_plugin_register_vcpu_tb_exec_cb(struct qemu_plugin_tb *tb,
> void *udata)
> {
> if (!tb->mem_only) {
> - int index = flags == QEMU_PLUGIN_CB_R_REGS ||
> - flags == QEMU_PLUGIN_CB_RW_REGS ?
> - PLUGIN_CB_REGULAR_R : PLUGIN_CB_REGULAR;
> -
> - plugin_register_dyn_cb__udata(&tb->cbs[index],
> + plugin_register_dyn_cb__udata(&tb->cbs[PLUGIN_CB_REGULAR],
> cb, flags, udata);
> }
> }
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2024-04-29 19:57 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-24 23:02 [PATCH v3 00/20] Rewrite plugin code generation Richard Henderson
2024-04-24 23:02 ` [PATCH v3 01/20] tcg: Make tcg/helper-info.h self-contained Richard Henderson
2024-04-29 10:57 ` Philippe Mathieu-Daudé
2024-04-24 23:02 ` [PATCH v3 02/20] tcg: Pass function pointer to tcg_gen_call* Richard Henderson
2024-04-29 11:00 ` Philippe Mathieu-Daudé
2024-04-24 23:02 ` [PATCH v3 03/20] plugins: Zero new qemu_plugin_dyn_cb entries Richard Henderson
2024-04-24 23:02 ` [PATCH v3 04/20] plugins: Move function pointer in qemu_plugin_dyn_cb Richard Henderson
2024-04-29 10:58 ` Philippe Mathieu-Daudé
2024-04-24 23:02 ` [PATCH v3 05/20] plugins: Create TCGHelperInfo for all out-of-line callbacks Richard Henderson
2024-04-24 23:02 ` [PATCH v3 06/20] plugins: Use emit_before_op for PLUGIN_GEN_AFTER_INSN Richard Henderson
2024-04-29 19:56 ` Pierrick Bouvier
2024-04-24 23:02 ` [PATCH v3 07/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_TB Richard Henderson
2024-04-29 19:57 ` Pierrick Bouvier
2024-04-24 23:02 ` [PATCH v3 08/20] plugins: Add PLUGIN_GEN_AFTER_TB Richard Henderson
2024-04-24 23:02 ` [PATCH v3 09/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_INSN Richard Henderson
2024-04-24 23:02 ` [PATCH v3 10/20] plugins: Use emit_before_op for PLUGIN_GEN_FROM_MEM Richard Henderson
2024-04-24 23:02 ` [PATCH v3 11/20] plugins: Remove plugin helpers Richard Henderson
2024-04-24 23:02 ` [PATCH v3 12/20] tcg: Remove TCG_CALL_PLUGIN Richard Henderson
2024-04-24 23:02 ` [PATCH v3 13/20] tcg: Remove INDEX_op_plugin_cb_{start,end} Richard Henderson
2024-04-24 23:02 ` [PATCH v3 14/20] plugins: Simplify callback queues Richard Henderson
2024-04-24 23:02 ` [PATCH v3 15/20] plugins: Introduce PLUGIN_CB_MEM_REGULAR Richard Henderson
2024-04-24 23:02 ` [PATCH v3 16/20] plugins: Replace pr_ops with a proper debug dump flag Richard Henderson
2024-04-24 23:02 ` [PATCH v3 17/20] plugins: Split out common cb expanders Richard Henderson
2024-04-24 23:02 ` [PATCH v3 18/20] plugins: Merge qemu_plugin_tb_insn_get to plugin-gen.c Richard Henderson
2024-04-24 23:02 ` [PATCH v3 19/20] plugins: Inline plugin_gen_empty_callback Richard Henderson
2024-04-24 23:02 ` [PATCH v3 20/20] plugins: Update the documentation block for plugin-gen.c Richard Henderson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.