aboutsummaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-07-11 22:20:51 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-07-11 22:20:51 +0100
commitd1987c8114921eb30859854de664f879b5626da7 (patch)
treefc52e32918b955c996e73018e31f26caf119cc92 /util
parent86108e23d798bcd3fce35ad271b198f8a8611746 (diff)
parent411ad8dd80077e98ed465775b044caf1a9482f6c (diff)
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
* More SVM fixes (Lara) * Module annotation database (Gerd) * Memory leak fixes (myself) * Build fixes (myself) * --with-devices-* support (Alex) # gpg: Signature made Fri 09 Jul 2021 17:23:52 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: (48 commits) meson: Use input/output for entitlements target configure: allow the selection of alternate config in the build configs: rename default-configs to configs and reorganise hw/arm: move CONFIG_V7M out of default-devices hw/arm: add dependency on OR_IRQ for XLNX_VERSAL meson: Introduce target-specific Kconfig meson: switch function tests from compilation to linking vl: fix leak of qdict_crumple return value target/i386: fix exceptions for MOV to DR target/i386: Added DR6 and DR7 consistency checks target/i386: Added MSRPM and IOPM size check monitor/tcg: move tcg hmp commands to accel/tcg, register them dynamically usb: build usb-host as module monitor/usb: register 'info usbhost' dynamically usb: drop usb_host_dev_is_scsi_storage hook monitor: allow register hmp commands accel: build tcg modular accel: add tcg module annotations accel: build qtest modular accel: add qtest module annotations ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util')
-rw-r--r--util/meson.build2
-rw-r--r--util/module.c200
-rw-r--r--util/trace-events4
3 files changed, 118 insertions, 88 deletions
diff --git a/util/meson.build b/util/meson.build
index 0ffd7f4bde..779f413c86 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -5,7 +5,7 @@ util_ss.add(when: 'CONFIG_POSIX', if_true: files('fdmon-poll.c'))
if config_host_data.get('CONFIG_EPOLL_CREATE1')
util_ss.add(files('fdmon-epoll.c'))
endif
-util_ss.add(when: ['CONFIG_LINUX_IO_URING', linux_io_uring], if_true: files('fdmon-io_uring.c'))
+util_ss.add(when: linux_io_uring, if_true: files('fdmon-io_uring.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('compatfd.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('event_notifier-posix.c'))
util_ss.add(when: 'CONFIG_POSIX', if_true: files('mmap-alloc.c'))
diff --git a/util/module.c b/util/module.c
index eee8ff2de1..6bb4ad915a 100644
--- a/util/module.c
+++ b/util/module.c
@@ -20,9 +20,11 @@
#include "qemu/queue.h"
#include "qemu/module.h"
#include "qemu/cutils.h"
+#include "qemu/config-file.h"
#ifdef CONFIG_MODULE_UPGRADES
#include "qemu-version.h"
#endif
+#include "trace.h"
typedef struct ModuleEntry
{
@@ -110,6 +112,38 @@ void module_call_init(module_init_type type)
}
#ifdef CONFIG_MODULES
+
+static const QemuModinfo module_info_stub[] = { {
+ /* end of list */
+} };
+static const QemuModinfo *module_info = module_info_stub;
+static const char *module_arch;
+
+void module_init_info(const QemuModinfo *info)
+{
+ module_info = info;
+}
+
+void module_allow_arch(const char *arch)
+{
+ module_arch = arch;
+}
+
+static bool module_check_arch(const QemuModinfo *modinfo)
+{
+ if (modinfo->arch) {
+ if (!module_arch) {
+ /* no arch set -> ignore all */
+ return false;
+ }
+ if (strcmp(module_arch, modinfo->arch) != 0) {
+ /* mismatch */
+ return false;
+ }
+ }
+ return true;
+}
+
static int module_load_file(const char *fname, bool mayfail, bool export_symbols)
{
GModule *g_module;
@@ -164,6 +198,7 @@ static int module_load_file(const char *fname, bool mayfail, bool export_symbols
ret = 0;
}
+ trace_module_load_module(fname);
QTAILQ_FOREACH_SAFE(e, &dso_init_list, node, next) {
QTAILQ_REMOVE(&dso_init_list, e, node);
g_free(e);
@@ -171,28 +206,6 @@ static int module_load_file(const char *fname, bool mayfail, bool export_symbols
out:
return ret;
}
-
-static const struct {
- const char *name;
- const char *dep;
-} module_deps[] = {
- { "audio-spice", "ui-spice-core" },
- { "chardev-spice", "ui-spice-core" },
- { "hw-display-qxl", "ui-spice-core" },
- { "ui-spice-app", "ui-spice-core" },
- { "ui-spice-app", "chardev-spice" },
-
- { "hw-display-virtio-gpu-gl", "hw-display-virtio-gpu" },
- { "hw-display-virtio-gpu-pci-gl", "hw-display-virtio-gpu-pci" },
- { "hw-display-virtio-vga-gl", "hw-display-virtio-vga" },
-
-#ifdef CONFIG_OPENGL
- { "ui-egl-headless", "ui-opengl" },
- { "ui-gtk", "ui-opengl" },
- { "ui-sdl", "ui-opengl" },
- { "ui-spice-core", "ui-opengl" },
-#endif
-};
#endif
bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
@@ -208,9 +221,11 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
char *dirs[5];
char *module_name;
int i = 0, n_dirs = 0;
- int ret, dep;
+ int ret;
bool export_symbols = false;
static GHashTable *loaded_modules;
+ const QemuModinfo *modinfo;
+ const char **sl;
if (!g_module_supported()) {
fprintf(stderr, "Module is not supported by system.\n");
@@ -223,23 +238,37 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
module_name = g_strdup_printf("%s%s", prefix, lib_name);
- for (dep = 0; dep < ARRAY_SIZE(module_deps); dep++) {
- if (strcmp(module_name, module_deps[dep].name) == 0) {
- /* we depend on another module */
- module_load_one("", module_deps[dep].dep, false);
- }
- if (strcmp(module_name, module_deps[dep].dep) == 0) {
- /* another module depends on us */
- export_symbols = true;
- }
- }
-
if (g_hash_table_contains(loaded_modules, module_name)) {
g_free(module_name);
return true;
}
g_hash_table_add(loaded_modules, module_name);
+ for (modinfo = module_info; modinfo->name != NULL; modinfo++) {
+ if (modinfo->arch) {
+ if (strcmp(modinfo->name, module_name) == 0) {
+ if (!module_check_arch(modinfo)) {
+ return false;
+ }
+ }
+ }
+ if (modinfo->deps) {
+ if (strcmp(modinfo->name, module_name) == 0) {
+ /* we depend on other module(s) */
+ for (sl = modinfo->deps; *sl != NULL; sl++) {
+ module_load_one("", *sl, false);
+ }
+ } else {
+ for (sl = modinfo->deps; *sl != NULL; sl++) {
+ if (strcmp(module_name, *sl) == 0) {
+ /* another module depends on us */
+ export_symbols = true;
+ }
+ }
+ }
+ }
+ }
+
search_dir = getenv("QEMU_MODULE_DIR");
if (search_dir != NULL) {
dirs[n_dirs++] = g_strdup_printf("%s", search_dir);
@@ -282,80 +311,77 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail)
return success;
}
-/*
- * Building devices and other qom objects modular is mostly useful in
- * case they have dependencies to external shared libraries, so we can
- * cut down the core qemu library dependencies. Which is the case for
- * only a very few devices & objects.
- *
- * So with the expectation that this will be rather the exception than
- * the rule and the list will not gain that many entries, go with a
- * simple manually maintained list for now.
- *
- * The list must be sorted by module (module_load_qom_all() needs this).
- */
-static struct {
- const char *type;
- const char *prefix;
- const char *module;
-} const qom_modules[] = {
- { "ccid-card-passthru", "hw-", "usb-smartcard" },
- { "ccid-card-emulated", "hw-", "usb-smartcard" },
- { "usb-redir", "hw-", "usb-redirect" },
- { "qxl-vga", "hw-", "display-qxl" },
- { "qxl", "hw-", "display-qxl" },
- { "virtio-gpu-device", "hw-", "display-virtio-gpu" },
- { "virtio-gpu-gl-device", "hw-", "display-virtio-gpu-gl" },
- { "vhost-user-gpu", "hw-", "display-virtio-gpu" },
- { "virtio-gpu-pci-base", "hw-", "display-virtio-gpu-pci" },
- { "virtio-gpu-pci", "hw-", "display-virtio-gpu-pci" },
- { "virtio-gpu-gl-pci", "hw-", "display-virtio-gpu-pci-gl" },
- { "vhost-user-gpu-pci", "hw-", "display-virtio-gpu-pci" },
- { "virtio-gpu-ccw", "hw-", "s390x-virtio-gpu-ccw" },
- { "virtio-vga-base", "hw-", "display-virtio-vga" },
- { "virtio-vga", "hw-", "display-virtio-vga" },
- { "virtio-vga-gl", "hw-", "display-virtio-vga-gl" },
- { "vhost-user-vga", "hw-", "display-virtio-vga" },
- { "chardev-braille", "chardev-", "baum" },
- { "chardev-spicevmc", "chardev-", "spice" },
- { "chardev-spiceport", "chardev-", "spice" },
-};
+#ifdef CONFIG_MODULES
static bool module_loaded_qom_all;
void module_load_qom_one(const char *type)
{
- int i;
+ const QemuModinfo *modinfo;
+ const char **sl;
if (!type) {
return;
}
- for (i = 0; i < ARRAY_SIZE(qom_modules); i++) {
- if (strcmp(qom_modules[i].type, type) == 0) {
- module_load_one(qom_modules[i].prefix,
- qom_modules[i].module,
- false);
- return;
+
+ trace_module_lookup_object_type(type);
+ for (modinfo = module_info; modinfo->name != NULL; modinfo++) {
+ if (!modinfo->objs) {
+ continue;
+ }
+ if (!module_check_arch(modinfo)) {
+ continue;
+ }
+ for (sl = modinfo->objs; *sl != NULL; sl++) {
+ if (strcmp(type, *sl) == 0) {
+ module_load_one("", modinfo->name, false);
+ }
}
}
}
void module_load_qom_all(void)
{
- int i;
+ const QemuModinfo *modinfo;
if (module_loaded_qom_all) {
return;
}
- for (i = 0; i < ARRAY_SIZE(qom_modules); i++) {
- if (i > 0 && (strcmp(qom_modules[i - 1].module,
- qom_modules[i].module) == 0 &&
- strcmp(qom_modules[i - 1].prefix,
- qom_modules[i].prefix) == 0)) {
- /* one module implementing multiple types -> load only once */
+
+ for (modinfo = module_info; modinfo->name != NULL; modinfo++) {
+ if (!modinfo->objs) {
+ continue;
+ }
+ if (!module_check_arch(modinfo)) {
continue;
}
- module_load_one(qom_modules[i].prefix, qom_modules[i].module, true);
+ module_load_one("", modinfo->name, false);
}
module_loaded_qom_all = true;
}
+
+void qemu_load_module_for_opts(const char *group)
+{
+ const QemuModinfo *modinfo;
+ const char **sl;
+
+ for (modinfo = module_info; modinfo->name != NULL; modinfo++) {
+ if (!modinfo->opts) {
+ continue;
+ }
+ for (sl = modinfo->opts; *sl != NULL; sl++) {
+ if (strcmp(group, *sl) == 0) {
+ module_load_one("", modinfo->name, false);
+ }
+ }
+ }
+}
+
+#else
+
+void module_allow_arch(const char *arch) {}
+void qemu_load_module_for_opts(const char *group) {}
+void module_load_qom_one(const char *type) {}
+void module_load_qom_all(void) {}
+
+#endif
diff --git a/util/trace-events b/util/trace-events
index 806cac14a7..c8f53d7d9f 100644
--- a/util/trace-events
+++ b/util/trace-events
@@ -100,3 +100,7 @@ uffd_create_fd_api_failed(int err) "errno: %i"
uffd_create_fd_api_noioctl(uint64_t ioctl_req, uint64_t ioctl_supp) "ioctl_req: 0x%" PRIx64 "ioctl_supp: 0x%" PRIx64
uffd_register_memory_failed(void *addr, uint64_t length, uint64_t mode, int err) "addr: %p length: %" PRIu64 " mode: 0x%" PRIx64 " errno: %i"
uffd_unregister_memory_failed(void *addr, uint64_t length, int err) "addr: %p length: %" PRIu64 " errno: %i"
+
+# module.c
+module_load_module(const char *name) "file %s"
+module_lookup_object_type(const char *name) "name %s"