diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-07-11 22:20:51 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-07-11 22:20:51 +0100 |
commit | d1987c8114921eb30859854de664f879b5626da7 (patch) | |
tree | fc52e32918b955c996e73018e31f26caf119cc92 /util | |
parent | 86108e23d798bcd3fce35ad271b198f8a8611746 (diff) | |
parent | 411ad8dd80077e98ed465775b044caf1a9482f6c (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.build | 2 | ||||
-rw-r--r-- | util/module.c | 200 | ||||
-rw-r--r-- | util/trace-events | 4 |
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" |