]> git.ipfire.org Git - thirdparty/qemu.git/commitdiff
tcg plugins: expose an API version concept
authorAlex Bennée <alex.bennee@linaro.org>
Mon, 4 Nov 2019 13:18:36 +0000 (13:18 +0000)
committerAlex Bennée <alex.bennee@linaro.org>
Tue, 12 Nov 2019 14:32:55 +0000 (14:32 +0000)
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>
include/qemu/qemu-plugin.h
plugins/loader.c
plugins/plugin.h
tests/plugin/bb.c
tests/plugin/empty.c
tests/plugin/hotblocks.c
tests/plugin/hotpages.c
tests/plugin/howvec.c
tests/plugin/insn.c
tests/plugin/mem.c

index a00a7deb4614da8c6e14aaef1f32534417f029d2..5502e112c8106be507584b565d1877dc10371866 100644 (file)
 
 typedef uint64_t qemu_plugin_id_t;
 
+/*
+ * Versioning plugins:
+ *
+ * The plugin API will pass a minimum and current API version that
+ * QEMU currently supports. The minimum API will be incremented if an
+ * API needs to be deprecated.
+ *
+ * The plugins export the API they were built against by exposing the
+ * symbol qemu_plugin_version which can be checked.
+ */
+
+extern QEMU_PLUGIN_EXPORT int qemu_plugin_version;
+
+#define QEMU_PLUGIN_VERSION 0
+
 typedef struct {
     /* string describing architecture */
     const char *target_name;
+    struct {
+        int min;
+        int cur;
+    } version;
     /* is this a full system emulation? */
     bool system_emulation;
     union {
index ce724ed583985b8f3fe0c4ec0c3826df2e03a2b0..15fc7e55156393c1130cd2521e3aabb841f8261c 100644 (file)
@@ -178,6 +178,25 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
         goto err_symbol;
     }
 
+    if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) {
+        error_report("TCG plugin %s does not declare API version %s",
+                     desc->path, g_module_error());
+        goto err_symbol;
+    } else {
+        int version = *(int *)sym;
+        if (version < QEMU_PLUGIN_MIN_VERSION) {
+            error_report("TCG plugin %s requires API version %d, but "
+                         "this QEMU supports only a minimum version of %d",
+                         desc->path, version, QEMU_PLUGIN_MIN_VERSION);
+            goto err_symbol;
+        } else if (version > QEMU_PLUGIN_VERSION) {
+            error_report("TCG plugin %s requires API version %d, but "
+                         "this QEMU supports only up to version %d",
+                         desc->path, version, QEMU_PLUGIN_VERSION);
+            goto err_symbol;
+        }
+    }
+
     qemu_rec_mutex_lock(&plugin.lock);
 
     /* find an unused random id with &ctx as the seed */
@@ -248,6 +267,8 @@ int qemu_plugin_load_list(QemuPluginList *head)
     g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
 
     info->target_name = TARGET_NAME;
+    info->version.min = QEMU_PLUGIN_MIN_VERSION;
+    info->version.cur = QEMU_PLUGIN_VERSION;
 #ifndef CONFIG_USER_ONLY
     MachineState *ms = MACHINE(qdev_get_machine());
     info->system_emulation = true;
index 5482168d797ab74cc40ce340b2160a01ba4a373f..1aa29dcaddf20d762c59f8571f9bdf6610664934 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <gmodule.h>
 
+#define QEMU_PLUGIN_MIN_VERSION 0
+
 /* global state */
 struct qemu_plugin_state {
     QTAILQ_HEAD(, qemu_plugin_ctx) ctxs;
index 45e1de5bd6842429bff21c230e44fb621cce6535..f30bea08dccfcd502686d370421545e7d4f37f00 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 static uint64_t bb_count;
 static uint64_t insn_count;
 static bool do_inline;
index 3f60f69027875ad21e7dc86457712947b2793584..8fa6bacd93d25e0b95f7b2c6f5a4a63b42ff83dd 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 /*
  * Empty TB translation callback.
  * This allows us to measure the overhead of injecting and then
index 1bd183849a120bf609eca1068f44bf93546d2646..3942a2ca544cc2cebeb8e788f03ccabd8f3f98a7 100644 (file)
@@ -15,6 +15,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 static bool do_inline;
 
 /* Plugins need to take care of their own locking */
index 77df07a3ccf0499903dc28afc0a3555e1976a711..ecd6c187327a27d9c302b46668e562c477892b7a 100644 (file)
@@ -18,6 +18,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 static uint64_t page_size = 4096;
index 58fa675e3487d77d227040546ec06375bf42d314..4ca555e123916d763eb99d83fbb48939a56e1429 100644 (file)
@@ -20,6 +20,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 typedef enum {
index e5fd07fb64b7564a304c5fe77b7797ba42f461ac..0a8f5a0000edfe6423260bff680d7343f3fd75e0 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 static uint64_t insn_count;
 static bool do_inline;
 
index d967388989601b4cbd889f6cb228bebe204e7bcf..878abf09d19b256ed9c63a540d52ffbe6c6ba5af 100644 (file)
@@ -14,6 +14,8 @@
 
 #include <qemu-plugin.h>
 
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
 static uint64_t mem_count;
 static uint64_t io_count;
 static bool do_inline;