aboutsummaryrefslogtreecommitdiff
path: root/plugins/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/core.c')
-rw-r--r--plugins/core.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/plugins/core.c b/plugins/core.c
index 09c98382f5..081323dafc 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;
}
@@ -338,12 +338,25 @@ 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,
+ [QEMU_PLUGIN_CB_R_REGS].flags = TCG_CALL_NO_WG,
+ /*
+ * 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->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 +365,38 @@ 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));
+
+ static TCGHelperInfo info[3] = {
+ [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 *)
+ */
+ [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))
+ };
- dyn_cb = plugin_get_dyn_cb(arr);
+ 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->type = PLUGIN_CB_MEM_REGULAR;
dyn_cb->rw = rw;
- dyn_cb->f.generic = cb;
+ dyn_cb->regular.f.vcpu_mem = cb;
+
+ assert((unsigned)flags < ARRAY_SIZE(info));
+ dyn_cb->regular.info = &info[flags];
}
/*
@@ -510,9 +547,9 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
break;
}
switch (cb->type) {
- case PLUGIN_CB_REGULAR:
- cb->f.vcpu_mem(cpu->cpu_index, make_plugin_meminfo(oi, rw),
- vaddr, cb->userp);
+ case PLUGIN_CB_MEM_REGULAR:
+ 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);