2 * Copyright (c) 2018 Citrix Systems Inc.
4 * This work is licensed under the terms of the GNU GPL, version 2 or later.
5 * See the COPYING file in the top-level directory.
8 #include "qemu/osdep.h"
9 #include "qemu/main-loop.h"
10 #include "qemu/module.h"
11 #include "qemu/uuid.h"
12 #include "hw/qdev-properties.h"
13 #include "hw/sysbus.h"
14 #include "hw/xen/xen.h"
15 #include "hw/xen/xen-backend.h"
16 #include "hw/xen/xen-bus.h"
17 #include "hw/xen/xen-bus-helper.h"
18 #include "monitor/monitor.h"
19 #include "qapi/error.h"
20 #include "qapi/qmp/qdict.h"
21 #include "sysemu/sysemu.h"
24 static char *xen_device_get_backend_path(XenDevice *xendev)
26 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
27 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
28 const char *type = object_get_typename(OBJECT(xendev));
29 const char *backend = xendev_class->backend;
35 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
36 xenbus->backend_id, backend, xendev->frontend_id,
40 static char *xen_device_get_frontend_path(XenDevice *xendev)
42 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
43 const char *type = object_get_typename(OBJECT(xendev));
44 const char *device = xendev_class->device;
50 return g_strdup_printf("/local/domain/%u/device/%s/%s",
51 xendev->frontend_id, device, xendev->name);
54 static void xen_device_unplug(XenDevice *xendev, Error **errp)
56 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
57 const char *type = object_get_typename(OBJECT(xendev));
58 Error *local_err = NULL;
61 trace_xen_device_unplug(type, xendev->name);
63 /* Mimic the way the Xen toolstack does an unplug */
65 tid = xs_transaction_start(xenbus->xsh);
66 if (tid == XBT_NULL) {
67 error_setg_errno(errp, errno, "failed xs_transaction_start");
71 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
77 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
78 &local_err, "%u", XenbusStateClosing);
83 if (!xs_transaction_end(xenbus->xsh, tid, false)) {
84 if (errno == EAGAIN) {
88 error_setg_errno(errp, errno, "failed xs_transaction_end");
95 * We only abort if there is already a failure so ignore any error
96 * from ending the transaction.
98 xs_transaction_end(xenbus->xsh, tid, true);
99 error_propagate(errp, local_err);
102 static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
104 XenDevice *xendev = XEN_DEVICE(dev);
106 monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
107 indent, "", xendev->name, xendev->frontend_id);
110 static char *xen_bus_get_dev_path(DeviceState *dev)
112 return xen_device_get_backend_path(XEN_DEVICE(dev));
118 XenWatchHandler handler;
123 static void watch_notify(Notifier *n, void *data)
125 XenWatch *watch = container_of(n, XenWatch, notifier);
126 const char *token = data;
128 if (!strcmp(watch->token, token)) {
129 watch->handler(watch->opaque);
133 static XenWatch *new_watch(const char *node, const char *key,
134 XenWatchHandler handler, void *opaque)
136 XenWatch *watch = g_new0(XenWatch, 1);
139 qemu_uuid_generate(&uuid);
141 watch->token = qemu_uuid_unparse_strdup(&uuid);
142 watch->node = g_strdup(node);
143 watch->key = g_strdup(key);
144 watch->handler = handler;
145 watch->opaque = opaque;
146 watch->notifier.notify = watch_notify;
151 static void free_watch(XenWatch *watch)
153 g_free(watch->token);
160 struct XenWatchList {
161 struct xs_handle *xsh;
162 NotifierList notifiers;
165 static void watch_list_event(void *opaque)
167 XenWatchList *watch_list = opaque;
171 v = xs_check_watch(watch_list->xsh);
176 token = v[XS_WATCH_TOKEN];
178 notifier_list_notify(&watch_list->notifiers, (void *)token);
183 static XenWatchList *watch_list_create(struct xs_handle *xsh)
185 XenWatchList *watch_list = g_new0(XenWatchList, 1);
189 watch_list->xsh = xsh;
190 notifier_list_init(&watch_list->notifiers);
191 qemu_set_fd_handler(xs_fileno(watch_list->xsh), watch_list_event, NULL,
197 static void watch_list_destroy(XenWatchList *watch_list)
199 g_assert(notifier_list_empty(&watch_list->notifiers));
200 qemu_set_fd_handler(xs_fileno(watch_list->xsh), NULL, NULL, NULL);
204 static XenWatch *watch_list_add(XenWatchList *watch_list, const char *node,
205 const char *key, XenWatchHandler handler,
206 void *opaque, Error **errp)
208 XenWatch *watch = new_watch(node, key, handler, opaque);
209 Error *local_err = NULL;
211 notifier_list_add(&watch_list->notifiers, &watch->notifier);
213 xs_node_watch(watch_list->xsh, node, key, watch->token, &local_err);
215 error_propagate(errp, local_err);
217 notifier_remove(&watch->notifier);
226 static void watch_list_remove(XenWatchList *watch_list, XenWatch *watch,
229 xs_node_unwatch(watch_list->xsh, watch->node, watch->key, watch->token,
232 notifier_remove(&watch->notifier);
236 static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node,
237 const char *key, XenWatchHandler handler,
240 trace_xen_bus_add_watch(node, key);
242 return watch_list_add(xenbus->watch_list, node, key, handler, xenbus,
246 static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch,
249 trace_xen_bus_remove_watch(watch->node, watch->key);
251 watch_list_remove(xenbus->watch_list, watch, errp);
254 static void xen_bus_backend_create(XenBus *xenbus, const char *type,
255 const char *name, char *path,
258 xs_transaction_t tid;
262 Error *local_err = NULL;
264 trace_xen_bus_backend_create(type, path);
267 tid = xs_transaction_start(xenbus->xsh);
268 if (tid == XBT_NULL) {
269 error_setg(errp, "failed xs_transaction_start");
273 key = xs_directory(xenbus->xsh, tid, path, &n);
275 if (!xs_transaction_end(xenbus->xsh, tid, true)) {
276 error_setg_errno(errp, errno, "failed xs_transaction_end");
282 for (i = 0; i < n; i++) {
286 * Assume anything found in the xenstore backend area, other than
287 * the keys created for a generic XenDevice, are parameters
288 * to be used to configure the backend.
290 if (!strcmp(key[i], "state") ||
291 !strcmp(key[i], "online") ||
292 !strcmp(key[i], "frontend") ||
293 !strcmp(key[i], "frontend-id") ||
294 !strcmp(key[i], "hotplug-status"))
297 if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
299 qdict_put_str(opts, key[i], val);
306 if (!xs_transaction_end(xenbus->xsh, tid, false)) {
309 if (errno == EAGAIN) {
313 error_setg_errno(errp, errno, "failed xs_transaction_end");
317 xen_backend_device_create(xenbus, type, name, opts, &local_err);
321 error_propagate_prepend(errp, local_err,
322 "failed to create '%s' device '%s': ",
327 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
329 char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
333 trace_xen_bus_type_enumerate(type);
335 backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
340 for (i = 0; i < n; i++) {
341 char *backend_path = g_strdup_printf("%s/%s", domain_path,
343 enum xenbus_state state;
346 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
347 NULL, "%u", &state) != 1)
348 state = XenbusStateUnknown;
350 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
351 NULL, "%u", &online) != 1)
354 if (online && state == XenbusStateInitialising) {
355 Error *local_err = NULL;
357 xen_bus_backend_create(xenbus, type, backend[i], backend_path,
360 error_report_err(local_err);
364 g_free(backend_path);
373 static void xen_bus_enumerate(XenBus *xenbus)
378 trace_xen_bus_enumerate();
380 type = xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
385 for (i = 0; i < n; i++) {
386 xen_bus_type_enumerate(xenbus, type[i]);
392 static void xen_bus_device_cleanup(XenDevice *xendev)
394 const char *type = object_get_typename(OBJECT(xendev));
395 Error *local_err = NULL;
397 trace_xen_bus_device_cleanup(type, xendev->name);
399 g_assert(!xendev->backend_online);
401 if (!xen_backend_try_device_destroy(xendev, &local_err)) {
402 object_unparent(OBJECT(xendev));
406 error_report_err(local_err);
410 static void xen_bus_cleanup(XenBus *xenbus)
412 XenDevice *xendev, *next;
414 trace_xen_bus_cleanup();
416 QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) {
417 g_assert(xendev->inactive);
418 QLIST_REMOVE(xendev, list);
419 xen_bus_device_cleanup(xendev);
423 static void xen_bus_backend_changed(void *opaque)
425 XenBus *xenbus = opaque;
427 xen_bus_enumerate(xenbus);
428 xen_bus_cleanup(xenbus);
431 static void xen_bus_unrealize(BusState *bus)
433 XenBus *xenbus = XEN_BUS(bus);
435 trace_xen_bus_unrealize();
437 if (xenbus->backend_watch) {
438 xen_bus_remove_watch(xenbus, xenbus->backend_watch, NULL);
439 xenbus->backend_watch = NULL;
442 if (xenbus->watch_list) {
443 watch_list_destroy(xenbus->watch_list);
444 xenbus->watch_list = NULL;
448 xs_close(xenbus->xsh);
452 static void xen_bus_realize(BusState *bus, Error **errp)
454 XenBus *xenbus = XEN_BUS(bus);
456 Error *local_err = NULL;
458 trace_xen_bus_realize();
460 xenbus->xsh = xs_open(0);
462 error_setg_errno(errp, errno, "failed xs_open");
466 if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */
467 "domid", NULL, "%u", &domid) == 1) {
468 xenbus->backend_id = domid;
470 xenbus->backend_id = 0; /* Assume lack of node means dom0 */
473 xenbus->watch_list = watch_list_create(xenbus->xsh);
475 module_call_init(MODULE_INIT_XEN_BACKEND);
477 xenbus->backend_watch =
478 xen_bus_add_watch(xenbus, "", /* domain root node */
479 "backend", xen_bus_backend_changed, &local_err);
481 /* This need not be treated as a hard error so don't propagate */
482 error_reportf_err(local_err,
483 "failed to set up enumeration watch: ");
489 xen_bus_unrealize(bus);
492 static void xen_bus_unplug_request(HotplugHandler *hotplug,
496 XenDevice *xendev = XEN_DEVICE(dev);
498 xen_device_unplug(xendev, errp);
501 static void xen_bus_class_init(ObjectClass *class, void *data)
503 BusClass *bus_class = BUS_CLASS(class);
504 HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
506 bus_class->print_dev = xen_bus_print_dev;
507 bus_class->get_dev_path = xen_bus_get_dev_path;
508 bus_class->realize = xen_bus_realize;
509 bus_class->unrealize = xen_bus_unrealize;
511 hotplug_class->unplug_request = xen_bus_unplug_request;
514 static const TypeInfo xen_bus_type_info = {
515 .name = TYPE_XEN_BUS,
517 .instance_size = sizeof(XenBus),
518 .class_size = sizeof(XenBusClass),
519 .class_init = xen_bus_class_init,
520 .interfaces = (InterfaceInfo[]) {
521 { TYPE_HOTPLUG_HANDLER },
526 void xen_device_backend_printf(XenDevice *xendev, const char *key,
527 const char *fmt, ...)
529 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
530 Error *local_err = NULL;
533 g_assert(xenbus->xsh);
536 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
537 &local_err, fmt, ap);
541 error_report_err(local_err);
545 static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
546 const char *fmt, ...)
548 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
552 g_assert(xenbus->xsh);
555 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
562 void xen_device_backend_set_state(XenDevice *xendev,
563 enum xenbus_state state)
565 const char *type = object_get_typename(OBJECT(xendev));
567 if (xendev->backend_state == state) {
571 trace_xen_device_backend_state(type, xendev->name,
574 xendev->backend_state = state;
575 xen_device_backend_printf(xendev, "state", "%u", state);
578 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
580 return xendev->backend_state;
583 static void xen_device_backend_set_online(XenDevice *xendev, bool online)
585 const char *type = object_get_typename(OBJECT(xendev));
587 if (xendev->backend_online == online) {
591 trace_xen_device_backend_online(type, xendev->name, online);
593 xendev->backend_online = online;
594 xen_device_backend_printf(xendev, "online", "%u", online);
598 * Tell from the state whether the frontend is likely alive,
599 * i.e. it will react to a change of state of the backend.
601 static bool xen_device_frontend_is_active(XenDevice *xendev)
603 switch (xendev->frontend_state) {
604 case XenbusStateInitWait:
605 case XenbusStateInitialised:
606 case XenbusStateConnected:
607 case XenbusStateClosing:
614 static void xen_device_backend_changed(void *opaque)
616 XenDevice *xendev = opaque;
617 const char *type = object_get_typename(OBJECT(xendev));
618 enum xenbus_state state;
621 trace_xen_device_backend_changed(type, xendev->name);
623 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
624 state = XenbusStateUnknown;
627 xen_device_backend_set_state(xendev, state);
629 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
633 xen_device_backend_set_online(xendev, !!online);
636 * If the toolstack (or unplug request callback) has set the backend
637 * state to Closing, but there is no active frontend then set the
638 * backend state to Closed.
640 if (state == XenbusStateClosing &&
641 !xen_device_frontend_is_active(xendev)) {
642 xen_device_backend_set_state(xendev, XenbusStateClosed);
646 * If a backend is still 'online' then we should leave it alone but,
647 * if a backend is not 'online', then the device is a candidate
648 * for destruction. Hence add it to the 'inactive' list to be cleaned
649 * by xen_bus_cleanup().
652 (state == XenbusStateClosed || state == XenbusStateInitialising ||
653 state == XenbusStateInitWait || state == XenbusStateUnknown) &&
655 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
657 xendev->inactive = true;
658 QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);
661 * Re-write the state to cause a XenBus backend_watch notification,
662 * resulting in a call to xen_bus_cleanup().
664 xen_device_backend_printf(xendev, "state", "%u", state);
668 static XenWatch *xen_device_add_watch(XenDevice *xendev, const char *node,
670 XenWatchHandler handler,
673 const char *type = object_get_typename(OBJECT(xendev));
675 trace_xen_device_add_watch(type, xendev->name, node, key);
677 return watch_list_add(xendev->watch_list, node, key, handler, xendev,
681 static void xen_device_remove_watch(XenDevice *xendev, XenWatch *watch,
684 const char *type = object_get_typename(OBJECT(xendev));
686 trace_xen_device_remove_watch(type, xendev->name, watch->node,
689 watch_list_remove(xendev->watch_list, watch, errp);
693 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
695 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
696 struct xs_permissions perms[2];
697 Error *local_err = NULL;
699 xendev->backend_path = xen_device_get_backend_path(xendev);
701 perms[0].id = xenbus->backend_id;
702 perms[0].perms = XS_PERM_NONE;
703 perms[1].id = xendev->frontend_id;
704 perms[1].perms = XS_PERM_READ;
706 g_assert(xenbus->xsh);
708 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, perms,
709 ARRAY_SIZE(perms), &local_err);
711 error_propagate_prepend(errp, local_err,
712 "failed to create backend: ");
716 xendev->backend_state_watch =
717 xen_device_add_watch(xendev, xendev->backend_path,
718 "state", xen_device_backend_changed,
721 error_propagate_prepend(errp, local_err,
722 "failed to watch backend state: ");
726 xendev->backend_online_watch =
727 xen_device_add_watch(xendev, xendev->backend_path,
728 "online", xen_device_backend_changed,
731 error_propagate_prepend(errp, local_err,
732 "failed to watch backend online: ");
737 static void xen_device_backend_destroy(XenDevice *xendev)
739 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
740 Error *local_err = NULL;
742 if (xendev->backend_online_watch) {
743 xen_device_remove_watch(xendev, xendev->backend_online_watch, NULL);
744 xendev->backend_online_watch = NULL;
747 if (xendev->backend_state_watch) {
748 xen_device_remove_watch(xendev, xendev->backend_state_watch, NULL);
749 xendev->backend_state_watch = NULL;
752 if (!xendev->backend_path) {
756 g_assert(xenbus->xsh);
758 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path,
760 g_free(xendev->backend_path);
761 xendev->backend_path = NULL;
764 error_report_err(local_err);
768 void xen_device_frontend_printf(XenDevice *xendev, const char *key,
769 const char *fmt, ...)
771 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
772 Error *local_err = NULL;
775 g_assert(xenbus->xsh);
778 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
779 &local_err, fmt, ap);
783 error_report_err(local_err);
787 int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
788 const char *fmt, ...)
790 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
794 g_assert(xenbus->xsh);
797 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
804 static void xen_device_frontend_set_state(XenDevice *xendev,
805 enum xenbus_state state,
808 const char *type = object_get_typename(OBJECT(xendev));
810 if (xendev->frontend_state == state) {
814 trace_xen_device_frontend_state(type, xendev->name,
817 xendev->frontend_state = state;
819 xen_device_frontend_printf(xendev, "state", "%u", state);
823 static void xen_device_frontend_changed(void *opaque)
825 XenDevice *xendev = opaque;
826 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
827 const char *type = object_get_typename(OBJECT(xendev));
828 enum xenbus_state state;
830 trace_xen_device_frontend_changed(type, xendev->name);
832 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
833 state = XenbusStateUnknown;
836 xen_device_frontend_set_state(xendev, state, false);
838 if (state == XenbusStateInitialising &&
839 xendev->backend_state == XenbusStateClosed &&
840 xendev->backend_online) {
842 * The frontend is re-initializing so switch back to
845 xen_device_backend_set_state(xendev, XenbusStateInitWait);
849 if (xendev_class->frontend_changed) {
850 Error *local_err = NULL;
852 xendev_class->frontend_changed(xendev, state, &local_err);
855 error_reportf_err(local_err, "frontend change error: ");
860 static bool xen_device_frontend_exists(XenDevice *xendev)
862 enum xenbus_state state;
864 return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
867 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
869 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
870 struct xs_permissions perms[2];
871 Error *local_err = NULL;
873 xendev->frontend_path = xen_device_get_frontend_path(xendev);
876 * The frontend area may have already been created by a legacy
879 if (!xen_device_frontend_exists(xendev)) {
880 perms[0].id = xendev->frontend_id;
881 perms[0].perms = XS_PERM_NONE;
882 perms[1].id = xenbus->backend_id;
883 perms[1].perms = XS_PERM_READ | XS_PERM_WRITE;
885 g_assert(xenbus->xsh);
887 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms,
888 ARRAY_SIZE(perms), &local_err);
890 error_propagate_prepend(errp, local_err,
891 "failed to create frontend: ");
896 xendev->frontend_state_watch =
897 xen_device_add_watch(xendev, xendev->frontend_path, "state",
898 xen_device_frontend_changed, &local_err);
900 error_propagate_prepend(errp, local_err,
901 "failed to watch frontend state: ");
905 static void xen_device_frontend_destroy(XenDevice *xendev)
907 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
908 Error *local_err = NULL;
910 if (xendev->frontend_state_watch) {
911 xen_device_remove_watch(xendev, xendev->frontend_state_watch,
913 xendev->frontend_state_watch = NULL;
916 if (!xendev->frontend_path) {
920 g_assert(xenbus->xsh);
922 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
924 g_free(xendev->frontend_path);
925 xendev->frontend_path = NULL;
928 error_report_err(local_err);
932 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
935 if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) {
936 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
940 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
941 unsigned int nr_refs, int prot,
944 void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs,
945 xendev->frontend_id, refs,
949 error_setg_errno(errp, errno,
950 "xengnttab_map_domain_grant_refs failed");
956 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
957 unsigned int nr_refs, Error **errp)
959 if (xengnttab_unmap(xendev->xgth, map, nr_refs)) {
960 error_setg_errno(errp, errno, "xengnttab_unmap failed");
964 static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain,
965 XenDeviceGrantCopySegment segs[],
966 unsigned int nr_segs, Error **errp)
968 uint32_t *refs = g_new(uint32_t, nr_segs);
969 int prot = to_domain ? PROT_WRITE : PROT_READ;
973 for (i = 0; i < nr_segs; i++) {
974 XenDeviceGrantCopySegment *seg = &segs[i];
976 refs[i] = to_domain ? seg->dest.foreign.ref :
977 seg->source.foreign.ref;
980 map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs,
981 xendev->frontend_id, refs,
984 error_setg_errno(errp, errno,
985 "xengnttab_map_domain_grant_refs failed");
989 for (i = 0; i < nr_segs; i++) {
990 XenDeviceGrantCopySegment *seg = &segs[i];
991 void *page = map + (i * XC_PAGE_SIZE);
994 memcpy(page + seg->dest.foreign.offset, seg->source.virt,
997 memcpy(seg->dest.virt, page + seg->source.foreign.offset,
1002 if (xengnttab_unmap(xendev->xgth, map, nr_segs)) {
1003 error_setg_errno(errp, errno, "xengnttab_unmap failed");
1010 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
1011 XenDeviceGrantCopySegment segs[],
1012 unsigned int nr_segs, Error **errp)
1014 xengnttab_grant_copy_segment_t *xengnttab_segs;
1017 if (!xendev->feature_grant_copy) {
1018 compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp);
1022 xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs);
1024 for (i = 0; i < nr_segs; i++) {
1025 XenDeviceGrantCopySegment *seg = &segs[i];
1026 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
1029 xengnttab_seg->flags = GNTCOPY_dest_gref;
1030 xengnttab_seg->dest.foreign.domid = xendev->frontend_id;
1031 xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref;
1032 xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset;
1033 xengnttab_seg->source.virt = seg->source.virt;
1035 xengnttab_seg->flags = GNTCOPY_source_gref;
1036 xengnttab_seg->source.foreign.domid = xendev->frontend_id;
1037 xengnttab_seg->source.foreign.ref = seg->source.foreign.ref;
1038 xengnttab_seg->source.foreign.offset =
1039 seg->source.foreign.offset;
1040 xengnttab_seg->dest.virt = seg->dest.virt;
1043 xengnttab_seg->len = seg->len;
1046 if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) {
1047 error_setg_errno(errp, errno, "xengnttab_grant_copy failed");
1051 for (i = 0; i < nr_segs; i++) {
1052 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i];
1054 if (xengnttab_seg->status != GNTST_okay) {
1055 error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i);
1061 g_free(xengnttab_segs);
1064 struct XenEventChannel {
1065 QLIST_ENTRY(XenEventChannel) list;
1067 xenevtchn_handle *xeh;
1068 evtchn_port_t local_port;
1069 XenEventHandler handler;
1073 static bool xen_device_poll(void *opaque)
1075 XenEventChannel *channel = opaque;
1077 return channel->handler(channel->opaque);
1080 static void xen_device_event(void *opaque)
1082 XenEventChannel *channel = opaque;
1083 unsigned long port = xenevtchn_pending(channel->xeh);
1085 if (port == channel->local_port) {
1086 xen_device_poll(channel);
1088 xenevtchn_unmask(channel->xeh, port);
1092 void xen_device_set_event_channel_context(XenDevice *xendev,
1093 XenEventChannel *channel,
1098 error_setg(errp, "bad channel");
1103 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true,
1104 NULL, NULL, NULL, NULL);
1107 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true,
1108 xen_device_event, NULL, xen_device_poll, channel);
1111 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
1113 XenEventHandler handler,
1114 void *opaque, Error **errp)
1116 XenEventChannel *channel = g_new0(XenEventChannel, 1);
1117 xenevtchn_port_or_error_t local_port;
1119 channel->xeh = xenevtchn_open(NULL, 0);
1120 if (!channel->xeh) {
1121 error_setg_errno(errp, errno, "failed xenevtchn_open");
1125 local_port = xenevtchn_bind_interdomain(channel->xeh,
1126 xendev->frontend_id,
1128 if (local_port < 0) {
1129 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
1133 channel->local_port = local_port;
1134 channel->handler = handler;
1135 channel->opaque = opaque;
1137 /* Only reason for failure is a NULL channel */
1138 xen_device_set_event_channel_context(xendev, channel,
1139 qemu_get_aio_context(),
1142 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
1148 xenevtchn_close(channel->xeh);
1156 void xen_device_notify_event_channel(XenDevice *xendev,
1157 XenEventChannel *channel,
1161 error_setg(errp, "bad channel");
1165 if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) {
1166 error_setg_errno(errp, errno, "xenevtchn_notify failed");
1170 void xen_device_unbind_event_channel(XenDevice *xendev,
1171 XenEventChannel *channel,
1175 error_setg(errp, "bad channel");
1179 QLIST_REMOVE(channel, list);
1181 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true,
1182 NULL, NULL, NULL, NULL);
1184 if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) {
1185 error_setg_errno(errp, errno, "xenevtchn_unbind failed");
1188 xenevtchn_close(channel->xeh);
1192 static void xen_device_unrealize(DeviceState *dev)
1194 XenDevice *xendev = XEN_DEVICE(dev);
1195 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
1196 const char *type = object_get_typename(OBJECT(xendev));
1197 XenEventChannel *channel, *next;
1199 if (!xendev->name) {
1203 trace_xen_device_unrealize(type, xendev->name);
1205 if (xendev->exit.notify) {
1206 qemu_remove_exit_notifier(&xendev->exit);
1207 xendev->exit.notify = NULL;
1210 if (xendev_class->unrealize) {
1211 xendev_class->unrealize(xendev);
1214 /* Make sure all event channels are cleaned up */
1215 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
1216 xen_device_unbind_event_channel(xendev, channel, NULL);
1219 xen_device_frontend_destroy(xendev);
1220 xen_device_backend_destroy(xendev);
1223 xengnttab_close(xendev->xgth);
1224 xendev->xgth = NULL;
1227 if (xendev->watch_list) {
1228 watch_list_destroy(xendev->watch_list);
1229 xendev->watch_list = NULL;
1233 xs_close(xendev->xsh);
1237 g_free(xendev->name);
1238 xendev->name = NULL;
1241 static void xen_device_exit(Notifier *n, void *data)
1243 XenDevice *xendev = container_of(n, XenDevice, exit);
1245 xen_device_unrealize(DEVICE(xendev));
1248 static void xen_device_realize(DeviceState *dev, Error **errp)
1250 XenDevice *xendev = XEN_DEVICE(dev);
1251 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
1252 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
1253 const char *type = object_get_typename(OBJECT(xendev));
1254 Error *local_err = NULL;
1256 if (xendev->frontend_id == DOMID_INVALID) {
1257 xendev->frontend_id = xen_domid;
1260 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1261 error_setg(errp, "invalid frontend-id");
1265 if (!xendev_class->get_name) {
1266 error_setg(errp, "get_name method not implemented");
1270 xendev->name = xendev_class->get_name(xendev, &local_err);
1272 error_propagate_prepend(errp, local_err,
1273 "failed to get device name: ");
1277 trace_xen_device_realize(type, xendev->name);
1279 xendev->xsh = xs_open(0);
1281 error_setg_errno(errp, errno, "failed xs_open");
1285 xendev->watch_list = watch_list_create(xendev->xsh);
1287 xendev->xgth = xengnttab_open(NULL, 0);
1288 if (!xendev->xgth) {
1289 error_setg_errno(errp, errno, "failed xengnttab_open");
1293 xendev->feature_grant_copy =
1294 (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0);
1296 xen_device_backend_create(xendev, &local_err);
1298 error_propagate(errp, local_err);
1302 xen_device_frontend_create(xendev, &local_err);
1304 error_propagate(errp, local_err);
1308 if (xendev_class->realize) {
1309 xendev_class->realize(xendev, &local_err);
1311 error_propagate(errp, local_err);
1316 xen_device_backend_printf(xendev, "frontend", "%s",
1317 xendev->frontend_path);
1318 xen_device_backend_printf(xendev, "frontend-id", "%u",
1319 xendev->frontend_id);
1320 xen_device_backend_printf(xendev, "hotplug-status", "connected");
1322 xen_device_backend_set_online(xendev, true);
1323 xen_device_backend_set_state(xendev, XenbusStateInitWait);
1325 if (!xen_device_frontend_exists(xendev)) {
1326 xen_device_frontend_printf(xendev, "backend", "%s",
1327 xendev->backend_path);
1328 xen_device_frontend_printf(xendev, "backend-id", "%u",
1329 xenbus->backend_id);
1331 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1334 xendev->exit.notify = xen_device_exit;
1335 qemu_add_exit_notifier(&xendev->exit);
1339 xen_device_unrealize(dev);
1342 static Property xen_device_props[] = {
1343 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1345 DEFINE_PROP_END_OF_LIST()
1348 static void xen_device_class_init(ObjectClass *class, void *data)
1350 DeviceClass *dev_class = DEVICE_CLASS(class);
1352 dev_class->realize = xen_device_realize;
1353 dev_class->unrealize = xen_device_unrealize;
1354 device_class_set_props(dev_class, xen_device_props);
1355 dev_class->bus_type = TYPE_XEN_BUS;
1358 static const TypeInfo xen_device_type_info = {
1359 .name = TYPE_XEN_DEVICE,
1360 .parent = TYPE_DEVICE,
1361 .instance_size = sizeof(XenDevice),
1363 .class_size = sizeof(XenDeviceClass),
1364 .class_init = xen_device_class_init,
1367 typedef struct XenBridge {
1368 SysBusDevice busdev;
1371 #define TYPE_XEN_BRIDGE "xen-bridge"
1373 static const TypeInfo xen_bridge_type_info = {
1374 .name = TYPE_XEN_BRIDGE,
1375 .parent = TYPE_SYS_BUS_DEVICE,
1376 .instance_size = sizeof(XenBridge),
1379 static void xen_register_types(void)
1381 type_register_static(&xen_bridge_type_info);
1382 type_register_static(&xen_bus_type_info);
1383 type_register_static(&xen_device_type_info);
1386 type_init(xen_register_types)
1388 void xen_bus_init(void)
1390 DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1391 BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL);
1393 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1394 qbus_set_bus_hotplug_handler(bus, &error_abort);