qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

plugin: expand the plugin_init function to include an info block

This provides a limited amount of info to plugins about the guest
system that will allow them to make some additional decisions on
setup.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

+43 -6
+24 -2
include/qemu/qemu-plugin.h
··· 38 38 39 39 typedef uint64_t qemu_plugin_id_t; 40 40 41 + typedef struct { 42 + /* string describing architecture */ 43 + const char *target_name; 44 + /* is this a full system emulation? */ 45 + bool system_emulation; 46 + union { 47 + /* 48 + * smp_vcpus may change if vCPUs can be hot-plugged, max_vcpus 49 + * is the system-wide limit. 50 + */ 51 + struct { 52 + int smp_vcpus; 53 + int max_vcpus; 54 + } system; 55 + }; 56 + } qemu_info_t; 57 + 41 58 /** 42 59 * qemu_plugin_install() - Install a plugin 43 60 * @id: this plugin's opaque ID 61 + * @info: a block describing some details about the guest 44 62 * @argc: number of arguments 45 63 * @argv: array of arguments (@argc elements) 46 64 * ··· 49 67 * Note: Calling qemu_plugin_uninstall() from this function is a bug. To raise 50 68 * an error during install, return !0. 51 69 * 70 + * Note: @info is only live during the call. Copy any information we 71 + * want to keep. 72 + * 52 73 * Note: @argv remains valid throughout the lifetime of the loaded plugin. 53 74 */ 54 - QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, int argc, 55 - char **argv); 75 + QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, 76 + const qemu_info_t *info, 77 + int argc, char **argv); 56 78 57 79 /* 58 80 * Prototypes for the various callback styles we will be registering
+19 -4
plugins/loader.c
··· 28 28 #include "hw/core/cpu.h" 29 29 #include "cpu.h" 30 30 #include "exec/exec-all.h" 31 + #ifndef CONFIG_USER_ONLY 32 + #include "hw/boards.h" 33 + #endif 34 + 31 35 #include "plugin.h" 32 36 33 37 /* ··· 58 62 }, 59 63 }; 60 64 61 - typedef int (*qemu_plugin_install_func_t)(qemu_plugin_id_t, int, char **); 65 + typedef int (*qemu_plugin_install_func_t)(qemu_plugin_id_t, const qemu_info_t *, int, char **); 62 66 63 67 extern struct qemu_plugin_state plugin; 64 68 ··· 145 149 return x * UINT64_C(2685821657736338717); 146 150 } 147 151 148 - static int plugin_load(struct qemu_plugin_desc *desc) 152 + static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info) 149 153 { 150 154 qemu_plugin_install_func_t install; 151 155 struct qemu_plugin_ctx *ctx; ··· 193 197 } 194 198 QTAILQ_INSERT_TAIL(&plugin.ctxs, ctx, entry); 195 199 ctx->installing = true; 196 - rc = install(ctx->id, desc->argc, desc->argv); 200 + rc = install(ctx->id, info, desc->argc, desc->argv); 197 201 ctx->installing = false; 198 202 if (rc) { 199 203 error_report("%s: qemu_plugin_install returned error code %d", ··· 241 245 int qemu_plugin_load_list(QemuPluginList *head) 242 246 { 243 247 struct qemu_plugin_desc *desc, *next; 248 + g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1); 249 + 250 + info->target_name = TARGET_NAME; 251 + #ifndef CONFIG_USER_ONLY 252 + MachineState *ms = MACHINE(qdev_get_machine()); 253 + info->system_emulation = true; 254 + info->system.smp_vcpus = ms->smp.cpus; 255 + info->system.max_vcpus = ms->smp.max_cpus; 256 + #else 257 + info->system_emulation = false; 258 + #endif 244 259 245 260 QTAILQ_FOREACH_SAFE(desc, head, entry, next) { 246 261 int err; 247 262 248 - err = plugin_load(desc); 263 + err = plugin_load(desc, info); 249 264 if (err) { 250 265 return err; 251 266 }