QEMU main repository: Please see https://www.qemu.org/docs/master/devel/submitting-a-patch.html for how to submit changes to QEMU. Pull Requests are ignored. Please only use release tarballs from the QEMU website. http://www.qemu.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

79 lines
2.7 KiB

/*
* SPDX-License-Identifier: GPL-2.0-or-later
*
* Copyright (C) 2026, Florian Hofhammer <florian.hofhammer@epfl.ch>
*/
#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 plugin tests whether we can read and write registers via the plugin
* API. We try to just read/write a single register, as some architectures have
* registers that cannot be written to, which would fail the test.
* See: https://lists.gnu.org/archive/html/qemu-devel/2026-02/msg07025.html
*/
static void vcpu_init_cb(qemu_plugin_id_t id, unsigned int vcpu_index)
{
g_autoptr(GArray) regs = qemu_plugin_get_registers();
g_assert(regs != NULL);
g_autoptr(GByteArray) buf = g_byte_array_sized_new(0);
qemu_plugin_reg_descriptor *reg_desc = NULL;
bool success = false;
/* Make sure we can read and write a register not marked as readonly */
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) {
g_byte_array_set_size(buf, 0);
success = qemu_plugin_read_register(reg_desc->handle, buf);
g_assert(success);
g_assert(buf->len > 0);
success = qemu_plugin_write_register(reg_desc->handle, buf);
g_assert(success);
break;
} else {
reg_desc = NULL;
}
}
g_assert(regs->len == 0 || reg_desc != NULL);
/*
* Check whether we can still read 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.
*/
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) {
g_byte_array_set_size(buf, 0);
success = qemu_plugin_read_register(reg_desc->handle, buf);
g_assert(success);
g_assert(buf->len > 0);
break;
} else {
reg_desc = NULL;
}
}
g_assert(regs->len == 0 || reg_desc != NULL);
/*
* Note: we currently do not test whether the read-only register can be
* written to, because doing so would throw an assert in the plugin API.
*/
}
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;
}