Hi Richard and Alex,

On 2025-10-22 18:00, Richard Henderson wrote:
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~

Thanks for the review.
Beyond the code style, are you open to accept such a functionality as part of API plugins?

I think it's simple and powerful enough to justify having it upstream. Plus, it will solve other issues than integration with Lorelei.

Regards,
Pierrick

Reply via email to