mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
qom: add support for qom objects in modules.
build some devices (qxl, virtio-gpu, ccid, usb-redir) as modules. build braille chardev as module. v2: more verbose comment for "build: fix device module builds" patch. note: qemu doesn't rebuild objects on cflags changes (specifically -fPIC being added when code is switched from builtin to module). Workaround for resulting build errors: "make clean", rebuild. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCgAGBQJfBHu4AAoJEEy22O7T6HE4uh8P/0clQVfXb8jBsCnLw2dJuvdx rJzgZTn5BQElCmZYN43LElyCcD7DO2Exz6JtV554oK/tjH/QkOKAKzPzk+FzhKta 3zyGvlS79KMHoMoIf6xSIbSv3/jt2iP9TU9HpaHXIBQJTAtExAasEPtr3ewgAhDv wd5FC/slM7NNofQgyz5ycAKGddwOYFP/zAnTZPU2noCek2B86OgBX+BN5VIaxn/g Reuk4z0QBLWXGmb2j6RbmBKZ61V/qokpz9OjwZ1reRU+tTXOzhu8ROr+GDmNj3D8 m8mt1t8UUIH35Zo9Lc0+4P6aKCk5gQI4tYukut/8zXqnNdPhQxsnCFiR1U8kZter +189dhVXLZ+vp8IMe7piu/a4iU/5Jgz30VUOetrAM0CDjzuI0Bbp1wSjgiLyZ9EC CZLxIm2lZCHCr92G4UtmUR0dnacoee96bsAs/Rd9U3DWRLaDwuTNGYPfW1J5fEyn nqLscU/8H2H8tQhSjX8nTkxXh29/bA1pzb/auPKkajS+rblACWgYyj8035VyWIiB NTJZzvXXAxLNObLZSLteUQLOn5ugjmicH7Q8RJZmcQzudq0PDlJrF8vXJ2R6PZLF 4ecSgy1b1xA7xvXc4tAdtnlcVvVl/LU5EMWooQP26cKZzJOM0GnUUlBo+K6oEQTf 0lXrg6LAhH1sevdFzhNd =DVlH -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kraxel/tags/modules-20200707-pull-request' into staging qom: add support for qom objects in modules. build some devices (qxl, virtio-gpu, ccid, usb-redir) as modules. build braille chardev as module. v2: more verbose comment for "build: fix device module builds" patch. note: qemu doesn't rebuild objects on cflags changes (specifically -fPIC being added when code is switched from builtin to module). Workaround for resulting build errors: "make clean", rebuild. # gpg: Signature made Tue 07 Jul 2020 14:42:16 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/modules-20200707-pull-request: chardev: enable modules, use for braille vga: build virtio-gpu as module vga: build virtio-gpu only once vga: build qxl as module usb: build usb-redir as module ccid: build smartcard as module build: fix device module builds qdev: device module support object: qom module support module: qom module support Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
aff2caf6b3
@ -59,6 +59,7 @@ common-obj-y += migration/
|
||||
common-obj-y += audio/
|
||||
common-obj-m += audio/
|
||||
common-obj-y += hw/
|
||||
common-obj-m += hw/
|
||||
|
||||
common-obj-y += replay/
|
||||
|
||||
@ -70,6 +71,7 @@ common-obj-$(CONFIG_TPM) += tpm.o
|
||||
|
||||
common-obj-y += backends/
|
||||
common-obj-y += chardev/
|
||||
common-obj-m += chardev/
|
||||
|
||||
common-obj-$(CONFIG_SECCOMP) += qemu-seccomp.o
|
||||
qemu-seccomp.o-cflags := $(SECCOMP_CFLAGS)
|
||||
|
@ -179,6 +179,20 @@ endif # CONFIG_SOFTMMU
|
||||
dummy := $(call unnest-vars,,obj-y)
|
||||
all-obj-y := $(obj-y)
|
||||
|
||||
#
|
||||
# common-obj-m has some crap here, probably as side effect from
|
||||
# unnest-vars recursing into target directories to fill obj-y and not
|
||||
# properly handling the -m case.
|
||||
#
|
||||
# Clear common-obj-m as workaround. Fixes suspious dependency errors
|
||||
# when building devices as modules. A bit hackish, but should be ok
|
||||
# as long as we do not have any target-specific modules.
|
||||
#
|
||||
# The meson-based build system currently in development doesn't need
|
||||
# unnest-vars and will obsolete this workaround.
|
||||
#
|
||||
common-obj-m :=
|
||||
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
dummy := $(call unnest-vars,.., \
|
||||
authz-obj-y \
|
||||
|
@ -18,8 +18,11 @@ chardev-obj-$(CONFIG_WIN32) += char-win.o
|
||||
chardev-obj-$(CONFIG_WIN32) += char-win-stdio.o
|
||||
|
||||
common-obj-y += msmouse.o wctablet.o testdev.o
|
||||
common-obj-$(CONFIG_BRLAPI) += baum.o
|
||||
|
||||
ifeq ($(CONFIG_BRLAPI),y)
|
||||
common-obj-m += baum.o
|
||||
baum.o-cflags := $(SDL_CFLAGS)
|
||||
baum.o-libs := $(BRLAPI_LIBS)
|
||||
endif
|
||||
|
||||
common-obj-$(CONFIG_SPICE) += spice.o
|
||||
|
@ -527,7 +527,7 @@ static const ChardevClass *char_get_class(const char *driver, Error **errp)
|
||||
const ChardevClass *cc;
|
||||
char *typename = g_strdup_printf("chardev-%s", driver);
|
||||
|
||||
oc = object_class_by_name(typename);
|
||||
oc = module_object_class_by_name(typename);
|
||||
g_free(typename);
|
||||
|
||||
if (!object_class_dynamic_cast(oc, TYPE_CHARDEV)) {
|
||||
|
@ -43,4 +43,6 @@ devices-dirs-y += smbios/
|
||||
endif
|
||||
|
||||
common-obj-y += $(devices-dirs-y)
|
||||
common-obj-m += display/
|
||||
common-obj-m += usb/
|
||||
obj-y += $(devices-dirs-y)
|
||||
|
@ -137,6 +137,9 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus)
|
||||
*/
|
||||
DeviceState *qdev_new(const char *name)
|
||||
{
|
||||
if (!object_class_by_name(name)) {
|
||||
module_load_qom_one(name);
|
||||
}
|
||||
return DEVICE(object_new(name));
|
||||
}
|
||||
|
||||
@ -147,10 +150,9 @@ DeviceState *qdev_new(const char *name)
|
||||
*/
|
||||
DeviceState *qdev_try_new(const char *name)
|
||||
{
|
||||
if (!object_class_by_name(name)) {
|
||||
if (!module_object_class_by_name(name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return DEVICE(object_new(name));
|
||||
}
|
||||
|
||||
|
@ -44,18 +44,24 @@ common-obj-$(CONFIG_ARTIST) += artist.o
|
||||
|
||||
obj-$(CONFIG_VGA) += vga.o
|
||||
|
||||
common-obj-$(CONFIG_QXL) += qxl.o qxl-logger.o qxl-render.o
|
||||
ifeq ($(CONFIG_QXL),y)
|
||||
common-obj-m += qxl.mo
|
||||
qxl.mo-objs = qxl.o qxl-logger.o qxl-render.o
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_VIRTIO_GPU),y)
|
||||
common-obj-m += virtio-gpu.mo
|
||||
virtio-gpu-obj-$(CONFIG_VIRTIO_GPU) += virtio-gpu-base.o virtio-gpu.o virtio-gpu-3d.o
|
||||
virtio-gpu-obj-$(CONFIG_VHOST_USER_GPU) += vhost-user-gpu.o
|
||||
virtio-gpu-obj-$(call land,$(CONFIG_VIRTIO_GPU),$(CONFIG_VIRTIO_PCI)) += virtio-gpu-pci.o
|
||||
virtio-gpu-obj-$(call land,$(CONFIG_VHOST_USER_GPU),$(CONFIG_VIRTIO_PCI)) += vhost-user-gpu-pci.o
|
||||
virtio-gpu-obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o
|
||||
virtio-gpu-obj-$(CONFIG_VHOST_USER_VGA) += vhost-user-vga.o
|
||||
virtio-gpu.mo-objs := $(virtio-gpu-obj-y)
|
||||
virtio-gpu.mo-cflags := $(VIRGL_CFLAGS)
|
||||
virtio-gpu.mo-libs := $(VIRGL_LIBS)
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_VIRTIO_GPU) += virtio-gpu-base.o virtio-gpu.o virtio-gpu-3d.o
|
||||
obj-$(CONFIG_VHOST_USER_GPU) += vhost-user-gpu.o
|
||||
obj-$(call land,$(CONFIG_VIRTIO_GPU),$(CONFIG_VIRTIO_PCI)) += virtio-gpu-pci.o
|
||||
obj-$(call land,$(CONFIG_VHOST_USER_GPU),$(CONFIG_VIRTIO_PCI)) += vhost-user-gpu-pci.o
|
||||
obj-$(CONFIG_VIRTIO_VGA) += virtio-vga.o
|
||||
obj-$(CONFIG_VHOST_USER_VGA) += vhost-user-vga.o
|
||||
virtio-gpu.o-cflags := $(VIRGL_CFLAGS)
|
||||
virtio-gpu.o-libs += $(VIRGL_LIBS)
|
||||
virtio-gpu-3d.o-cflags := $(VIRGL_CFLAGS)
|
||||
virtio-gpu-3d.o-libs += $(VIRGL_LIBS)
|
||||
common-obj-$(CONFIG_DPCD) += dpcd.o
|
||||
common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx_dp.o
|
||||
|
||||
|
@ -29,11 +29,13 @@ common-obj-$(CONFIG_USB_NETWORK) += dev-network.o
|
||||
|
||||
ifeq ($(CONFIG_USB_SMARTCARD),y)
|
||||
common-obj-y += dev-smartcard-reader.o
|
||||
common-obj-$(CONFIG_SMARTCARD) += smartcard.mo
|
||||
ifeq ($(CONFIG_SMARTCARD),y)
|
||||
common-obj-m += smartcard.mo
|
||||
smartcard.mo-objs := ccid-card-passthru.o ccid-card-emulated.o
|
||||
smartcard.mo-cflags := $(SMARTCARD_CFLAGS)
|
||||
smartcard.mo-libs := $(SMARTCARD_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_POSIX),y)
|
||||
common-obj-$(CONFIG_USB_STORAGE_MTP) += dev-mtp.o
|
||||
@ -41,9 +43,12 @@ endif
|
||||
|
||||
# usb redirection
|
||||
ifeq ($(CONFIG_USB),y)
|
||||
common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
|
||||
redirect.o-cflags = $(USB_REDIR_CFLAGS)
|
||||
redirect.o-libs = $(USB_REDIR_LIBS)
|
||||
ifeq ($(CONFIG_USB_REDIR),y)
|
||||
common-obj-m += redirect.mo
|
||||
redirect.mo-objs = redirect.o quirks.o
|
||||
redirect.mo-cflags = $(USB_REDIR_CFLAGS)
|
||||
redirect.mo-libs = $(USB_REDIR_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
# usb pass-through
|
||||
|
@ -70,5 +70,7 @@ void register_dso_module_init(void (*fn)(void), module_init_type type);
|
||||
|
||||
void module_call_init(module_init_type type);
|
||||
bool module_load_one(const char *prefix, const char *lib_name);
|
||||
void module_load_qom_one(const char *type);
|
||||
void module_load_qom_all(void);
|
||||
|
||||
#endif
|
||||
|
@ -994,6 +994,18 @@ bool object_class_is_abstract(ObjectClass *klass);
|
||||
*/
|
||||
ObjectClass *object_class_by_name(const char *typename);
|
||||
|
||||
/**
|
||||
* module_object_class_by_name:
|
||||
* @typename: The QOM typename to obtain the class for.
|
||||
*
|
||||
* For objects which might be provided by a module. Behaves like
|
||||
* object_class_by_name, but additionally tries to load the module
|
||||
* needed in case the class is not available.
|
||||
*
|
||||
* Returns: The class for @typename or %NULL if not found.
|
||||
*/
|
||||
ObjectClass *module_object_class_by_name(const char *typename);
|
||||
|
||||
void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
|
||||
const char *implements_type, bool include_abstract,
|
||||
void *opaque);
|
||||
|
@ -149,6 +149,7 @@ static void qdev_print_devinfos(bool show_no_user)
|
||||
int i;
|
||||
bool cat_printed;
|
||||
|
||||
module_load_qom_all();
|
||||
list = object_class_get_list_sorted(TYPE_DEVICE, false);
|
||||
|
||||
for (i = 0; i <= DEVICE_CATEGORY_MAX; i++) {
|
||||
@ -217,13 +218,13 @@ static DeviceClass *qdev_get_device_class(const char **driver, Error **errp)
|
||||
DeviceClass *dc;
|
||||
const char *original_name = *driver;
|
||||
|
||||
oc = object_class_by_name(*driver);
|
||||
oc = module_object_class_by_name(*driver);
|
||||
if (!oc) {
|
||||
const char *typename = find_typename_by_alias(*driver);
|
||||
|
||||
if (typename) {
|
||||
*driver = typename;
|
||||
oc = object_class_by_name(*driver);
|
||||
oc = module_object_class_by_name(*driver);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
qom/object.c
14
qom/object.c
@ -985,6 +985,20 @@ ObjectClass *object_class_by_name(const char *typename)
|
||||
return type->class;
|
||||
}
|
||||
|
||||
ObjectClass *module_object_class_by_name(const char *typename)
|
||||
{
|
||||
ObjectClass *oc;
|
||||
|
||||
oc = object_class_by_name(typename);
|
||||
#ifdef CONFIG_MODULES
|
||||
if (!oc) {
|
||||
module_load_qom_one(typename);
|
||||
oc = object_class_by_name(typename);
|
||||
}
|
||||
#endif
|
||||
return oc;
|
||||
}
|
||||
|
||||
ObjectClass *object_class_get_parent(ObjectClass *class)
|
||||
{
|
||||
TypeImpl *type = type_get_parent(class->type);
|
||||
|
@ -116,6 +116,7 @@ ObjectTypeInfoList *qmp_qom_list_types(bool has_implements,
|
||||
{
|
||||
ObjectTypeInfoList *ret = NULL;
|
||||
|
||||
module_load_qom_all();
|
||||
object_class_foreach(qom_list_types_tramp, implements, abstract, &ret);
|
||||
|
||||
return ret;
|
||||
@ -130,7 +131,7 @@ ObjectPropertyInfoList *qmp_device_list_properties(const char *typename,
|
||||
ObjectPropertyIterator iter;
|
||||
ObjectPropertyInfoList *prop_list = NULL;
|
||||
|
||||
klass = object_class_by_name(typename);
|
||||
klass = module_object_class_by_name(typename);
|
||||
if (klass == NULL) {
|
||||
error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
|
||||
"Device '%s' not found", typename);
|
||||
|
@ -1772,8 +1772,8 @@ static bool vga_interface_available(VGAInterfaceType t)
|
||||
|
||||
assert(t < VGA_TYPE_MAX);
|
||||
return !ti->class_names[0] ||
|
||||
object_class_by_name(ti->class_names[0]) ||
|
||||
object_class_by_name(ti->class_names[1]);
|
||||
module_object_class_by_name(ti->class_names[0]) ||
|
||||
module_object_class_by_name(ti->class_names[1]);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -245,3 +245,70 @@ bool module_load_one(const char *prefix, const char *lib_name)
|
||||
#endif
|
||||
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
|
||||
* to rule and the list will not gain that many entries go with a
|
||||
* simple manually maintained list for now.
|
||||
*/
|
||||
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-pci", "hw-", "display-virtio-gpu" },
|
||||
{ "virtio-vga", "hw-", "display-virtio-gpu" },
|
||||
{ "vhost-user-gpu-device", "hw-", "display-virtio-gpu" },
|
||||
{ "vhost-user-gpu-pci", "hw-", "display-virtio-gpu" },
|
||||
{ "vhost-user-vga", "hw-", "display-virtio-gpu" },
|
||||
{ "chardev-braille", "chardev-", "baum" },
|
||||
};
|
||||
|
||||
static bool module_loaded_qom_all;
|
||||
|
||||
void module_load_qom_one(const char *type)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (module_loaded_qom_all) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void module_load_qom_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
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 */
|
||||
continue;
|
||||
}
|
||||
module_load_one(qom_modules[i].prefix, qom_modules[i].module);
|
||||
}
|
||||
module_loaded_qom_all = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user