From nobody Thu Nov 20 03:15:34 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1697896190; cv=none; d=zohomail.com; s=zohoarc; b=dpLLMFTXOsH8WV+0xGmCm+t7CAHMQZVeTa3rAkfRGA/vDIpcjcOdokAGObzLDTNdA+uxuRKEJMTR+2hSQ1zm/8+Hc7pyNZwFbgRWby+sJu0QdDmsLZU9kyUDIR/x/6xJKKB3y1HFKB/FFWrOaV9wzGefxypmDzuT0GTnny7ukfc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1697896190; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3+B7YY6Kq+P5XenPwiuC9qSs2I9YgWnDxzWmz1fNEi4=; b=MnUKn3oTHDwB2H1aRMPZ+U9zugRaDZLCWj2SyVwFTcqXxlUba65rExpO8Ig9kcnqJJVsKDEG2KUARF6K0dnifh/ezJY98j8o9ZV4TXkQ8H4CdzqJvYnqoPRdX2EPOn4o/gTBNDeFZZ29i0EoymvbX9li2UvoZAzJWNbQZ19PX8Y= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1697896190596998.1879189274084; Sat, 21 Oct 2023 06:49:50 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1quCLj-0003aR-PL; Sat, 21 Oct 2023 09:49:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1quB2m-00072F-V1 for qemu-devel@nongnu.org; Sat, 21 Oct 2023 08:25:29 -0400 Received: from skiff.uberspace.de ([185.26.156.131]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1quB2g-0005pH-0C for qemu-devel@nongnu.org; Sat, 21 Oct 2023 08:25:27 -0400 Received: (qmail 24468 invoked by uid 990); 21 Oct 2023 12:25:11 -0000 Received: from unknown (HELO unkown) (::1) by skiff.uberspace.de (Haraka/3.0.1) with ESMTPSA; Sat, 21 Oct 2023 14:25:10 +0200 Authentication-Results: skiff.uberspace.de; auth=pass (plain) From: Julian Ganz To: qemu-devel@nongnu.org Cc: Julian Ganz , Richard Henderson , Paolo Bonzini , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Alexandre Iooss , Mahmoud Mandour Subject: [PATCH] tcg-plugins: add a hook for interrupts, exceptions and traps Date: Sat, 21 Oct 2023 14:24:54 +0200 Message-ID: <20231021122502.26746-1-neither@nut.email> X-Mailer: git-send-email 2.42.0 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Rspamd-Bar: ++ X-Rspamd-Report: SUSPICIOUS_RECIPS(1.5) BAYES_HAM(-0.029244) MID_CONTAINS_FROM(1) MIME_GOOD(-0.1) R_MISSING_CHARSET(0.5) X-Rspamd-Score: 2.870755 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=nut.email; s=uberspace; h=from; bh=DA0CCytzGZMMSzo+EOqLJ2yK0ag/lo+92Eu/lmy4vWQ=; b=EiWALQsmgpd55YP0q2OYFYdZzbpaGFyqTXh9qteHTSSMvqcW1/HZsMblyx2hjNX5gasjqNRu42 GOiw7J2No6zVjIpIIX8IKvFN0XCsqO7hTFK+QUWCMOC812LSQZ01ibT20SwsazEW7AoQFXjPc2iX BuohL0watcFXkOox0oSpIhPhY51Wtp8/M+VcLqvDszskB3gbhiXs6UOPBNrvhWTUcK1RTu8Q0fpf S/6buN6cEvTPhm5xpzQlxiJ7fFh0/7WGi4ydzohyLSfNU0lBrFUeWR9qM2P9CYDny1+SeEeKqVRC mjNiBp16TkiYzPX9X0FfIJCBWcWJcLh/CyRdSGYqt+I60Hn9ti/jL6+JpNiR5mHqEP+wJBMJreAy eGV0O7W7aEno/9wY2acxkhWVKxgftxVjukESZEaykmvaHcw8AKX6pa+etXbmFB0hPH3wwlqvLn81 fGL1AZVdT6IOrbggKqIZ668LfzH2u3/PmDXuXwh/2eKv+38XrunUfOxzE28knCyoFHNM7Pz1wN+I MmAVVGzPk5OJA1lf7LR6/sRQOPOAzCe7eLbDra2pzOLHRf8Z1/d9SXbUnWoW3FOb9g4VhucTo2Gc IwSvL7mU7CMMUnCb13SA4CgN1m2J/I5OefV4iIgzugntNwGgx/tPuwQN5k6Q0qVgk8HDpt3/I33f Y= Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: none client-ip=185.26.156.131; envelope-from=neither@nut.email; helo=skiff.uberspace.de X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_INVALID=0.1, DKIM_SIGNED=0.1, MSGID_FROM_MTA_HEADER=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 21 Oct 2023 09:48:44 -0400 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @nut.email) X-ZM-MESSAGEID: 1697896195015100011 Content-Type: text/plain; charset="utf-8" Some analysis greatly benefits, or depends on, information about interrupts. For example, we may need to handle the execution of a new translation block differently if it is not the result of normal program flow but of an interrupt. Even with the existing interfaces, it is more or less possible to discern these situations using some heuristice. For example, the PC landing in a trap vector is a strong indicator that a trap, i.e. an interrupt or event occured. However, such heuristics require knowledge about the architecture and may be prone to errors. The callback introduced by this change provides a generic and easy-to-use interface for plugin authors. It allows them to register a callback in which they may alter some plugin-internal state to convey the firing of an interrupt for a given CPU, or perform some stand-alone analysis based on the interrupt and, for example, the CPU state. Signed-off-by: Julian Ganz --- accel/tcg/cpu-exec.c | 3 +++ include/qemu/plugin-event.h | 1 + include/qemu/plugin.h | 4 ++++ include/qemu/qemu-plugin.h | 11 +++++++++++ plugins/core.c | 12 ++++++++++++ plugins/qemu-plugins.symbols | 1 + 6 files changed, 32 insertions(+) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 1a5bc90220..e094d9236d 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -754,6 +754,8 @@ static inline bool cpu_handle_exception(CPUState *cpu, = int *ret) qemu_mutex_unlock_iothread(); cpu->exception_index =3D -1; =20 + qemu_plugin_vcpu_interrupt_cb(cpu); + if (unlikely(cpu->singlestep_enabled)) { /* * After processing the exception, ensure an EXCP_DEBUG is @@ -866,6 +868,7 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, if (need_replay_interrupt(interrupt_request)) { replay_interrupt(); } + qemu_plugin_vcpu_interrupt_cb(cpu); /* * After processing the interrupt, ensure an EXCP_DEBUG is * raised when single-stepping so that GDB doesn't miss the diff --git a/include/qemu/plugin-event.h b/include/qemu/plugin-event.h index 7056d8427b..d085bdda4e 100644 --- a/include/qemu/plugin-event.h +++ b/include/qemu/plugin-event.h @@ -20,6 +20,7 @@ enum qemu_plugin_event { QEMU_PLUGIN_EV_VCPU_SYSCALL_RET, QEMU_PLUGIN_EV_FLUSH, QEMU_PLUGIN_EV_ATEXIT, + QEMU_PLUGIN_EV_VCPU_INTERRUPT, QEMU_PLUGIN_EV_MAX, /* total number of plugin events we support */ }; =20 diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index 7fdc3a4849..f942e45f41 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -190,6 +190,7 @@ void qemu_plugin_vcpu_exit_hook(CPUState *cpu); void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb); void qemu_plugin_vcpu_idle_cb(CPUState *cpu); void qemu_plugin_vcpu_resume_cb(CPUState *cpu); +void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu); void qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a= 5, @@ -270,6 +271,9 @@ static inline void qemu_plugin_vcpu_idle_cb(CPUState *c= pu) static inline void qemu_plugin_vcpu_resume_cb(CPUState *cpu) { } =20 +static inline void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu) +{ } + static inline void 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 a= 6, diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 50a9957279..2eb4b325fe 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -206,6 +206,17 @@ void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_= t id, void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_id_t id, qemu_plugin_vcpu_simple_cb_t cb); =20 +/** + * qemu_plugin_register_vcpu_interrupt_cb() - register a vCPU interrupt ca= llback + * @id: plugin ID + * @cb: callback function + * + * The @cb function is called every time a vCPU receives an interrupt, exc= eption + * or trap. + */ +void qemu_plugin_register_vcpu_interrupt_cb(qemu_plugin_id_t id, + qemu_plugin_vcpu_simple_cb_t c= b); + /** struct qemu_plugin_tb - Opaque handle for a translation block */ struct qemu_plugin_tb; /** struct qemu_plugin_insn - Opaque handle for a translated instruction */ diff --git a/plugins/core.c b/plugins/core.c index fcd33a2bff..3658bdef45 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -103,6 +103,7 @@ static void plugin_vcpu_cb__simple(CPUState *cpu, enum = qemu_plugin_event ev) case QEMU_PLUGIN_EV_VCPU_EXIT: case QEMU_PLUGIN_EV_VCPU_IDLE: case QEMU_PLUGIN_EV_VCPU_RESUME: + case QEMU_PLUGIN_EV_VCPU_INTERRUPT: /* iterate safely; plugins might uninstall themselves at any time = */ QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) { qemu_plugin_vcpu_simple_cb_t func =3D cb->f.vcpu_simple; @@ -400,6 +401,11 @@ void qemu_plugin_vcpu_resume_cb(CPUState *cpu) plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_RESUME); } =20 +void qemu_plugin_vcpu_interrupt_cb(CPUState *cpu) +{ + plugin_vcpu_cb__simple(cpu, QEMU_PLUGIN_EV_VCPU_INTERRUPT); +} + void qemu_plugin_register_vcpu_idle_cb(qemu_plugin_id_t id, qemu_plugin_vcpu_simple_cb_t cb) { @@ -412,6 +418,12 @@ void qemu_plugin_register_vcpu_resume_cb(qemu_plugin_i= d_t id, plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_RESUME, cb); } =20 +void qemu_plugin_register_vcpu_interrupt_cb(qemu_plugin_id_t id, + qemu_plugin_vcpu_simple_cb_t c= b) +{ + plugin_register_cb(id, QEMU_PLUGIN_EV_VCPU_INTERRUPT, cb); +} + void qemu_plugin_register_flush_cb(qemu_plugin_id_t id, qemu_plugin_simple_cb_t cb) { diff --git a/plugins/qemu-plugins.symbols b/plugins/qemu-plugins.symbols index 71f6c90549..1fddb4b9fd 100644 --- a/plugins/qemu-plugins.symbols +++ b/plugins/qemu-plugins.symbols @@ -35,6 +35,7 @@ qemu_plugin_register_vcpu_tb_exec_cb; qemu_plugin_register_vcpu_tb_exec_inline; qemu_plugin_register_vcpu_tb_trans_cb; + qemu_plugin_register_vcpu_interrupt_cb; qemu_plugin_reset; qemu_plugin_start_code; qemu_plugin_tb_get_insn; --=20 2.42.0