mirror of
https://github.com/qemu/qemu.git
synced 2026-02-04 05:35:39 +00:00
linux-user: add plugin API to filter syscalls
This commit adds a syscall filter API to the TCG plugin API set. Plugins can register a filter callback to QEMU to decide whether to intercept a syscall, process it and bypass the QEMU syscall handler. Signed-off-by: Ziyang Zhang <functioner@sjtu.edu.cn> Co-authored-by: Mingyuan Xia <xiamy@ultrarisc.com> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> [Pierrick - move send_through_syscall_filters to linux-user/syscall.c] Link: https://lore.kernel.org/qemu-devel/20251214144620.179282-2-functioner@sjtu.edu.cn Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
This commit is contained in:
committed by
Pierrick Bouvier
parent
d37ce14f98
commit
5ed628d1d3
@@ -23,6 +23,7 @@ enum qemu_plugin_event {
|
||||
QEMU_PLUGIN_EV_VCPU_INTERRUPT,
|
||||
QEMU_PLUGIN_EV_VCPU_EXCEPTION,
|
||||
QEMU_PLUGIN_EV_VCPU_HOSTCALL,
|
||||
QEMU_PLUGIN_EV_VCPU_SYSCALL_FILTER,
|
||||
QEMU_PLUGIN_EV_MAX, /* total number of plugin events we support */
|
||||
};
|
||||
|
||||
|
||||
@@ -55,15 +55,16 @@ void qemu_plugin_opt_parse(const char *optstr, QemuPluginList *head);
|
||||
int qemu_plugin_load_list(QemuPluginList *head, Error **errp);
|
||||
|
||||
union qemu_plugin_cb_sig {
|
||||
qemu_plugin_simple_cb_t simple;
|
||||
qemu_plugin_udata_cb_t udata;
|
||||
qemu_plugin_vcpu_simple_cb_t vcpu_simple;
|
||||
qemu_plugin_vcpu_udata_cb_t vcpu_udata;
|
||||
qemu_plugin_vcpu_discon_cb_t vcpu_discon;
|
||||
qemu_plugin_vcpu_tb_trans_cb_t vcpu_tb_trans;
|
||||
qemu_plugin_vcpu_mem_cb_t vcpu_mem;
|
||||
qemu_plugin_vcpu_syscall_cb_t vcpu_syscall;
|
||||
qemu_plugin_vcpu_syscall_ret_cb_t vcpu_syscall_ret;
|
||||
qemu_plugin_simple_cb_t simple;
|
||||
qemu_plugin_udata_cb_t udata;
|
||||
qemu_plugin_vcpu_simple_cb_t vcpu_simple;
|
||||
qemu_plugin_vcpu_udata_cb_t vcpu_udata;
|
||||
qemu_plugin_vcpu_discon_cb_t vcpu_discon;
|
||||
qemu_plugin_vcpu_tb_trans_cb_t vcpu_tb_trans;
|
||||
qemu_plugin_vcpu_mem_cb_t vcpu_mem;
|
||||
qemu_plugin_vcpu_syscall_cb_t vcpu_syscall;
|
||||
qemu_plugin_vcpu_syscall_ret_cb_t vcpu_syscall_ret;
|
||||
qemu_plugin_vcpu_syscall_filter_cb_t vcpu_syscall_filter;
|
||||
void *generic;
|
||||
};
|
||||
|
||||
@@ -169,6 +170,11 @@ qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1,
|
||||
uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5,
|
||||
uint64_t a6, uint64_t a7, uint64_t a8);
|
||||
void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t num, int64_t ret);
|
||||
bool
|
||||
qemu_plugin_vcpu_syscall_filter(CPUState *cpu, int64_t num, uint64_t a1,
|
||||
uint64_t a2, uint64_t a3, uint64_t a4,
|
||||
uint64_t a5, uint64_t a6, uint64_t a7,
|
||||
uint64_t a8, uint64_t *sysret);
|
||||
|
||||
void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
|
||||
uint64_t value_low,
|
||||
@@ -280,6 +286,15 @@ static inline
|
||||
void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t num, int64_t ret)
|
||||
{ }
|
||||
|
||||
static inline bool
|
||||
qemu_plugin_vcpu_syscall_filter(CPUState *cpu, int64_t num, uint64_t a1,
|
||||
uint64_t a2, uint64_t a3, uint64_t a4,
|
||||
uint64_t a5, uint64_t a6, uint64_t a7,
|
||||
uint64_t a8, uint64_t *sysret)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void qemu_plugin_vcpu_mem_cb(CPUState *cpu, uint64_t vaddr,
|
||||
uint64_t value_low,
|
||||
uint64_t value_high,
|
||||
|
||||
@@ -798,6 +798,33 @@ typedef void
|
||||
uint64_t a3, uint64_t a4, uint64_t a5,
|
||||
uint64_t a6, uint64_t a7, uint64_t a8);
|
||||
|
||||
/**
|
||||
* typedef qemu_plugin_vcpu_syscall_filter_cb_t - vCPU syscall filter callback
|
||||
* function type
|
||||
* @id: plugin id
|
||||
* @vcpu_index: the executing vCPU
|
||||
* @num: the syscall number
|
||||
* @a1: the 1st syscall argument
|
||||
* @a2: the 2nd syscall argument
|
||||
* @a3: the 3rd syscall argument
|
||||
* @a4: the 4th syscall argument
|
||||
* @a5: the 5th syscall argument
|
||||
* @a6: the 6th syscall argument
|
||||
* @a7: the 7th syscall argument
|
||||
* @a8: the 8th syscall argument
|
||||
* @sysret: reference of the syscall return value, must set this if filtered
|
||||
*
|
||||
* Returns true if you want to filter this syscall (i.e. stop it being
|
||||
* handled further), otherwise returns false.
|
||||
*/
|
||||
typedef bool
|
||||
(*qemu_plugin_vcpu_syscall_filter_cb_t)(qemu_plugin_id_t id,
|
||||
unsigned int vcpu_index,
|
||||
int64_t num, uint64_t a1, uint64_t a2,
|
||||
uint64_t a3, uint64_t a4, uint64_t a5,
|
||||
uint64_t a6, uint64_t a7, uint64_t a8,
|
||||
uint64_t *sysret);
|
||||
|
||||
QEMU_PLUGIN_API
|
||||
void qemu_plugin_register_vcpu_syscall_cb(qemu_plugin_id_t id,
|
||||
qemu_plugin_vcpu_syscall_cb_t cb);
|
||||
@@ -811,6 +838,11 @@ void
|
||||
qemu_plugin_register_vcpu_syscall_ret_cb(qemu_plugin_id_t id,
|
||||
qemu_plugin_vcpu_syscall_ret_cb_t cb);
|
||||
|
||||
QEMU_PLUGIN_API
|
||||
void
|
||||
qemu_plugin_register_vcpu_syscall_filter_cb(qemu_plugin_id_t id,
|
||||
qemu_plugin_vcpu_syscall_filter_cb_t cb);
|
||||
|
||||
|
||||
/**
|
||||
* qemu_plugin_insn_disas() - return disassembly string for instruction
|
||||
|
||||
Reference in New Issue
Block a user