On 10/22/25 01:53, Ziyang Zhang wrote:
@@ -165,6 +166,10 @@ 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 *ret);
The second and third lines should indented just past the ( on the first line,
i.e. with
CPUState.
+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 *ret)
Like this.
+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 *ret);
Likewise.
+static inline bool send_through_syscall_filters(CPUState *cpu, int num,
+ abi_long arg1, abi_long arg2,
+ abi_long arg3, abi_long arg4,
+ abi_long arg5, abi_long arg6,
+ abi_long arg7, abi_long arg8, abi_long *ret)
Do not mark inline; let the compiler decide.
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index d78b2029fa..b8225f838f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -14084,8 +14084,11 @@ abi_long do_syscall(CPUArchState *cpu_env, int num,
abi_long arg1,
print_syscall(cpu_env, num, arg1, arg2, arg3, arg4, arg5, arg6);
}
- ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
- arg5, arg6, arg7, arg8);
+ if (!send_through_syscall_filters(cpu, num, arg1, arg2, arg3, arg4, arg5,
+ arg6, arg7, arg8, &ret)) {
Incorrect indent.
+ ret = do_syscall1(cpu_env, num, arg1, arg2, arg3, arg4,
+ arg5, arg6, arg7, arg8);
Likewise.
diff --git a/plugins/core.c b/plugins/core.c
index ead09fd2f1..1b2f875fb1 100644
--- a/plugins/core.c
+++ b/plugins/core.c
@@ -538,6 +538,40 @@ void qemu_plugin_vcpu_syscall_ret(CPUState *cpu, int64_t
num, int64_t ret)
}
}
+/*
+ * Disable CFI checks.
+ * The callback function has been loaded from an external library so we do not
+ * have type information
+ */
+QEMU_DISABLE_CFI
+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 *ret)
Likewise.
+{
+ struct qemu_plugin_cb *cb, *next;
+ enum qemu_plugin_event ev = QEMU_PLUGIN_EV_VCPU_SYSCALL_FILTER;
+
+ if (!test_bit(ev, cpu->plugin_state->event_mask)) {
+ return false;
+ }
+
+ bool filtered = false;
+ QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
+ qemu_plugin_vcpu_syscall_filter_cb_t func = cb->f.vcpu_syscall_filter;
+
+ qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
+ if (func(cb->ctx->id, cpu->cpu_index, num, a1, a2, a3, a4,
+ a5, a6, a7, a8, ret)) {
+ filtered = true;
+ qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
+ break;
+ }
+ qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
+ }
+ return filtered;
+}
The loop is better written
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
bool filtered;
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
filtered = cb->f.vcpu_syscall_filter(cb->ctx->id, cpu->cpu_index,
num, a1, a2, a3, a4, a5,
a6, a7, a8, ret);
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_NO_REGS);
if (filtered) {
return true;
}
}
return false;
r~