On 3/4/26 2:36 AM, Florian Hofhammer wrote:
On 03/03/2026 20:20, Pierrick Bouvier wrote:
On 3/3/26 5:07 AM, Florian Hofhammer wrote:
Hi,
This patch series builds on top of the discussion from the thread at
https://lore.kernel.org/qemu-devel/[email protected]/
and adds a plugin API function to set the program counter of the guest,
as just writing to it via qemu_plugin_write_register() has no direct
effect.
This version v6 of the patch series addresses the requested changes from
the previous v4 submission and an incorrect commit message from v5
(details below).
Note: checkpatch.pl still reports a warning about line length violations
in patch nr. 6/7 but I did not fix this, as the line was already > 80
characters long previously, the change added only a single character,
and I think the readability of the code is better as it is now. Please
let me know if you disagree and would like me to fix this!
Best regards,
Florian
Changes:
v6:
- update commit message for patch 4/7
v5:
- make QEMU abort via asserts instead of just returning an error from
the plugin API if preconditions are violated
- extend tests for qemu_plugin_set_pc() to different contexts
- fix issues highlighted by checkpatch.pl
v4:
- switch strcmp out in favor of g_strcmp0
- split the patch introducing the qemu_plugin_set_pc() API into three
patches, two for preparing the plugin infrastructure and the syscall
handling code and a third introducing the actual plugin API
v3:
- make PC registers read-only across architectures
- add tests for read-only registers
- adjust test structure for qemu_plugin_set_pc() by moving
architecture-specific tests into corresponding directories
v2:
- add setjmp() in syscall handling path to allow PC redirection from
syscall callbacks (via longjmp(), the cpu_loop()'s setjmp() for
exiting a TB would not be live anymore in syscall handlers)
- add flags to ensure the qemu_plugin_set_pc() API is only called from
contexts where the CPU is live
- add test for qemu_plugin_set_pc() API
v1:
- initial version
---
Florian Hofhammer (7):
plugins: add flag to specify whether PC is rw
linux-user: make syscall emulation interruptible
plugins: add PC diversion API function
tests/tcg: add tests for qemu_plugin_set_pc API
plugins: add read-only property for registers
plugins: prohibit writing to read-only registers
tests/tcg/plugins: test register accesses
MAINTAINERS | 1 +
include/plugins/qemu-plugin.h | 19 +++
linux-user/aarch64/cpu_loop.c | 2 +-
linux-user/alpha/cpu_loop.c | 2 +-
linux-user/arm/cpu_loop.c | 2 +-
linux-user/hexagon/cpu_loop.c | 2 +-
linux-user/hppa/cpu_loop.c | 1 +
linux-user/i386/cpu_loop.c | 8 +-
linux-user/include/special-errno.h | 8 ++
linux-user/loongarch64/cpu_loop.c | 5 +-
linux-user/m68k/cpu_loop.c | 2 +-
linux-user/microblaze/cpu_loop.c | 2 +-
linux-user/mips/cpu_loop.c | 9 +-
linux-user/or1k/cpu_loop.c | 2 +-
linux-user/ppc/cpu_loop.c | 10 +-
linux-user/riscv/cpu_loop.c | 2 +-
linux-user/s390x/cpu_loop.c | 2 +-
linux-user/sh4/cpu_loop.c | 2 +-
linux-user/sparc/cpu_loop.c | 4 +-
linux-user/syscall.c | 16 +++
linux-user/xtensa/cpu_loop.c | 1 +
plugins/api.c | 42 ++++++-
plugins/core.c | 29 +++--
tests/tcg/arm/Makefile.target | 6 +
tests/tcg/multiarch/Makefile.target | 17 ++-
.../multiarch/{ => plugin}/check-plugin-output.sh | 0
.../{ => plugin}/test-plugin-mem-access.c | 0
tests/tcg/multiarch/plugin/test-plugin-set-pc.c | 140
+++++++++++++++++++++
tests/tcg/plugins/meson.build | 2 +
tests/tcg/plugins/registers.c | 79 ++++++++++++
tests/tcg/plugins/setpc.c | 120 ++++++++++++++++++
31 files changed, 495 insertions(+), 42 deletions(-)
---
base-commit: 3fb456e9a0e9eef6a71d9b49bfff596a0f0046e9
change-id: 20260303-setpc-v5-c1df30bad07f
Hi Florian,
it seems like there is a small issue building documentation with this series,
which should be trivial to fix.
https://github.com/p-b-o/qemu-ci/actions/runs/22632339221
Sorry, I didn't catch this one before. I didn't have sphinx installed
locally and built without the docs.
No worries, it's hard to guess all the things that you *might* miss, and
it's a common mistake even for regular contributors, including myself.
It seems as if the issue is coming from the declaration of the new API
as "QEMU_PLUGIN_API G_NORETURN void ..." and sphinx is tripping over the
"G_NORETURN" macro. To fix this, I could either change the sphinx config
to accept the macro, or remove the attribute from the declaration. I'd
personally prefer the former but I'd be happy to get your opinion on
this.
Simply move the attribute after prototype, it's the same semantic.
diff --git a/include/plugins/qemu-plugin.h b/include/plugins/qemu-plugin.h
index 791d223df40..0825bc9279d 100644
--- a/include/plugins/qemu-plugin.h
+++ b/include/plugins/qemu-plugin.h
@@ -1055,8 +1055,7 @@ bool qemu_plugin_write_register(struct
qemu_plugin_register *handle,
* resumes execution at that address. This function does not return.
*/
QEMU_PLUGIN_API
-G_NORETURN
-void qemu_plugin_set_pc(uint64_t vaddr);
+void qemu_plugin_set_pc(uint64_t vaddr) G_NORETURN;
/**
* qemu_plugin_read_memory_vaddr() - read from memory using a virtual
address
Regards,
Pierrick