Merge tag 'v9.0.0-rc3'
[qemu/ar7.git] / hw / xen / xen-bus.c
blobfb82cc33e48bcd06dc9c46b942bd7d6ac0317613
1 /*
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.
6 */
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"
22 #include "net/net.h"
23 #include "trace.h"
25 static char *xen_device_get_backend_path(XenDevice *xendev)
27 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
28 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
29 const char *type = object_get_typename(OBJECT(xendev));
30 const char *backend = xendev_class->backend;
32 if (!backend) {
33 backend = type;
36 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
37 xenbus->backend_id, backend, xendev->frontend_id,
38 xendev->name);
41 static char *xen_device_get_frontend_path(XenDevice *xendev)
43 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
44 const char *type = object_get_typename(OBJECT(xendev));
45 const char *device = xendev_class->device;
47 if (!device) {
48 device = type;
51 return g_strdup_printf("/local/domain/%u/device/%s/%s",
52 xendev->frontend_id, device, xendev->name);
55 static void xen_device_unplug(XenDevice *xendev, Error **errp)
57 ERRP_GUARD();
58 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
59 const char *type = object_get_typename(OBJECT(xendev));
60 xs_transaction_t tid;
62 trace_xen_device_unplug(type, xendev->name);
64 /* Mimic the way the Xen toolstack does an unplug */
65 again:
66 tid = qemu_xen_xs_transaction_start(xenbus->xsh);
67 if (tid == XBT_NULL) {
68 error_setg_errno(errp, errno, "failed xs_transaction_start");
69 return;
72 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
73 errp, "%u", 0);
74 if (*errp) {
75 goto abort;
78 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
79 errp, "%u", XenbusStateClosing);
80 if (*errp) {
81 goto abort;
84 if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
85 if (errno == EAGAIN) {
86 goto again;
89 error_setg_errno(errp, errno, "failed xs_transaction_end");
92 return;
94 abort:
96 * We only abort if there is already a failure so ignore any error
97 * from ending the transaction.
99 qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
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));
115 static void xen_bus_backend_create(XenBus *xenbus, const char *type,
116 const char *name, char *path,
117 Error **errp)
119 ERRP_GUARD();
120 xs_transaction_t tid;
121 char **key;
122 QDict *opts;
123 unsigned int i, n;
125 trace_xen_bus_backend_create(type, path);
127 again:
128 tid = qemu_xen_xs_transaction_start(xenbus->xsh);
129 if (tid == XBT_NULL) {
130 error_setg(errp, "failed xs_transaction_start");
131 return;
134 key = qemu_xen_xs_directory(xenbus->xsh, tid, path, &n);
135 if (!key) {
136 if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, true)) {
137 error_setg_errno(errp, errno, "failed xs_transaction_end");
139 return;
142 opts = qdict_new();
143 for (i = 0; i < n; i++) {
144 char *val;
147 * Assume anything found in the xenstore backend area, other than
148 * the keys created for a generic XenDevice, are parameters
149 * to be used to configure the backend.
151 if (!strcmp(key[i], "state") ||
152 !strcmp(key[i], "online") ||
153 !strcmp(key[i], "frontend") ||
154 !strcmp(key[i], "frontend-id") ||
155 !strcmp(key[i], "hotplug-status"))
156 continue;
158 if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
159 &val) == 1) {
160 qdict_put_str(opts, key[i], val);
161 free(val);
165 free(key);
167 if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
168 qobject_unref(opts);
170 if (errno == EAGAIN) {
171 goto again;
174 error_setg_errno(errp, errno, "failed xs_transaction_end");
175 return;
178 xen_backend_device_create(xenbus, type, name, opts, errp);
179 qobject_unref(opts);
181 if (*errp) {
182 error_prepend(errp, "failed to create '%s' device '%s': ", type, name);
186 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
188 char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
189 char **backend;
190 unsigned int i, n;
192 trace_xen_bus_type_enumerate(type);
194 backend = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
195 if (!backend) {
196 goto out;
199 for (i = 0; i < n; i++) {
200 char *backend_path = g_strdup_printf("%s/%s", domain_path,
201 backend[i]);
202 enum xenbus_state state;
203 unsigned int online;
205 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
206 NULL, "%u", &state) != 1)
207 state = XenbusStateUnknown;
209 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
210 NULL, "%u", &online) != 1)
211 online = 0;
213 if (online && state == XenbusStateInitialising &&
214 !xen_backend_exists(type, backend[i])) {
215 Error *local_err = NULL;
217 xen_bus_backend_create(xenbus, type, backend[i], backend_path,
218 &local_err);
219 if (local_err) {
220 error_report_err(local_err);
224 g_free(backend_path);
227 free(backend);
229 out:
230 g_free(domain_path);
233 static void xen_bus_enumerate(XenBus *xenbus)
235 char **type;
236 unsigned int i, n;
238 trace_xen_bus_enumerate();
240 type = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
241 if (!type) {
242 return;
245 for (i = 0; i < n; i++) {
246 xen_bus_type_enumerate(xenbus, type[i]);
249 free(type);
252 static void xen_bus_device_cleanup(XenDevice *xendev)
254 const char *type = object_get_typename(OBJECT(xendev));
255 Error *local_err = NULL;
257 trace_xen_bus_device_cleanup(type, xendev->name);
259 g_assert(!xendev->backend_online);
261 if (!xen_backend_try_device_destroy(xendev, &local_err)) {
262 object_unparent(OBJECT(xendev));
265 if (local_err) {
266 error_report_err(local_err);
270 static void xen_bus_cleanup(XenBus *xenbus)
272 XenDevice *xendev, *next;
274 trace_xen_bus_cleanup();
276 QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) {
277 g_assert(xendev->inactive);
278 QLIST_REMOVE(xendev, list);
279 xen_bus_device_cleanup(xendev);
283 static void xen_bus_backend_changed(void *opaque, const char *path)
285 XenBus *xenbus = opaque;
287 xen_bus_enumerate(xenbus);
288 xen_bus_cleanup(xenbus);
291 static void xen_bus_unrealize(BusState *bus)
293 XenBus *xenbus = XEN_BUS(bus);
295 trace_xen_bus_unrealize();
297 if (xenbus->backend_watch) {
298 unsigned int i;
300 for (i = 0; i < xenbus->backend_types; i++) {
301 if (xenbus->backend_watch[i]) {
302 xs_node_unwatch(xenbus->xsh, xenbus->backend_watch[i]);
306 g_free(xenbus->backend_watch);
307 xenbus->backend_watch = NULL;
310 if (xenbus->xsh) {
311 qemu_xen_xs_close(xenbus->xsh);
315 static void xen_bus_realize(BusState *bus, Error **errp)
317 char *key = g_strdup_printf("%u", xen_domid);
318 XenBus *xenbus = XEN_BUS(bus);
319 unsigned int domid;
320 const char **type;
321 unsigned int i;
322 Error *local_err = NULL;
324 trace_xen_bus_realize();
326 xenbus->xsh = qemu_xen_xs_open();
327 if (!xenbus->xsh) {
328 error_setg_errno(errp, errno, "failed xs_open");
329 goto fail;
332 if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */
333 "domid", NULL, "%u", &domid) == 1) {
334 xenbus->backend_id = domid;
335 } else {
336 xenbus->backend_id = 0; /* Assume lack of node means dom0 */
339 module_call_init(MODULE_INIT_XEN_BACKEND);
341 type = xen_backend_get_types(&xenbus->backend_types);
342 xenbus->backend_watch = g_new(struct qemu_xs_watch *,
343 xenbus->backend_types);
345 for (i = 0; i < xenbus->backend_types; i++) {
346 char *node = g_strdup_printf("backend/%s", type[i]);
348 xenbus->backend_watch[i] =
349 xs_node_watch(xenbus->xsh, node, key, xen_bus_backend_changed,
350 xenbus, &local_err);
351 if (local_err) {
352 /* This need not be treated as a hard error so don't propagate */
353 error_reportf_err(local_err,
354 "failed to set up '%s' enumeration watch: ",
355 type[i]);
358 g_free(node);
361 g_free(type);
362 g_free(key);
363 return;
365 fail:
366 xen_bus_unrealize(bus);
367 g_free(key);
370 static void xen_bus_unplug_request(HotplugHandler *hotplug,
371 DeviceState *dev,
372 Error **errp)
374 XenDevice *xendev = XEN_DEVICE(dev);
376 xen_device_unplug(xendev, errp);
379 static void xen_bus_class_init(ObjectClass *class, void *data)
381 BusClass *bus_class = BUS_CLASS(class);
382 HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
384 bus_class->print_dev = xen_bus_print_dev;
385 bus_class->get_dev_path = xen_bus_get_dev_path;
386 bus_class->realize = xen_bus_realize;
387 bus_class->unrealize = xen_bus_unrealize;
389 hotplug_class->unplug_request = xen_bus_unplug_request;
392 static const TypeInfo xen_bus_type_info = {
393 .name = TYPE_XEN_BUS,
394 .parent = TYPE_BUS,
395 .instance_size = sizeof(XenBus),
396 .class_size = sizeof(XenBusClass),
397 .class_init = xen_bus_class_init,
398 .interfaces = (InterfaceInfo[]) {
399 { TYPE_HOTPLUG_HANDLER },
404 void xen_device_backend_printf(XenDevice *xendev, const char *key,
405 const char *fmt, ...)
407 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
408 Error *local_err = NULL;
409 va_list ap;
411 g_assert(xenbus->xsh);
413 va_start(ap, fmt);
414 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
415 &local_err, fmt, ap);
416 va_end(ap);
418 if (local_err) {
419 error_report_err(local_err);
423 G_GNUC_SCANF(3, 4)
424 static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
425 const char *fmt, ...)
427 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
428 va_list ap;
429 int rc;
431 g_assert(xenbus->xsh);
433 va_start(ap, fmt);
434 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
435 NULL, fmt, ap);
436 va_end(ap);
438 return rc;
441 void xen_device_backend_set_state(XenDevice *xendev,
442 enum xenbus_state state)
444 const char *type = object_get_typename(OBJECT(xendev));
446 if (xendev->backend_state == state) {
447 return;
450 trace_xen_device_backend_state(type, xendev->name,
451 xs_strstate(state));
453 xendev->backend_state = state;
454 xen_device_backend_printf(xendev, "state", "%u", state);
457 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
459 return xendev->backend_state;
462 static void xen_device_backend_set_online(XenDevice *xendev, bool online)
464 const char *type = object_get_typename(OBJECT(xendev));
466 if (xendev->backend_online == online) {
467 return;
470 trace_xen_device_backend_online(type, xendev->name, online);
472 xendev->backend_online = online;
473 xen_device_backend_printf(xendev, "online", "%u", online);
477 * Tell from the state whether the frontend is likely alive,
478 * i.e. it will react to a change of state of the backend.
480 static bool xen_device_frontend_is_active(XenDevice *xendev)
482 switch (xendev->frontend_state) {
483 case XenbusStateInitWait:
484 case XenbusStateInitialised:
485 case XenbusStateConnected:
486 case XenbusStateClosing:
487 return true;
488 default:
489 return false;
493 static void xen_device_backend_changed(void *opaque, const char *path)
495 XenDevice *xendev = opaque;
496 const char *type = object_get_typename(OBJECT(xendev));
497 enum xenbus_state state;
498 unsigned int online;
500 trace_xen_device_backend_changed(type, xendev->name);
502 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
503 state = XenbusStateUnknown;
506 xen_device_backend_set_state(xendev, state);
508 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
509 online = 0;
512 xen_device_backend_set_online(xendev, !!online);
515 * If the toolstack (or unplug request callback) has set the backend
516 * state to Closing, but there is no active frontend then set the
517 * backend state to Closed.
519 if (state == XenbusStateClosing &&
520 !xen_device_frontend_is_active(xendev)) {
521 xen_device_backend_set_state(xendev, XenbusStateClosed);
525 * If a backend is still 'online' then we should leave it alone but,
526 * if a backend is not 'online', then the device is a candidate
527 * for destruction. Hence add it to the 'inactive' list to be cleaned
528 * by xen_bus_cleanup().
530 if (!online &&
531 (state == XenbusStateClosed || state == XenbusStateInitialising ||
532 state == XenbusStateInitWait || state == XenbusStateUnknown) &&
533 !xendev->inactive) {
534 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
536 xendev->inactive = true;
537 QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);
540 * Re-write the state to cause a XenBus backend_watch notification,
541 * resulting in a call to xen_bus_cleanup().
543 xen_device_backend_printf(xendev, "state", "%u", state);
547 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
549 ERRP_GUARD();
550 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
552 xendev->backend_path = xen_device_get_backend_path(xendev);
554 g_assert(xenbus->xsh);
556 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path,
557 xenbus->backend_id, xendev->frontend_id, XS_PERM_READ, errp);
558 if (*errp) {
559 error_prepend(errp, "failed to create backend: ");
560 return;
563 xendev->backend_state_watch =
564 xs_node_watch(xendev->xsh, xendev->backend_path,
565 "state", xen_device_backend_changed, xendev,
566 errp);
567 if (*errp) {
568 error_prepend(errp, "failed to watch backend state: ");
569 return;
572 xendev->backend_online_watch =
573 xs_node_watch(xendev->xsh, xendev->backend_path,
574 "online", xen_device_backend_changed, xendev,
575 errp);
576 if (*errp) {
577 error_prepend(errp, "failed to watch backend online: ");
578 return;
582 static void xen_device_backend_destroy(XenDevice *xendev)
584 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
585 Error *local_err = NULL;
587 if (xendev->backend_online_watch) {
588 xs_node_unwatch(xendev->xsh, xendev->backend_online_watch);
589 xendev->backend_online_watch = NULL;
592 if (xendev->backend_state_watch) {
593 xs_node_unwatch(xendev->xsh, xendev->backend_state_watch);
594 xendev->backend_state_watch = NULL;
597 if (!xendev->backend_path) {
598 return;
601 g_assert(xenbus->xsh);
603 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path,
604 &local_err);
605 g_free(xendev->backend_path);
606 xendev->backend_path = NULL;
608 if (local_err) {
609 error_report_err(local_err);
613 void xen_device_frontend_printf(XenDevice *xendev, const char *key,
614 const char *fmt, ...)
616 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
617 Error *local_err = NULL;
618 va_list ap;
620 g_assert(xenbus->xsh);
622 va_start(ap, fmt);
623 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
624 &local_err, fmt, ap);
625 va_end(ap);
627 if (local_err) {
628 error_report_err(local_err);
632 int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
633 const char *fmt, ...)
635 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
636 va_list ap;
637 int rc;
639 g_assert(xenbus->xsh);
641 va_start(ap, fmt);
642 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
643 NULL, fmt, ap);
644 va_end(ap);
646 return rc;
649 static void xen_device_frontend_set_state(XenDevice *xendev,
650 enum xenbus_state state,
651 bool publish)
653 const char *type = object_get_typename(OBJECT(xendev));
655 if (xendev->frontend_state == state) {
656 return;
659 trace_xen_device_frontend_state(type, xendev->name,
660 xs_strstate(state));
662 xendev->frontend_state = state;
663 if (publish) {
664 xen_device_frontend_printf(xendev, "state", "%u", state);
668 static void xen_device_frontend_changed(void *opaque, const char *path)
670 XenDevice *xendev = opaque;
671 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
672 const char *type = object_get_typename(OBJECT(xendev));
673 enum xenbus_state state;
675 trace_xen_device_frontend_changed(type, xendev->name);
677 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
678 state = XenbusStateUnknown;
681 xen_device_frontend_set_state(xendev, state, false);
683 if (state == XenbusStateInitialising &&
684 xendev->backend_state == XenbusStateClosed &&
685 xendev->backend_online) {
687 * The frontend is re-initializing so switch back to
688 * InitWait.
690 xen_device_backend_set_state(xendev, XenbusStateInitWait);
691 return;
694 if (xendev_class->frontend_changed) {
695 Error *local_err = NULL;
697 xendev_class->frontend_changed(xendev, state, &local_err);
699 if (local_err) {
700 error_reportf_err(local_err, "frontend change error: ");
705 static bool xen_device_frontend_exists(XenDevice *xendev)
707 enum xenbus_state state;
709 return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
712 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
714 ERRP_GUARD();
715 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
716 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
718 if (xendev_class->get_frontend_path) {
719 xendev->frontend_path = xendev_class->get_frontend_path(xendev, errp);
720 if (!xendev->frontend_path) {
721 error_prepend(errp, "failed to create frontend: ");
722 return;
724 } else {
725 xendev->frontend_path = xen_device_get_frontend_path(xendev);
729 * The frontend area may have already been created by a legacy
730 * toolstack.
732 if (!xen_device_frontend_exists(xendev)) {
733 g_assert(xenbus->xsh);
735 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path,
736 xendev->frontend_id, xenbus->backend_id,
737 XS_PERM_READ | XS_PERM_WRITE, errp);
738 if (*errp) {
739 error_prepend(errp, "failed to create frontend: ");
740 return;
744 xendev->frontend_state_watch =
745 xs_node_watch(xendev->xsh, xendev->frontend_path, "state",
746 xen_device_frontend_changed, xendev, errp);
747 if (*errp) {
748 error_prepend(errp, "failed to watch frontend state: ");
752 static void xen_device_frontend_destroy(XenDevice *xendev)
754 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
755 Error *local_err = NULL;
757 if (xendev->frontend_state_watch) {
758 xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
759 xendev->frontend_state_watch = NULL;
762 if (!xendev->frontend_path) {
763 return;
766 g_assert(xenbus->xsh);
768 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
769 &local_err);
770 g_free(xendev->frontend_path);
771 xendev->frontend_path = NULL;
773 if (local_err) {
774 error_report_err(local_err);
778 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
779 Error **errp)
781 if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
782 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
786 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
787 unsigned int nr_refs, int prot,
788 Error **errp)
790 void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
791 xendev->frontend_id, refs, prot);
793 if (!map) {
794 error_setg_errno(errp, errno,
795 "xengnttab_map_domain_grant_refs failed");
798 return map;
801 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
802 unsigned int nr_refs, Error **errp)
804 if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
805 error_setg_errno(errp, errno, "xengnttab_unmap failed");
809 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
810 XenDeviceGrantCopySegment segs[],
811 unsigned int nr_segs, Error **errp)
813 qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
814 (XenGrantCopySegment *)segs, nr_segs, errp);
817 struct XenEventChannel {
818 QLIST_ENTRY(XenEventChannel) list;
819 AioContext *ctx;
820 xenevtchn_handle *xeh;
821 evtchn_port_t local_port;
822 XenEventHandler handler;
823 void *opaque;
826 static bool xen_device_poll(void *opaque)
828 XenEventChannel *channel = opaque;
830 return channel->handler(channel->opaque);
833 static void xen_device_event(void *opaque)
835 XenEventChannel *channel = opaque;
836 unsigned long port = qemu_xen_evtchn_pending(channel->xeh);
838 if (port == channel->local_port) {
839 xen_device_poll(channel);
841 qemu_xen_evtchn_unmask(channel->xeh, port);
845 void xen_device_set_event_channel_context(XenDevice *xendev,
846 XenEventChannel *channel,
847 AioContext *ctx,
848 Error **errp)
850 if (!channel) {
851 error_setg(errp, "bad channel");
852 return;
855 if (channel->ctx)
856 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
857 NULL, NULL, NULL, NULL, NULL);
859 channel->ctx = ctx;
860 if (ctx) {
861 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
862 xen_device_event, NULL, xen_device_poll, NULL,
863 channel);
867 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
868 unsigned int port,
869 XenEventHandler handler,
870 void *opaque, Error **errp)
872 XenEventChannel *channel = g_new0(XenEventChannel, 1);
873 xenevtchn_port_or_error_t local_port;
875 channel->xeh = qemu_xen_evtchn_open();
876 if (!channel->xeh) {
877 error_setg_errno(errp, errno, "failed xenevtchn_open");
878 goto fail;
881 local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh,
882 xendev->frontend_id,
883 port);
884 if (local_port < 0) {
885 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
886 goto fail;
889 channel->local_port = local_port;
890 channel->handler = handler;
891 channel->opaque = opaque;
893 /* Only reason for failure is a NULL channel */
894 xen_device_set_event_channel_context(xendev, channel,
895 qemu_get_aio_context(),
896 &error_abort);
898 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
900 return channel;
902 fail:
903 if (channel->xeh) {
904 qemu_xen_evtchn_close(channel->xeh);
907 g_free(channel);
909 return NULL;
912 void xen_device_notify_event_channel(XenDevice *xendev,
913 XenEventChannel *channel,
914 Error **errp)
916 if (!channel) {
917 error_setg(errp, "bad channel");
918 return;
921 if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
922 error_setg_errno(errp, errno, "xenevtchn_notify failed");
926 unsigned int xen_event_channel_get_local_port(XenEventChannel *channel)
928 return channel->local_port;
931 void xen_device_unbind_event_channel(XenDevice *xendev,
932 XenEventChannel *channel,
933 Error **errp)
935 if (!channel) {
936 error_setg(errp, "bad channel");
937 return;
940 QLIST_REMOVE(channel, list);
942 if (channel->ctx) {
943 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
944 NULL, NULL, NULL, NULL, NULL);
947 if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
948 error_setg_errno(errp, errno, "xenevtchn_unbind failed");
951 qemu_xen_evtchn_close(channel->xeh);
952 g_free(channel);
955 static void xen_device_unrealize(DeviceState *dev)
957 XenDevice *xendev = XEN_DEVICE(dev);
958 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
959 const char *type = object_get_typename(OBJECT(xendev));
960 XenEventChannel *channel, *next;
962 if (!xendev->name) {
963 return;
966 trace_xen_device_unrealize(type, xendev->name);
968 if (xendev->exit.notify) {
969 qemu_remove_exit_notifier(&xendev->exit);
970 xendev->exit.notify = NULL;
973 if (xendev_class->unrealize) {
974 xendev_class->unrealize(xendev);
977 /* Make sure all event channels are cleaned up */
978 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
979 xen_device_unbind_event_channel(xendev, channel, NULL);
982 xen_device_frontend_destroy(xendev);
983 xen_device_backend_destroy(xendev);
985 if (xendev->xgth) {
986 qemu_xen_gnttab_close(xendev->xgth);
987 xendev->xgth = NULL;
990 if (xendev->xsh) {
991 qemu_xen_xs_close(xendev->xsh);
992 xendev->xsh = NULL;
995 g_free(xendev->name);
996 xendev->name = NULL;
999 static void xen_device_exit(Notifier *n, void *data)
1001 XenDevice *xendev = container_of(n, XenDevice, exit);
1003 xen_device_unrealize(DEVICE(xendev));
1006 static void xen_device_realize(DeviceState *dev, Error **errp)
1008 ERRP_GUARD();
1009 XenDevice *xendev = XEN_DEVICE(dev);
1010 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
1011 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
1012 const char *type = object_get_typename(OBJECT(xendev));
1014 if (xendev->frontend_id == DOMID_INVALID) {
1015 xendev->frontend_id = xen_domid;
1018 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1019 error_setg(errp, "invalid frontend-id");
1020 goto unrealize;
1023 if (!xendev_class->get_name) {
1024 error_setg(errp, "get_name method not implemented");
1025 goto unrealize;
1028 xendev->name = xendev_class->get_name(xendev, errp);
1029 if (*errp) {
1030 error_prepend(errp, "failed to get device name: ");
1031 goto unrealize;
1034 trace_xen_device_realize(type, xendev->name);
1036 xendev->xsh = qemu_xen_xs_open();
1037 if (!xendev->xsh) {
1038 error_setg_errno(errp, errno, "failed xs_open");
1039 goto unrealize;
1042 xendev->xgth = qemu_xen_gnttab_open();
1043 if (!xendev->xgth) {
1044 error_setg_errno(errp, errno, "failed xengnttab_open");
1045 goto unrealize;
1048 xen_device_backend_create(xendev, errp);
1049 if (*errp) {
1050 goto unrealize;
1053 xen_device_frontend_create(xendev, errp);
1054 if (*errp) {
1055 goto unrealize;
1058 xen_device_backend_printf(xendev, "frontend", "%s",
1059 xendev->frontend_path);
1060 xen_device_backend_printf(xendev, "frontend-id", "%u",
1061 xendev->frontend_id);
1062 xen_device_backend_printf(xendev, "hotplug-status", "connected");
1064 xen_device_backend_set_online(xendev, true);
1065 xen_device_backend_set_state(xendev, XenbusStateInitWait);
1067 if (!xen_device_frontend_exists(xendev)) {
1068 xen_device_frontend_printf(xendev, "backend", "%s",
1069 xendev->backend_path);
1070 xen_device_frontend_printf(xendev, "backend-id", "%u",
1071 xenbus->backend_id);
1073 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1076 if (xendev_class->realize) {
1077 xendev_class->realize(xendev, errp);
1078 if (*errp) {
1079 goto unrealize;
1083 xendev->exit.notify = xen_device_exit;
1084 qemu_add_exit_notifier(&xendev->exit);
1085 return;
1087 unrealize:
1088 xen_device_unrealize(dev);
1091 static Property xen_device_props[] = {
1092 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1093 DOMID_INVALID),
1094 DEFINE_PROP_END_OF_LIST()
1097 static void xen_device_class_init(ObjectClass *class, void *data)
1099 DeviceClass *dev_class = DEVICE_CLASS(class);
1101 dev_class->realize = xen_device_realize;
1102 dev_class->unrealize = xen_device_unrealize;
1103 device_class_set_props(dev_class, xen_device_props);
1104 dev_class->bus_type = TYPE_XEN_BUS;
1107 static const TypeInfo xen_device_type_info = {
1108 .name = TYPE_XEN_DEVICE,
1109 .parent = TYPE_DEVICE,
1110 .instance_size = sizeof(XenDevice),
1111 .abstract = true,
1112 .class_size = sizeof(XenDeviceClass),
1113 .class_init = xen_device_class_init,
1116 typedef struct XenBridge {
1117 SysBusDevice busdev;
1118 } XenBridge;
1120 #define TYPE_XEN_BRIDGE "xen-bridge"
1122 static const TypeInfo xen_bridge_type_info = {
1123 .name = TYPE_XEN_BRIDGE,
1124 .parent = TYPE_SYS_BUS_DEVICE,
1125 .instance_size = sizeof(XenBridge),
1128 static void xen_register_types(void)
1130 type_register_static(&xen_bridge_type_info);
1131 type_register_static(&xen_bus_type_info);
1132 type_register_static(&xen_device_type_info);
1135 type_init(xen_register_types)
1137 void xen_bus_init(void)
1139 DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1140 BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
1142 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1143 qbus_set_bus_hotplug_handler(bus);
1145 qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device",
1146 "xen", "xen-net-device");