#include "qemu/rcu_queue.h"
#include "qemu/qht.h"
#include "qemu/bitmap.h"
+#include "qemu/cacheinfo.h"
#include "qemu/xxhash.h"
#include "qemu/plugin.h"
+#include "qemu/memalign.h"
#include "hw/core/cpu.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
+#include "exec/tb-flush.h"
#ifndef CONFIG_USER_ONLY
#include "hw/boards.h"
#endif
+#include "qemu/compiler.h"
#include "plugin.h"
{
struct qemu_plugin_parse_arg *arg = opaque;
struct qemu_plugin_desc *p;
+ bool is_on;
+ char *fullarg;
if (strcmp(name, "file") == 0) {
if (strcmp(value, "") == 0) {
QTAILQ_INSERT_TAIL(arg->head, p, entry);
}
arg->curr = p;
- } else if (strcmp(name, "arg") == 0) {
+ } else {
if (arg->curr == NULL) {
error_setg(errp, "missing earlier '-plugin file=' option");
return 1;
}
+
+ if (g_strcmp0(name, "arg") == 0 &&
+ !qapi_bool_parse(name, value, &is_on, NULL)) {
+ if (strchr(value, '=') == NULL) {
+ /* Will treat arg="argname" as "argname=on" */
+ fullarg = g_strdup_printf("%s=%s", value, "on");
+ } else {
+ fullarg = g_strdup_printf("%s", value);
+ }
+ warn_report("using 'arg=%s' is deprecated", value);
+ error_printf("Please use '%s' directly\n", fullarg);
+ } else {
+ fullarg = g_strdup_printf("%s=%s", name, value);
+ }
+
p = arg->curr;
p->argc++;
p->argv = g_realloc_n(p->argv, p->argc, sizeof(char *));
- p->argv[p->argc - 1] = g_strdup(value);
- } else {
- error_setg(errp, "-plugin: unexpected parameter '%s'; ignored", name);
+ p->argv[p->argc - 1] = fullarg;
}
+
return 0;
}
-void qemu_plugin_opt_parse(const char *optarg, QemuPluginList *head)
+void qemu_plugin_opt_parse(const char *optstr, QemuPluginList *head)
{
struct qemu_plugin_parse_arg arg;
QemuOpts *opts;
- opts = qemu_opts_parse_noisily(qemu_find_opts("plugin"), optarg, true);
+ opts = qemu_opts_parse_noisily(qemu_find_opts("plugin"), optstr, true);
if (opts == NULL) {
exit(1);
}
return x * UINT64_C(2685821657736338717);
}
-static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info)
+/*
+ * Disable CFI checks.
+ * The install and version functions have been loaded from an external library
+ * so we do not have type information
+ */
+QEMU_DISABLE_CFI
+static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp)
{
qemu_plugin_install_func_t install;
struct qemu_plugin_ctx *ctx;
ctx->handle = g_module_open(desc->path, G_MODULE_BIND_LOCAL);
if (ctx->handle == NULL) {
- error_report("%s: %s", __func__, g_module_error());
+ error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
goto err_dlopen;
}
if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) {
- error_report("%s: %s", __func__, g_module_error());
+ error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error());
goto err_symbol;
}
install = (qemu_plugin_install_func_t) sym;
/* symbol was found; it could be NULL though */
if (install == NULL) {
- error_report("%s: %s: qemu_plugin_install is NULL",
- __func__, desc->path);
+ error_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL",
+ desc->path);
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());
+ error_setg(errp, "Could not load plugin %s: plugin 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);
+ error_setg(errp, "Could not load plugin %s: plugin 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);
+ error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but "
+ "this QEMU supports only up to version %d",
+ desc->path, version, QEMU_PLUGIN_VERSION);
goto err_symbol;
}
}
rc = install(ctx->id, info, desc->argc, desc->argv);
ctx->installing = false;
if (rc) {
- error_report("%s: qemu_plugin_install returned error code %d",
- __func__, rc);
+ error_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d",
+ desc->path, rc);
/*
* we cannot rely on the plugin doing its own cleanup, so
* call a full uninstall if the plugin did not yet call it.
return rc;
err_symbol:
+ g_module_close(ctx->handle);
err_dlopen:
qemu_vfree(ctx);
return 1;
* Note: the descriptor of each successfully installed plugin is removed
* from the list given by @head.
*/
-int qemu_plugin_load_list(QemuPluginList *head)
+int qemu_plugin_load_list(QemuPluginList *head, Error **errp)
{
struct qemu_plugin_desc *desc, *next;
g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1);
QTAILQ_FOREACH_SAFE(desc, head, entry, next) {
int err;
- err = plugin_load(desc, info);
+ err = plugin_load(desc, info, errp);
if (err) {
return err;
}