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