On 1/20/26 7:19 AM, Florian Hofhammer wrote:
> Hi,
>
> This patch series builds on top of the discussion from the thread at
> https://lore.kernel.org/qemu-devel/e9bcd7c7-2d67-469e-b2f3-d1a68e456b2b@epfl.ch/
> 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.
>
> Based on the discussion in the above thread, the series also introduces
> a means to declare registers as read-only from the plugin side, which
> prevents plugins from writing to them via qemu_plugin_write_register().
> This for now is only applied to the PC, and finding the PC register is
> done via some rather hacky strcmp()s. In the above thread, we also
> discussed encoding the read-only property in a custom attribute in the
> GDB XMLs, but that would (1) make syncing with GDB harder, (2) not
> cover all architectures, as there's not an XML description of all
> architectures available in the gdb-xml/ directory, and (3) require quite
> some changes to the whole GDB infrastructure in gdbstub/ to even encode
> the attribute in the correct structs and pass them on over the different
> layers up into the plugin API.
>
> This patch series does not (yet) bump the plugin API version, as I've
> sent another patch yesterday (see
> https://lore.kernel.org/qemu-devel/f877dd79-1285-4752-811e-f0d430ff27fe@fhofhammer.de/)
> that makes some changes to qemu_plugin_{read,write}_register() as well
> and I'll adjust the plugin API version bump and API usage in a v4 once I
> have an idea whether the patches will make it into a release or not to
> avoid conflicts later on.
>
> Best regards,
> Florian
>
> Changes:
> 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 (5):
> plugins: add PC diversion API function
> plugins: add read-only property for registers
> plugins: prohibit writing to read-only registers
> tests/tcg: add test for qemu_plugin_set_pc API
> tests/tcg/plugins: test register readonly feature
>
> include/qemu/qemu-plugin.h | 17 +++++
> 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 | 4 ++
> 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 | 5 +-
> linux-user/openrisc/cpu_loop.c | 2 +-
> linux-user/ppc/cpu_loop.c | 6 +-
> 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 | 8 +++
> linux-user/xtensa/cpu_loop.c | 3 +
> plugins/api.c | 41 +++++++++--
> plugins/core.c | 25 ++++---
> tests/tcg/arm/Makefile.target | 6 ++
> tests/tcg/hexagon/Makefile.target | 7 ++
> tests/tcg/mips/Makefile.target | 6 +-
> tests/tcg/mips64/Makefile.target | 15 ++++
> tests/tcg/mips64el/Makefile.target | 15 ++++
> tests/tcg/mipsel/Makefile.target | 15 ++++
> tests/tcg/multiarch/Makefile.target | 20 +++++-
> .../{ => plugin}/check-plugin-output.sh | 0
> .../{ => plugin}/test-plugin-mem-access.c | 0
> .../plugin/test-plugin-skip-syscalls.c | 26 +++++++
> tests/tcg/plugins/meson.build | 2 +-
> tests/tcg/plugins/registers.c | 71 +++++++++++++++++++
> tests/tcg/plugins/syscall.c | 6 ++
> tests/tcg/sparc64/Makefile.target | 16 +++++
> 36 files changed, 321 insertions(+), 38 deletions(-)
> create mode 100644 tests/tcg/mips64/Makefile.target
> create mode 100644 tests/tcg/mips64el/Makefile.target
> create mode 100644 tests/tcg/mipsel/Makefile.target
> rename tests/tcg/multiarch/{ => plugin}/check-plugin-output.sh (100%)
> rename tests/tcg/multiarch/{ => plugin}/test-plugin-mem-access.c (100%)
> create mode 100644 tests/tcg/multiarch/plugin/test-plugin-skip-syscalls.c
> create mode 100644 tests/tcg/plugins/registers.c
> create mode 100644 tests/tcg/sparc64/Makefile.target
>
>
> base-commit: 38879a667fbb4ef54c70de71494882615f600a64
Thanks for posting Florian.
I'll let Alex review it to see if it matches his original vision, and
the readonly approach for pc register.
Regards,
Pierrick