1 /* 2 * QEMU Plugin Core Loader Code 3 * 4 * This is the code responsible for loading and unloading the plugins. 5 * Aside from the basic housekeeping tasks we also need to ensure any 6 * generated code is flushed when we remove a plugin so we cannot end 7 * up calling and unloaded helper function. 8 * 9 * Copyright (C) 2017, Emilio G. Cota <cota@braap.org> 10 * Copyright (C) 2019, Linaro 11 * 12 * License: GNU GPL, version 2 or later. 13 * See the COPYING file in the top-level directory. 14 * 15 * SPDX-License-Identifier: GPL-2.0-or-later 16 */ 17 18 #include "qemu/osdep.h" 19 #include "qemu/error-report.h" 20 #include "qemu/config-file.h" 21 #include "qapi/error.h" 22 #include "qemu/lockable.h" 23 #include "qemu/option.h" 24 #include "qemu/rcu_queue.h" 25 #include "qemu/qht.h" 26 #include "qemu/bitmap.h" 27 #include "qemu/cacheinfo.h" 28 #include "qemu/xxhash.h" 29 #include "qemu/plugin.h" 30 #include "qemu/memalign.h" 31 #include "hw/core/cpu.h" 32 #include "exec/tb-flush.h" 33 #ifndef CONFIG_USER_ONLY 34 #include "hw/boards.h" 35 #endif 36 37 #include "plugin.h" 38 39 /* 40 * For convenience we use a bitmap for plugin.mask, but really all we need is a 41 * u32, which is what we store in TranslationBlock. 42 */ 43 QEMU_BUILD_BUG_ON(QEMU_PLUGIN_EV_MAX > 32); 44 45 struct qemu_plugin_desc { 46 char *path; 47 char **argv; 48 QTAILQ_ENTRY(qemu_plugin_desc) entry; 49 int argc; 50 }; 51 52 struct qemu_plugin_parse_arg { 53 QemuPluginList *head; 54 struct qemu_plugin_desc *curr; 55 }; 56 57 QemuOptsList qemu_plugin_opts = { 58 .name = "plugin", 59 .implied_opt_name = "file", 60 .head = QTAILQ_HEAD_INITIALIZER(qemu_plugin_opts.head), 61 .desc = { 62 /* do our own parsing to support multiple plugins */ 63 { /* end of list */ } 64 }, 65 }; 66 67 typedef int (*qemu_plugin_install_func_t)(qemu_plugin_id_t, const qemu_info_t *, int, char **); 68 69 extern struct qemu_plugin_state plugin; 70 71 void qemu_plugin_add_dyn_cb_arr(GArray *arr) 72 { 73 uint32_t hash = qemu_xxhash2((uint64_t)(uintptr_t)arr); 74 bool inserted; 75 76 inserted = qht_insert(&plugin.dyn_cb_arr_ht, arr, hash, NULL); 77 g_assert(inserted); 78 } 79 80 static struct qemu_plugin_desc *plugin_find_desc(QemuPluginList *head, 81 const char *path) 82 { 83 struct qemu_plugin_desc *desc; 84 85 QTAILQ_FOREACH(desc, head, entry) { 86 if (strcmp(desc->path, path) == 0) { 87 return desc; 88 } 89 } 90 return NULL; 91 } 92 93 static int plugin_add(void *opaque, const char *name, const char *value, 94 Error **errp) 95 { 96 struct qemu_plugin_parse_arg *arg = opaque; 97 struct qemu_plugin_desc *p; 98 bool is_on; 99 char *fullarg; 100 101 if (strcmp(name, "file") == 0) { 102 if (strcmp(value, "") == 0) { 103 error_setg(errp, "requires a non-empty argument"); 104 return 1; 105 } 106 p = plugin_find_desc(arg->head, value); 107 if (p == NULL) { 108 p = g_new0(struct qemu_plugin_desc, 1); 109 p->path = g_strdup(value); 110 QTAILQ_INSERT_TAIL(arg->head, p, entry); 111 } 112 arg->curr = p; 113 } else { 114 if (arg->curr == NULL) { 115 error_setg(errp, "missing earlier '-plugin file=' option"); 116 return 1; 117 } 118 119 if (g_strcmp0(name, "arg") == 0 && 120 !qapi_bool_parse(name, value, &is_on, NULL)) { 121 if (strchr(value, '=') == NULL) { 122 /* Will treat arg="argname" as "argname=on" */ 123 fullarg = g_strdup_printf("%s=%s", value, "on"); 124 } else { 125 fullarg = g_strdup_printf("%s", value); 126 } 127 warn_report("using 'arg=%s' is deprecated", value); 128 error_printf("Please use '%s' directly\n", fullarg); 129 } else { 130 fullarg = g_strdup_printf("%s=%s", name, value); 131 } 132 133 p = arg->curr; 134 p->argc++; 135 p->argv = g_realloc_n(p->argv, p->argc, sizeof(char *)); 136 p->argv[p->argc - 1] = fullarg; 137 } 138 139 return 0; 140 } 141 142 void qemu_plugin_opt_parse(const char *optstr, QemuPluginList *head) 143 { 144 struct qemu_plugin_parse_arg arg; 145 QemuOpts *opts; 146 147 opts = qemu_opts_parse_noisily(qemu_find_opts("plugin"), optstr, true); 148 if (opts == NULL) { 149 exit(1); 150 } 151 arg.head = head; 152 arg.curr = NULL; 153 qemu_opt_foreach(opts, plugin_add, &arg, &error_fatal); 154 qemu_opts_del(opts); 155 } 156 157 /* 158 * From: https://en.wikipedia.org/wiki/Xorshift 159 * This is faster than rand_r(), and gives us a wider range (RAND_MAX is only 160 * guaranteed to be >= INT_MAX). 161 */ 162 static uint64_t xorshift64star(uint64_t x) 163 { 164 x ^= x >> 12; /* a */ 165 x ^= x << 25; /* b */ 166 x ^= x >> 27; /* c */ 167 return x * UINT64_C(2685821657736338717); 168 } 169 170 /* 171 * Disable CFI checks. 172 * The install and version functions have been loaded from an external library 173 * so we do not have type information 174 */ 175 QEMU_DISABLE_CFI 176 static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info, Error **errp) 177 { 178 qemu_plugin_install_func_t install; 179 struct qemu_plugin_ctx *ctx; 180 gpointer sym; 181 int rc; 182 183 ctx = qemu_memalign(qemu_dcache_linesize, sizeof(*ctx)); 184 memset(ctx, 0, sizeof(*ctx)); 185 ctx->desc = desc; 186 187 ctx->handle = g_module_open(desc->path, G_MODULE_BIND_LOCAL); 188 if (ctx->handle == NULL) { 189 error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error()); 190 goto err_dlopen; 191 } 192 193 if (!g_module_symbol(ctx->handle, "qemu_plugin_install", &sym)) { 194 error_setg(errp, "Could not load plugin %s: %s", desc->path, g_module_error()); 195 goto err_symbol; 196 } 197 install = (qemu_plugin_install_func_t) sym; 198 /* symbol was found; it could be NULL though */ 199 if (install == NULL) { 200 error_setg(errp, "Could not load plugin %s: qemu_plugin_install is NULL", 201 desc->path); 202 goto err_symbol; 203 } 204 205 if (!g_module_symbol(ctx->handle, "qemu_plugin_version", &sym)) { 206 error_setg(errp, "Could not load plugin %s: plugin does not declare API version %s", 207 desc->path, g_module_error()); 208 goto err_symbol; 209 } else { 210 int version = *(int *)sym; 211 if (version < QEMU_PLUGIN_MIN_VERSION) { 212 error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but " 213 "this QEMU supports only a minimum version of %d", 214 desc->path, version, QEMU_PLUGIN_MIN_VERSION); 215 goto err_symbol; 216 } else if (version > QEMU_PLUGIN_VERSION) { 217 error_setg(errp, "Could not load plugin %s: plugin requires API version %d, but " 218 "this QEMU supports only up to version %d", 219 desc->path, version, QEMU_PLUGIN_VERSION); 220 goto err_symbol; 221 } 222 } 223 224 qemu_rec_mutex_lock(&plugin.lock); 225 226 /* find an unused random id with &ctx as the seed */ 227 ctx->id = (uint64_t)(uintptr_t)ctx; 228 for (;;) { 229 void *existing; 230 231 ctx->id = xorshift64star(ctx->id); 232 existing = g_hash_table_lookup(plugin.id_ht, &ctx->id); 233 if (likely(existing == NULL)) { 234 bool success; 235 236 success = g_hash_table_insert(plugin.id_ht, &ctx->id, &ctx->id); 237 g_assert(success); 238 break; 239 } 240 } 241 QTAILQ_INSERT_TAIL(&plugin.ctxs, ctx, entry); 242 ctx->installing = true; 243 rc = install(ctx->id, info, desc->argc, desc->argv); 244 ctx->installing = false; 245 if (rc) { 246 error_setg(errp, "Could not load plugin %s: qemu_plugin_install returned error code %d", 247 desc->path, rc); 248 /* 249 * we cannot rely on the plugin doing its own cleanup, so 250 * call a full uninstall if the plugin did not yet call it. 251 */ 252 if (!ctx->uninstalling) { 253 plugin_reset_uninstall(ctx->id, NULL, false); 254 } 255 } 256 257 qemu_rec_mutex_unlock(&plugin.lock); 258 return rc; 259 260 err_symbol: 261 g_module_close(ctx->handle); 262 err_dlopen: 263 qemu_vfree(ctx); 264 return 1; 265 } 266 267 /* call after having removed @desc from the list */ 268 static void plugin_desc_free(struct qemu_plugin_desc *desc) 269 { 270 int i; 271 272 for (i = 0; i < desc->argc; i++) { 273 g_free(desc->argv[i]); 274 } 275 g_free(desc->argv); 276 g_free(desc->path); 277 g_free(desc); 278 } 279 280 /** 281 * qemu_plugin_load_list - load a list of plugins 282 * @head: head of the list of descriptors of the plugins to be loaded 283 * 284 * Returns 0 if all plugins in the list are installed, !0 otherwise. 285 * 286 * Note: the descriptor of each successfully installed plugin is removed 287 * from the list given by @head. 288 */ 289 int qemu_plugin_load_list(QemuPluginList *head, Error **errp) 290 { 291 struct qemu_plugin_desc *desc, *next; 292 g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1); 293 294 info->target_name = TARGET_NAME; 295 info->version.min = QEMU_PLUGIN_MIN_VERSION; 296 info->version.cur = QEMU_PLUGIN_VERSION; 297 #ifndef CONFIG_USER_ONLY 298 MachineState *ms = MACHINE(qdev_get_machine()); 299 info->system_emulation = true; 300 info->system.smp_vcpus = ms->smp.cpus; 301 info->system.max_vcpus = ms->smp.max_cpus; 302 #else 303 info->system_emulation = false; 304 #endif 305 306 QTAILQ_FOREACH_SAFE(desc, head, entry, next) { 307 int err; 308 309 err = plugin_load(desc, info, errp); 310 if (err) { 311 return err; 312 } 313 QTAILQ_REMOVE(head, desc, entry); 314 } 315 return 0; 316 } 317 318 struct qemu_plugin_reset_data { 319 struct qemu_plugin_ctx *ctx; 320 qemu_plugin_simple_cb_t cb; 321 bool reset; 322 }; 323 324 static void plugin_reset_destroy__locked(struct qemu_plugin_reset_data *data) 325 { 326 struct qemu_plugin_ctx *ctx = data->ctx; 327 enum qemu_plugin_event ev; 328 bool success; 329 330 /* 331 * After updating the subscription lists there is no need to wait for an RCU 332 * grace period to elapse, because right now we either are in a "safe async" 333 * work environment (i.e. all vCPUs are asleep), or no vCPUs have yet been 334 * created. 335 */ 336 for (ev = 0; ev < QEMU_PLUGIN_EV_MAX; ev++) { 337 plugin_unregister_cb__locked(ctx, ev); 338 } 339 340 if (data->reset) { 341 g_assert(ctx->resetting); 342 if (data->cb) { 343 data->cb(ctx->id); 344 } 345 ctx->resetting = false; 346 g_free(data); 347 return; 348 } 349 350 g_assert(ctx->uninstalling); 351 /* we cannot dlclose if we are going to return to plugin code */ 352 if (ctx->installing) { 353 error_report("Calling qemu_plugin_uninstall from the install function " 354 "is a bug. Instead, return !0 from the install function."); 355 abort(); 356 } 357 358 success = g_hash_table_remove(plugin.id_ht, &ctx->id); 359 g_assert(success); 360 QTAILQ_REMOVE(&plugin.ctxs, ctx, entry); 361 if (data->cb) { 362 data->cb(ctx->id); 363 } 364 if (!g_module_close(ctx->handle)) { 365 warn_report("%s: %s", __func__, g_module_error()); 366 } 367 plugin_desc_free(ctx->desc); 368 qemu_vfree(ctx); 369 g_free(data); 370 } 371 372 static void plugin_reset_destroy(struct qemu_plugin_reset_data *data) 373 { 374 qemu_rec_mutex_lock(&plugin.lock); 375 plugin_reset_destroy__locked(data); 376 qemu_rec_mutex_lock(&plugin.lock); 377 } 378 379 static void plugin_flush_destroy(CPUState *cpu, run_on_cpu_data arg) 380 { 381 struct qemu_plugin_reset_data *data = arg.host_ptr; 382 383 g_assert(cpu_in_exclusive_context(cpu)); 384 tb_flush(cpu); 385 plugin_reset_destroy(data); 386 } 387 388 void plugin_reset_uninstall(qemu_plugin_id_t id, 389 qemu_plugin_simple_cb_t cb, 390 bool reset) 391 { 392 struct qemu_plugin_reset_data *data; 393 struct qemu_plugin_ctx *ctx; 394 395 WITH_QEMU_LOCK_GUARD(&plugin.lock) { 396 ctx = plugin_id_to_ctx_locked(id); 397 if (ctx->uninstalling || (reset && ctx->resetting)) { 398 return; 399 } 400 ctx->resetting = reset; 401 ctx->uninstalling = !reset; 402 } 403 404 data = g_new(struct qemu_plugin_reset_data, 1); 405 data->ctx = ctx; 406 data->cb = cb; 407 data->reset = reset; 408 /* 409 * Only flush the code cache if the vCPUs have been created. If so, 410 * current_cpu must be non-NULL. 411 */ 412 if (current_cpu) { 413 async_safe_run_on_cpu(current_cpu, plugin_flush_destroy, 414 RUN_ON_CPU_HOST_PTR(data)); 415 } else { 416 /* 417 * If current_cpu isn't set, then we don't have yet any vCPU threads 418 * and we therefore can remove the callbacks synchronously. 419 */ 420 plugin_reset_destroy(data); 421 } 422 } 423