[PATCH v3 0/5] Enable PC diversion via the plugin API

Florian Hofhammer posted 5 patches 2 weeks, 3 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/ef60bfbb-cc12-4411-acc1-8c131726f22e@epfl.ch
Maintainers: Laurent Vivier <laurent@vivier.eu>, Brian Cain <brian.cain@oss.qualcomm.com>, "Alex Bennée" <alex.bennee@linaro.org>, Alexandre Iooss <erdnaxe@crans.org>, Mahmoud Mandour <ma.mandourr@gmail.com>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Peter Maydell <peter.maydell@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Aurelien Jarno <aurelien@aurel32.net>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <arikalo@gmail.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>
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
[PATCH v3 0/5] Enable PC diversion via the plugin API
Posted by Florian Hofhammer 2 weeks, 3 days ago
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
-- 
2.52.0
Re: [PATCH v3 0/5] Enable PC diversion via the plugin API
Posted by Pierrick Bouvier 1 week, 4 days ago
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