On 2/24/26 7:58 AM, Florian Hofhammer wrote:
> This commit tests the readonly feature for registers exposed via the
> plugin API introduced earlier in the patch series.
>
> Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
> ---
> tests/tcg/plugins/meson.build | 1 +
> tests/tcg/plugins/registers.c | 68 +++++++++++++++++++++++++++++++++++
> 2 files changed, 69 insertions(+)
> create mode 100644 tests/tcg/plugins/registers.c
>
> diff --git a/tests/tcg/plugins/meson.build b/tests/tcg/plugins/meson.build
> index c5e49753fd..5005aa8dc9 100644
> --- a/tests/tcg/plugins/meson.build
> +++ b/tests/tcg/plugins/meson.build
> @@ -6,6 +6,7 @@ test_plugins = [
> 'insn.c',
> 'mem.c',
> 'patch.c',
> +'registers.c',
> 'reset.c',
> 'syscall.c',
> ]
> diff --git a/tests/tcg/plugins/registers.c b/tests/tcg/plugins/registers.c
> new file mode 100644
> index 0000000000..a7bd692225
> --- /dev/null
> +++ b/tests/tcg/plugins/registers.c
> @@ -0,0 +1,68 @@
> +/*
> + * Copyright (C) 2026, Florian Hofhammer <florian.hofhammer@epfl.ch>
> + *
> + * License: GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#include "glib.h"
> +#include <inttypes.h>
> +#include <assert.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <stdio.h>
> +
> +#include <qemu-plugin.h>
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
> +
> +/*
> + * This callback is called when a vCPU is initialized. It tests whether we
> + * successfully read from a register and write value back to it. It also tests
> + * that read-only registers cannot be written to, i.e., we can read a read-only
> + * register but writing to it fails.
> + */
> +static void vcpu_init_cb(qemu_plugin_id_t id, unsigned int vcpu_index)
> +{
> + g_autoptr(GArray) regs = qemu_plugin_get_registers();
> + g_autoptr(GByteArray) buf = g_byte_array_sized_new(0);
> + bool success = false;
> +
> + /* Make sure we can read and write an arbitrary register */
> + qemu_plugin_reg_descriptor *reg_desc = &g_array_index(regs,
> + qemu_plugin_reg_descriptor, 0);
> + g_assert(reg_desc->is_readonly == false);
> + success = qemu_plugin_read_register(reg_desc->handle, buf);
> + g_assert(success);
> + success = qemu_plugin_write_register(reg_desc->handle, buf);
> + g_assert(success);
> +
> + /*
> + * Reset the buffer and find a read-only register. On each architecture, at
> + * least the PC should be read-only because it's only supposed to be
> + * modified via the qemu_plugin_set_pc() function.
> + */
> + g_byte_array_set_size(buf, 0);
> + for (size_t i = 0; i < regs->len; i++) {
> + reg_desc = &g_array_index(regs, qemu_plugin_reg_descriptor, i);
> + if (reg_desc->is_readonly) {
> + success = qemu_plugin_read_register(reg_desc->handle, buf);
> + g_assert(success);
> + break;
> + } else {
> + reg_desc = NULL;
> + }
> + }
> + /* Make sure there is a read-only register and we cannot write to it */
> + g_assert(reg_desc != NULL);
> + success = qemu_plugin_write_register(reg_desc->handle, buf);
> + g_assert(!success);
> +}
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
> + const qemu_info_t *info,
> + int argc, char **argv)
> +{
> + qemu_plugin_register_vcpu_init_cb(id, vcpu_init_cb);
> + return 0;
> +}
Looks great, and nice to have a test for this.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>