mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 20:03:54 -06:00
plugins: Add enforcement of QEMU_PLUGIN_CB flags in register R/W callbacks
This patch adds functionality to enforce the requested QEMU_PLUGIN_CB_ flags level passed when registering a callback function using the plugins API. Each time a callback is about to be invoked, a thread-local variable will be updated with the level that callback requested. Then, called API functions (in particular, the register read and write API) will call qemu_plugin_get_cb_flags() to check the level is at least the level they require. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Signed-off-by: Rowan Hart <rowanbhart@gmail.com> Message-ID: <20250624175351.440780-4-rowanbhart@gmail.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Message-ID: <20250627112512.1880708-8-alex.bennee@linaro.org>
This commit is contained in:
parent
1a92b65859
commit
766e00bd57
6 changed files with 96 additions and 6 deletions
|
@ -15,6 +15,7 @@
|
|||
#include "qemu/lockable.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/plugin.h"
|
||||
#include "qemu/qemu-plugin.h"
|
||||
#include "qemu/queue.h"
|
||||
#include "qemu/rcu_queue.h"
|
||||
#include "qemu/rcu.h"
|
||||
|
@ -266,7 +267,9 @@ static void qemu_plugin_vcpu_init__async(CPUState *cpu, run_on_cpu_data unused)
|
|||
plugin_grow_scoreboards__locked(cpu);
|
||||
qemu_rec_mutex_unlock(&plugin.lock);
|
||||
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_INIT);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
|
||||
void qemu_plugin_vcpu_init_hook(CPUState *cpu)
|
||||
|
@ -279,7 +282,9 @@ void qemu_plugin_vcpu_exit_hook(CPUState *cpu)
|
|||
{
|
||||
bool success;
|
||||
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_EXIT);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
|
||||
assert(cpu->cpu_index != UNASSIGNED_CPU_INDEX);
|
||||
qemu_rec_mutex_lock(&plugin.lock);
|
||||
|
@ -367,6 +372,7 @@ void plugin_register_dyn_cb__udata(GArray **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,
|
||||
[QEMU_PLUGIN_CB_RW_REGS].flags = 0,
|
||||
/*
|
||||
* Match qemu_plugin_vcpu_udata_cb_t:
|
||||
* void (*)(uint32_t, void *)
|
||||
|
@ -396,6 +402,7 @@ void plugin_register_dyn_cond_cb__udata(GArray **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,
|
||||
[QEMU_PLUGIN_CB_RW_REGS].flags = 0,
|
||||
/*
|
||||
* Match qemu_plugin_vcpu_udata_cb_t:
|
||||
* void (*)(uint32_t, void *)
|
||||
|
@ -434,6 +441,7 @@ void plugin_register_vcpu_mem_cb(GArray **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,
|
||||
[QEMU_PLUGIN_CB_RW_REGS].flags = 0,
|
||||
/*
|
||||
* Match qemu_plugin_vcpu_mem_cb_t:
|
||||
* void (*)(uint32_t, qemu_plugin_meminfo_t, uint64_t, void *)
|
||||
|
@ -473,7 +481,9 @@ void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb)
|
|||
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
|
||||
qemu_plugin_vcpu_tb_trans_cb_t func = cb->f.vcpu_tb_trans;
|
||||
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
func(cb->ctx->id, tb);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -498,7 +508,9 @@ qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2,
|
|||
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
|
||||
qemu_plugin_vcpu_syscall_cb_t func = cb->f.vcpu_syscall;
|
||||
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
func(cb->ctx->id, cpu->cpu_index, num, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -520,7 +532,9 @@ void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t num, int64_t ret)
|
|||
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
|
||||
qemu_plugin_vcpu_syscall_ret_cb_t func = cb->f.vcpu_syscall_ret;
|
||||
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
func(cb->ctx->id, cpu->cpu_index, num, ret);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -528,14 +542,18 @@ void qemu_plugin_vcpu_idle_cb(CPUState *cpu)
|
|||
{
|
||||
/* idle and resume cb may be called before init, ignore in this case */
|
||||
if (cpu->cpu_index < plugin.num_vcpus) {
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_IDLE);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_plugin_vcpu_resume_cb(CPUState *cpu)
|
||||
{
|
||||
if (cpu->cpu_index < plugin.num_vcpus) {
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
|
||||
plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_RESUME);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -615,9 +633,13 @@ void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
|
|||
switch (cb->type) {
|
||||
case PLUGIN_CB_MEM_REGULAR:
|
||||
if (rw & cb->regular.rw) {
|
||||
qemu_plugin_set_cb_flags(cpu,
|
||||
tcg_call_to_qemu_plugin_cb_flags(cb->regular.info->flags));
|
||||
|
||||
cb->regular.f.vcpu_mem(cpu->cpu_index,
|
||||
make_plugin_meminfo(oi, rw),
|
||||
vaddr, cb->regular.userp);
|
||||
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
|
||||
}
|
||||
break;
|
||||
case PLUGIN_CB_INLINE_ADD_U64:
|
||||
|
@ -760,3 +782,14 @@ void plugin_scoreboard_free(struct qemu_plugin_scoreboard *score)
|
|||
g_array_free(score->data, TRUE);
|
||||
g_free(score);
|
||||
}
|
||||
|
||||
enum qemu_plugin_cb_flags tcg_call_to_qemu_plugin_cb_flags(int flags)
|
||||
{
|
||||
if (flags & TCG_CALL_NO_RWG) {
|
||||
return QEMU_PLUGIN_CB_NO_REGS;
|
||||
} else if (flags & TCG_CALL_NO_WG) {
|
||||
return QEMU_PLUGIN_CB_R_REGS;
|
||||
} else {
|
||||
return QEMU_PLUGIN_CB_RW_REGS;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue