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

tcg plugins: expose an API version concept

This is a very simple versioning API which allows the plugin
infrastructure to check the API a plugin was built against. We also
expose a min/cur API version to the plugin via the info block in case
it wants to avoid using old deprecated APIs in the future.

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Robert Foley <robert.foley@linaro.org>

+56
+19
include/qemu/qemu-plugin.h
··· 38 38 39 39 typedef uint64_t qemu_plugin_id_t; 40 40 41 + /* 42 + * Versioning plugins: 43 + * 44 + * The plugin API will pass a minimum and current API version that 45 + * QEMU currently supports. The minimum API will be incremented if an 46 + * API needs to be deprecated. 47 + * 48 + * The plugins export the API they were built against by exposing the 49 + * symbol qemu_plugin_version which can be checked. 50 + */ 51 + 52 + extern QEMU_PLUGIN_EXPORT int qemu_plugin_version; 53 + 54 + #define QEMU_PLUGIN_VERSION 0 55 + 41 56 typedef struct { 42 57 /* string describing architecture */ 43 58 const char *target_name; 59 + struct { 60 + int min; 61 + int cur; 62 + } version; 44 63 /* is this a full system emulation? */ 45 64 bool system_emulation; 46 65 union {
+21
plugins/loader.c
··· 178 178 goto err_symbol; 179 179 } 180 180 181 + if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) { 182 + error_report("TCG plugin %s does not declare API version %s", 183 + desc->path, g_module_error()); 184 + goto err_symbol; 185 + } else { 186 + int version = *(int *)sym; 187 + if (version < QEMU_PLUGIN_MIN_VERSION) { 188 + error_report("TCG plugin %s requires API version %d, but " 189 + "this QEMU supports only a minimum version of %d", 190 + desc->path, version, QEMU_PLUGIN_MIN_VERSION); 191 + goto err_symbol; 192 + } else if (version > QEMU_PLUGIN_VERSION) { 193 + error_report("TCG plugin %s requires API version %d, but " 194 + "this QEMU supports only up to version %d", 195 + desc->path, version, QEMU_PLUGIN_VERSION); 196 + goto err_symbol; 197 + } 198 + } 199 + 181 200 qemu_rec_mutex_lock(&plugin.lock); 182 201 183 202 /* find an unused random id with &ctx as the seed */ ··· 248 267 g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1); 249 268 250 269 info->target_name = TARGET_NAME; 270 + info->version.min = QEMU_PLUGIN_MIN_VERSION; 271 + info->version.cur = QEMU_PLUGIN_VERSION; 251 272 #ifndef CONFIG_USER_ONLY 252 273 MachineState *ms = MACHINE(qdev_get_machine()); 253 274 info->system_emulation = true;
+2
plugins/plugin.h
··· 14 14 15 15 #include <gmodule.h> 16 16 17 + #define QEMU_PLUGIN_MIN_VERSION 0 18 + 17 19 /* global state */ 18 20 struct qemu_plugin_state { 19 21 QTAILQ_HEAD(, qemu_plugin_ctx) ctxs;
+2
tests/plugin/bb.c
··· 14 14 15 15 #include <qemu-plugin.h> 16 16 17 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 18 + 17 19 static uint64_t bb_count; 18 20 static uint64_t insn_count; 19 21 static bool do_inline;
+2
tests/plugin/empty.c
··· 13 13 14 14 #include <qemu-plugin.h> 15 15 16 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 17 + 16 18 /* 17 19 * Empty TB translation callback. 18 20 * This allows us to measure the overhead of injecting and then
+2
tests/plugin/hotblocks.c
··· 15 15 16 16 #include <qemu-plugin.h> 17 17 18 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 19 + 18 20 static bool do_inline; 19 21 20 22 /* Plugins need to take care of their own locking */
+2
tests/plugin/hotpages.c
··· 18 18 19 19 #include <qemu-plugin.h> 20 20 21 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 22 + 21 23 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 22 24 23 25 static uint64_t page_size = 4096;
+2
tests/plugin/howvec.c
··· 20 20 21 21 #include <qemu-plugin.h> 22 22 23 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 24 + 23 25 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 24 26 25 27 typedef enum {
+2
tests/plugin/insn.c
··· 14 14 15 15 #include <qemu-plugin.h> 16 16 17 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 18 + 17 19 static uint64_t insn_count; 18 20 static bool do_inline; 19 21
+2
tests/plugin/mem.c
··· 14 14 15 15 #include <qemu-plugin.h> 16 16 17 + QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION; 18 + 17 19 static uint64_t mem_count; 18 20 static uint64_t io_count; 19 21 static bool do_inline;