diff options
author | Peter Maydell | 2019-01-14 14:54:17 +0100 |
---|---|---|
committer | Peter Maydell | 2019-01-14 14:54:17 +0100 |
commit | c9d18c1c150c84e7a976df989ad04ddf01083f46 (patch) | |
tree | b4b04c95b9c75162cdf60dbcda51c9ca7563071b /hw/xen/xen-backend.c | |
parent | Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-3.2-part2'... (diff) | |
parent | xen-block: avoid repeated memory allocation (diff) | |
download | qemu-c9d18c1c150c84e7a976df989ad04ddf01083f46.tar.gz qemu-c9d18c1c150c84e7a976df989ad04ddf01083f46.tar.xz qemu-c9d18c1c150c84e7a976df989ad04ddf01083f46.zip |
Merge remote-tracking branch 'remotes/aperard/tags/pull-xen-20190114' into staging
Xen queue
* Xen PV backend 'qdevification'.
Starting with xen_disk.
* Performance improvements for xen-block.
* Remove of the Xen PV domain builder.
* bug fixes.
# gpg: Signature made Mon 14 Jan 2019 13:46:33 GMT
# gpg: using RSA key 0CF5572FD7FB55AF
# gpg: Good signature from "Anthony PERARD <anthony.perard@gmail.com>"
# gpg: aka "Anthony PERARD <anthony.perard@citrix.com>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg: It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 5379 2F71 024C 600F 778A 7161 D8D5 7199 DF83 42C8
# Subkey fingerprint: F80C 0063 08E2 2CFD 8A92 E798 0CF5 572F D7FB 55AF
* remotes/aperard/tags/pull-xen-20190114: (25 commits)
xen-block: avoid repeated memory allocation
xen-block: improve response latency
xen-block: improve batching behaviour
xen: Replace few mentions of xend by libxl
Remove broken Xen PV domain builder
xen: remove the legacy 'xen_disk' backend
MAINTAINERS: add myself as a Xen maintainer
xen: automatically create XenBlockDevice-s
xen: add a mechanism to automatically create XenDevice-s...
xen: add implementations of xen-block connect and disconnect functions...
xen: purge 'blk' and 'ioreq' from function names in dataplane/xen-block.c
xen: remove 'ioreq' struct/varable/field names from dataplane/xen-block.c
xen: remove 'XenBlkDev' and 'blkdev' names from dataplane/xen-block
xen: add header and build dataplane/xen-block.c
xen: remove unnecessary code from dataplane/xen-block.c
xen: duplicate xen_disk.c as basis of dataplane/xen-block.c
xen: add event channel interface for XenDevice-s
xen: add grant table interface for XenDevice-s
xen: add xenstore watcher infrastructure
xen: create xenstore areas for XenDevice-s
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/xen/xen-backend.c')
-rw-r--r-- | hw/xen/xen-backend.c | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/hw/xen/xen-backend.c b/hw/xen/xen-backend.c new file mode 100644 index 0000000000..da065f81b7 --- /dev/null +++ b/hw/xen/xen-backend.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2018 Citrix Systems Inc. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "qapi/error.h" +#include "hw/xen/xen-backend.h" +#include "hw/xen/xen-bus.h" + +typedef struct XenBackendImpl { + const char *type; + XenBackendDeviceCreate create; + XenBackendDeviceDestroy destroy; +} XenBackendImpl; + +struct XenBackendInstance { + QLIST_ENTRY(XenBackendInstance) entry; + const XenBackendImpl *impl; + XenBus *xenbus; + char *name; + XenDevice *xendev; +}; + +static GHashTable *xen_backend_table_get(void) +{ + static GHashTable *table; + + if (table == NULL) { + table = g_hash_table_new(g_str_hash, g_str_equal); + } + + return table; +} + +static void xen_backend_table_add(XenBackendImpl *impl) +{ + g_hash_table_insert(xen_backend_table_get(), (void *)impl->type, impl); +} + +static const XenBackendImpl *xen_backend_table_lookup(const char *type) +{ + return g_hash_table_lookup(xen_backend_table_get(), type); +} + +void xen_backend_register(const XenBackendInfo *info) +{ + XenBackendImpl *impl = g_new0(XenBackendImpl, 1); + + g_assert(info->type); + + if (xen_backend_table_lookup(info->type)) { + error_report("attempt to register duplicate Xen backend type '%s'", + info->type); + abort(); + } + + if (!info->create) { + error_report("backend type '%s' has no creator", info->type); + abort(); + } + + impl->type = info->type; + impl->create = info->create; + impl->destroy = info->destroy; + + xen_backend_table_add(impl); +} + +static QLIST_HEAD(, XenBackendInstance) backend_list; + +static void xen_backend_list_add(XenBackendInstance *backend) +{ + QLIST_INSERT_HEAD(&backend_list, backend, entry); +} + +static XenBackendInstance *xen_backend_list_find(XenDevice *xendev) +{ + XenBackendInstance *backend; + + QLIST_FOREACH(backend, &backend_list, entry) { + if (backend->xendev == xendev) { + return backend; + } + } + + return NULL; +} + +static void xen_backend_list_remove(XenBackendInstance *backend) +{ + QLIST_REMOVE(backend, entry); +} + +void xen_backend_device_create(XenBus *xenbus, const char *type, + const char *name, QDict *opts, Error **errp) +{ + const XenBackendImpl *impl = xen_backend_table_lookup(type); + XenBackendInstance *backend; + Error *local_error = NULL; + + if (!impl) { + return; + } + + backend = g_new0(XenBackendInstance, 1); + backend->xenbus = xenbus; + backend->name = g_strdup(name); + + impl->create(backend, opts, &local_error); + if (local_error) { + error_propagate(errp, local_error); + g_free(backend->name); + g_free(backend); + return; + } + + backend->impl = impl; + xen_backend_list_add(backend); +} + +XenBus *xen_backend_get_bus(XenBackendInstance *backend) +{ + return backend->xenbus; +} + +const char *xen_backend_get_name(XenBackendInstance *backend) +{ + return backend->name; +} + +void xen_backend_set_device(XenBackendInstance *backend, + XenDevice *xendev) +{ + g_assert(!backend->xendev); + backend->xendev = xendev; +} + +XenDevice *xen_backend_get_device(XenBackendInstance *backend) +{ + return backend->xendev; +} + + +bool xen_backend_try_device_destroy(XenDevice *xendev, Error **errp) +{ + XenBackendInstance *backend = xen_backend_list_find(xendev); + const XenBackendImpl *impl; + + if (!backend) { + return false; + } + + impl = backend->impl; + impl->destroy(backend, errp); + + xen_backend_list_remove(backend); + g_free(backend->name); + g_free(backend); + + return true; +} |