Merge tag 'pull-loongarch-20241016' of https://gitlab.com/gaosong/qemu into staging
[qemu/armbru.git] / hw / xen / xen-bus.c
blob95b207ac8b4858d3b7018b77bf3b2fd91524f547
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-legacy-backend.h" /* xen_be_init() */
17 #include "hw/xen/xen-bus.h"
18 #include "hw/xen/xen-bus-helper.h"
19 #include "monitor/monitor.h"
20 #include "qapi/error.h"
21 #include "qapi/qmp/qdict.h"
22 #include "sysemu/sysemu.h"
23 #include "net/net.h"
24 #include "trace.h"
26 static char *xen_device_get_backend_path(XenDevice *xendev)
28 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
29 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
30 const char *type = object_get_typename(OBJECT(xendev));
31 const char *backend = xendev_class->backend;
33 if (!backend) {
34 backend = type;
37 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
38 xenbus->backend_id, backend, xendev->frontend_id,
39 xendev->name);
42 static char *xen_device_get_frontend_path(XenDevice *xendev)
44 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
45 const char *type = object_get_typename(OBJECT(xendev));
46 const char *device = xendev_class->device;
48 if (!device) {
49 device = type;
52 return g_strdup_printf("/local/domain/%u/device/%s/%s",
53 xendev->frontend_id, device, xendev->name);
56 static void xen_device_unplug(XenDevice *xendev, Error **errp)
58 ERRP_GUARD();
59 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
60 const char *type = object_get_typename(OBJECT(xendev));
61 xs_transaction_t tid;
63 trace_xen_device_unplug(type, xendev->name);
65 /* Mimic the way the Xen toolstack does an unplug */
66 again:
67 tid = qemu_xen_xs_transaction_start(xenbus->xsh);
68 if (tid == XBT_NULL) {
69 error_setg_errno(errp, errno, "failed xs_transaction_start");
70 return;
73 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
74 errp, "%u", 0);
75 if (*errp) {
76 goto abort;
79 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
80 errp, "%u", XenbusStateClosing);
81 if (*errp) {
82 goto abort;
85 if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
86 if (errno == EAGAIN) {
87 goto again;
90 error_setg_errno(errp, errno, "failed xs_transaction_end");
93 return;
95 abort:
97 * We only abort if there is already a failure so ignore any error
98 * from ending the transaction.
100 qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
103 static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
105 XenDevice *xendev = XEN_DEVICE(dev);
107 monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
108 indent, "", xendev->name, xendev->frontend_id);
111 static char *xen_bus_get_dev_path(DeviceState *dev)
113 return xen_device_get_backend_path(XEN_DEVICE(dev));
116 static void xen_bus_backend_create(XenBus *xenbus, const char *type,
117 const char *name, char *path,
118 Error **errp)
120 ERRP_GUARD();
121 xs_transaction_t tid;
122 char **key;
123 QDict *opts;
124 unsigned int i, n;
126 trace_xen_bus_backend_create(type, path);
128 again:
129 tid = qemu_xen_xs_transaction_start(xenbus->xsh);
130 if (tid == XBT_NULL) {
131 error_setg(errp, "failed xs_transaction_start");
132 return;
135 key = qemu_xen_xs_directory(xenbus->xsh, tid, path, &n);
136 if (!key) {
137 if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, true)) {
138 error_setg_errno(errp, errno, "failed xs_transaction_end");
140 return;
143 opts = qdict_new();
144 for (i = 0; i < n; i++) {
145 char *val;
148 * Assume anything found in the xenstore backend area, other than
149 * the keys created for a generic XenDevice, are parameters
150 * to be used to configure the backend.
152 if (!strcmp(key[i], "state") ||
153 !strcmp(key[i], "online") ||
154 !strcmp(key[i], "frontend") ||
155 !strcmp(key[i], "frontend-id") ||
156 !strcmp(key[i], "hotplug-status"))
157 continue;
159 if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
160 &val) == 1) {
161 qdict_put_str(opts, key[i], val);
162 free(val);
166 free(key);
168 if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
169 qobject_unref(opts);
171 if (errno == EAGAIN) {
172 goto again;
175 error_setg_errno(errp, errno, "failed xs_transaction_end");
176 return;
179 xen_backend_device_create(xenbus, type, name, opts, errp);
180 qobject_unref(opts);
182 if (*errp) {
183 error_prepend(errp, "failed to create '%s' device '%s': ", type, name);
187 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
189 char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
190 char **backend;
191 unsigned int i, n;
193 trace_xen_bus_type_enumerate(type);
195 backend = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
196 if (!backend) {
197 goto out;
200 for (i = 0; i < n; i++) {
201 char *backend_path = g_strdup_printf("%s/%s", domain_path,
202 backend[i]);
203 enum xenbus_state state;
204 unsigned int online;
206 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
207 NULL, "%u", &state) != 1)
208 state = XenbusStateUnknown;
210 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
211 NULL, "%u", &online) != 1)
212 online = 0;
214 if (online && state == XenbusStateInitialising &&
215 !xen_backend_exists(type, backend[i])) {
216 Error *local_err = NULL;
218 xen_bus_backend_create(xenbus, type, backend[i], backend_path,
219 &local_err);
220 if (local_err) {
221 error_report_err(local_err);
225 g_free(backend_path);
228 free(backend);
230 out:
231 g_free(domain_path);
234 static void xen_bus_enumerate(XenBus *xenbus)
236 char **type;
237 unsigned int i, n;
239 trace_xen_bus_enumerate();
241 type = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
242 if (!type) {
243 return;
246 for (i = 0; i < n; i++) {
247 xen_bus_type_enumerate(xenbus, type[i]);
250 free(type);
253 static void xen_bus_device_cleanup(XenDevice *xendev)
255 const char *type = object_get_typename(OBJECT(xendev));
256 Error *local_err = NULL;
258 trace_xen_bus_device_cleanup(type, xendev->name);
260 g_assert(!xendev->backend_online);
262 if (!xen_backend_try_device_destroy(xendev, &local_err)) {
263 object_unparent(OBJECT(xendev));
266 if (local_err) {
267 error_report_err(local_err);
271 static void xen_bus_cleanup(XenBus *xenbus)
273 XenDevice *xendev, *next;
275 trace_xen_bus_cleanup();
277 QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) {
278 g_assert(xendev->inactive);
279 QLIST_REMOVE(xendev, list);
280 xen_bus_device_cleanup(xendev);
284 static void xen_bus_backend_changed(void *opaque, const char *path)
286 XenBus *xenbus = opaque;
288 xen_bus_enumerate(xenbus);
289 xen_bus_cleanup(xenbus);
292 static void xen_bus_unrealize(BusState *bus)
294 XenBus *xenbus = XEN_BUS(bus);
296 trace_xen_bus_unrealize();
298 if (xenbus->backend_watch) {
299 unsigned int i;
301 for (i = 0; i < xenbus->backend_types; i++) {
302 if (xenbus->backend_watch[i]) {
303 xs_node_unwatch(xenbus->xsh, xenbus->backend_watch[i]);
307 g_free(xenbus->backend_watch);
308 xenbus->backend_watch = NULL;
311 if (xenbus->xsh) {
312 qemu_xen_xs_close(xenbus->xsh);
316 static void xen_bus_realize(BusState *bus, Error **errp)
318 char *key = g_strdup_printf("%u", xen_domid);
319 XenBus *xenbus = XEN_BUS(bus);
320 unsigned int domid;
321 const char **type;
322 unsigned int i;
323 Error *local_err = NULL;
325 trace_xen_bus_realize();
327 xenbus->xsh = qemu_xen_xs_open();
328 if (!xenbus->xsh) {
329 error_setg_errno(errp, errno, "failed xs_open");
330 goto fail;
333 /* Initialize legacy backend core & drivers */
334 xen_be_init();
336 if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */
337 "domid", NULL, "%u", &domid) == 1) {
338 xenbus->backend_id = domid;
339 } else {
340 xenbus->backend_id = 0; /* Assume lack of node means dom0 */
343 module_call_init(MODULE_INIT_XEN_BACKEND);
345 type = xen_backend_get_types(&xenbus->backend_types);
346 xenbus->backend_watch = g_new(struct qemu_xs_watch *,
347 xenbus->backend_types);
349 for (i = 0; i < xenbus->backend_types; i++) {
350 char *node = g_strdup_printf("backend/%s", type[i]);
352 xenbus->backend_watch[i] =
353 xs_node_watch(xenbus->xsh, node, key, xen_bus_backend_changed,
354 xenbus, &local_err);
355 if (local_err) {
356 /* This need not be treated as a hard error so don't propagate */
357 error_reportf_err(local_err,
358 "failed to set up '%s' enumeration watch: ",
359 type[i]);
362 g_free(node);
365 g_free(type);
366 g_free(key);
367 return;
369 fail:
370 xen_bus_unrealize(bus);
371 g_free(key);
374 static void xen_bus_unplug_request(HotplugHandler *hotplug,
375 DeviceState *dev,
376 Error **errp)
378 XenDevice *xendev = XEN_DEVICE(dev);
380 xen_device_unplug(xendev, errp);
383 static void xen_bus_class_init(ObjectClass *class, void *data)
385 BusClass *bus_class = BUS_CLASS(class);
386 HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
388 bus_class->print_dev = xen_bus_print_dev;
389 bus_class->get_dev_path = xen_bus_get_dev_path;
390 bus_class->realize = xen_bus_realize;
391 bus_class->unrealize = xen_bus_unrealize;
393 hotplug_class->unplug_request = xen_bus_unplug_request;
396 static const TypeInfo xen_bus_type_info = {
397 .name = TYPE_XEN_BUS,
398 .parent = TYPE_BUS,
399 .instance_size = sizeof(XenBus),
400 .class_size = sizeof(XenBusClass),
401 .class_init = xen_bus_class_init,
402 .interfaces = (InterfaceInfo[]) {
403 { TYPE_HOTPLUG_HANDLER },
408 void xen_device_backend_printf(XenDevice *xendev, const char *key,
409 const char *fmt, ...)
411 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
412 Error *local_err = NULL;
413 va_list ap;
415 g_assert(xenbus->xsh);
417 va_start(ap, fmt);
418 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
419 &local_err, fmt, ap);
420 va_end(ap);
422 if (local_err) {
423 error_report_err(local_err);
427 G_GNUC_SCANF(3, 4)
428 static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
429 const char *fmt, ...)
431 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
432 va_list ap;
433 int rc;
435 g_assert(xenbus->xsh);
437 va_start(ap, fmt);
438 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
439 NULL, fmt, ap);
440 va_end(ap);
442 return rc;
445 void xen_device_backend_set_state(XenDevice *xendev,
446 enum xenbus_state state)
448 const char *type = object_get_typename(OBJECT(xendev));
450 if (xendev->backend_state == state) {
451 return;
454 trace_xen_device_backend_state(type, xendev->name,
455 xs_strstate(state));
457 xendev->backend_state = state;
458 xen_device_backend_printf(xendev, "state", "%u", state);
461 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
463 return xendev->backend_state;
466 static void xen_device_backend_set_online(XenDevice *xendev, bool online)
468 const char *type = object_get_typename(OBJECT(xendev));
470 if (xendev->backend_online == online) {
471 return;
474 trace_xen_device_backend_online(type, xendev->name, online);
476 xendev->backend_online = online;
477 xen_device_backend_printf(xendev, "online", "%u", online);
481 * Tell from the state whether the frontend is likely alive,
482 * i.e. it will react to a change of state of the backend.
484 static bool xen_device_frontend_is_active(XenDevice *xendev)
486 switch (xendev->frontend_state) {
487 case XenbusStateInitWait:
488 case XenbusStateInitialised:
489 case XenbusStateConnected:
490 case XenbusStateClosing:
491 return true;
492 default:
493 return false;
497 static void xen_device_backend_changed(void *opaque, const char *path)
499 XenDevice *xendev = opaque;
500 const char *type = object_get_typename(OBJECT(xendev));
501 enum xenbus_state state;
502 unsigned int online;
504 trace_xen_device_backend_changed(type, xendev->name);
506 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
507 state = XenbusStateUnknown;
510 xen_device_backend_set_state(xendev, state);
512 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
513 online = 0;
516 xen_device_backend_set_online(xendev, !!online);
519 * If the toolstack (or unplug request callback) has set the backend
520 * state to Closing, but there is no active frontend then set the
521 * backend state to Closed.
523 if (state == XenbusStateClosing &&
524 !xen_device_frontend_is_active(xendev)) {
525 xen_device_backend_set_state(xendev, XenbusStateClosed);
529 * If a backend is still 'online' then we should leave it alone but,
530 * if a backend is not 'online', then the device is a candidate
531 * for destruction. Hence add it to the 'inactive' list to be cleaned
532 * by xen_bus_cleanup().
534 if (!online &&
535 (state == XenbusStateClosed || state == XenbusStateInitialising ||
536 state == XenbusStateInitWait || state == XenbusStateUnknown) &&
537 !xendev->inactive) {
538 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
540 xendev->inactive = true;
541 QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);
544 * Re-write the state to cause a XenBus backend_watch notification,
545 * resulting in a call to xen_bus_cleanup().
547 xen_device_backend_printf(xendev, "state", "%u", state);
551 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
553 ERRP_GUARD();
554 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
556 xendev->backend_path = xen_device_get_backend_path(xendev);
558 g_assert(xenbus->xsh);
560 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path,
561 xenbus->backend_id, xendev->frontend_id, XS_PERM_READ, errp);
562 if (*errp) {
563 error_prepend(errp, "failed to create backend: ");
564 return;
567 xendev->backend_state_watch =
568 xs_node_watch(xendev->xsh, xendev->backend_path,
569 "state", xen_device_backend_changed, xendev,
570 errp);
571 if (*errp) {
572 error_prepend(errp, "failed to watch backend state: ");
573 return;
576 xendev->backend_online_watch =
577 xs_node_watch(xendev->xsh, xendev->backend_path,
578 "online", xen_device_backend_changed, xendev,
579 errp);
580 if (*errp) {
581 error_prepend(errp, "failed to watch backend online: ");
582 return;
586 static void xen_device_backend_destroy(XenDevice *xendev)
588 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
589 Error *local_err = NULL;
591 if (xendev->backend_online_watch) {
592 xs_node_unwatch(xendev->xsh, xendev->backend_online_watch);
593 xendev->backend_online_watch = NULL;
596 if (xendev->backend_state_watch) {
597 xs_node_unwatch(xendev->xsh, xendev->backend_state_watch);
598 xendev->backend_state_watch = NULL;
601 if (!xendev->backend_path) {
602 return;
605 g_assert(xenbus->xsh);
607 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path,
608 &local_err);
609 g_free(xendev->backend_path);
610 xendev->backend_path = NULL;
612 if (local_err) {
613 error_report_err(local_err);
617 void xen_device_frontend_printf(XenDevice *xendev, const char *key,
618 const char *fmt, ...)
620 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
621 Error *local_err = NULL;
622 va_list ap;
624 g_assert(xenbus->xsh);
626 va_start(ap, fmt);
627 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
628 &local_err, fmt, ap);
629 va_end(ap);
631 if (local_err) {
632 error_report_err(local_err);
636 int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
637 const char *fmt, ...)
639 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
640 va_list ap;
641 int rc;
643 g_assert(xenbus->xsh);
645 va_start(ap, fmt);
646 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
647 NULL, fmt, ap);
648 va_end(ap);
650 return rc;
653 static void xen_device_frontend_set_state(XenDevice *xendev,
654 enum xenbus_state state,
655 bool publish)
657 const char *type = object_get_typename(OBJECT(xendev));
659 if (xendev->frontend_state == state) {
660 return;
663 trace_xen_device_frontend_state(type, xendev->name,
664 xs_strstate(state));
666 xendev->frontend_state = state;
667 if (publish) {
668 xen_device_frontend_printf(xendev, "state", "%u", state);
672 static void xen_device_frontend_changed(void *opaque, const char *path)
674 XenDevice *xendev = opaque;
675 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
676 const char *type = object_get_typename(OBJECT(xendev));
677 enum xenbus_state state;
679 trace_xen_device_frontend_changed(type, xendev->name);
681 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
682 state = XenbusStateUnknown;
685 xen_device_frontend_set_state(xendev, state, false);
687 if (state == XenbusStateInitialising &&
688 xendev->backend_state == XenbusStateClosed &&
689 xendev->backend_online) {
691 * The frontend is re-initializing so switch back to
692 * InitWait.
694 xen_device_backend_set_state(xendev, XenbusStateInitWait);
695 return;
698 if (xendev_class->frontend_changed) {
699 Error *local_err = NULL;
701 xendev_class->frontend_changed(xendev, state, &local_err);
703 if (local_err) {
704 error_reportf_err(local_err, "frontend change error: ");
709 static bool xen_device_frontend_exists(XenDevice *xendev)
711 enum xenbus_state state;
713 return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
716 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
718 ERRP_GUARD();
719 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
720 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
722 if (xendev_class->get_frontend_path) {
723 xendev->frontend_path = xendev_class->get_frontend_path(xendev, errp);
724 if (!xendev->frontend_path) {
725 error_prepend(errp, "failed to create frontend: ");
726 return;
728 } else {
729 xendev->frontend_path = xen_device_get_frontend_path(xendev);
733 * The frontend area may have already been created by a legacy
734 * toolstack.
736 if (!xen_device_frontend_exists(xendev)) {
737 g_assert(xenbus->xsh);
739 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path,
740 xendev->frontend_id, xenbus->backend_id,
741 XS_PERM_READ | XS_PERM_WRITE, errp);
742 if (*errp) {
743 error_prepend(errp, "failed to create frontend: ");
744 return;
748 xendev->frontend_state_watch =
749 xs_node_watch(xendev->xsh, xendev->frontend_path, "state",
750 xen_device_frontend_changed, xendev, errp);
751 if (*errp) {
752 error_prepend(errp, "failed to watch frontend state: ");
756 static void xen_device_frontend_destroy(XenDevice *xendev)
758 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
759 Error *local_err = NULL;
761 if (xendev->frontend_state_watch) {
762 xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
763 xendev->frontend_state_watch = NULL;
766 if (!xendev->frontend_path) {
767 return;
770 g_assert(xenbus->xsh);
772 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
773 &local_err);
774 g_free(xendev->frontend_path);
775 xendev->frontend_path = NULL;
777 if (local_err) {
778 error_report_err(local_err);
782 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
783 Error **errp)
785 if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
786 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
790 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
791 unsigned int nr_refs, int prot,
792 Error **errp)
794 void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
795 xendev->frontend_id, refs, prot);
797 if (!map) {
798 error_setg_errno(errp, errno,
799 "xengnttab_map_domain_grant_refs failed");
802 return map;
805 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
806 unsigned int nr_refs, Error **errp)
808 if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
809 error_setg_errno(errp, errno, "xengnttab_unmap failed");
813 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
814 XenDeviceGrantCopySegment segs[],
815 unsigned int nr_segs, Error **errp)
817 qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
818 (XenGrantCopySegment *)segs, nr_segs, errp);
821 struct XenEventChannel {
822 QLIST_ENTRY(XenEventChannel) list;
823 AioContext *ctx;
824 xenevtchn_handle *xeh;
825 evtchn_port_t local_port;
826 XenEventHandler handler;
827 void *opaque;
830 static bool xen_device_poll(void *opaque)
832 XenEventChannel *channel = opaque;
834 return channel->handler(channel->opaque);
837 static void xen_device_event(void *opaque)
839 XenEventChannel *channel = opaque;
840 unsigned long port = qemu_xen_evtchn_pending(channel->xeh);
842 if (port == channel->local_port) {
843 xen_device_poll(channel);
845 qemu_xen_evtchn_unmask(channel->xeh, port);
849 void xen_device_set_event_channel_context(XenDevice *xendev,
850 XenEventChannel *channel,
851 AioContext *ctx,
852 Error **errp)
854 if (!channel) {
855 error_setg(errp, "bad channel");
856 return;
859 if (channel->ctx)
860 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
861 NULL, NULL, NULL, NULL, NULL);
863 channel->ctx = ctx;
864 if (ctx) {
865 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
866 xen_device_event, NULL, xen_device_poll, NULL,
867 channel);
871 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
872 unsigned int port,
873 XenEventHandler handler,
874 void *opaque, Error **errp)
876 XenEventChannel *channel = g_new0(XenEventChannel, 1);
877 xenevtchn_port_or_error_t local_port;
879 channel->xeh = qemu_xen_evtchn_open();
880 if (!channel->xeh) {
881 error_setg_errno(errp, errno, "failed xenevtchn_open");
882 goto fail;
885 local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh,
886 xendev->frontend_id,
887 port);
888 if (local_port < 0) {
889 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
890 goto fail;
893 channel->local_port = local_port;
894 channel->handler = handler;
895 channel->opaque = opaque;
897 /* Only reason for failure is a NULL channel */
898 xen_device_set_event_channel_context(xendev, channel,
899 qemu_get_aio_context(),
900 &error_abort);
902 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
904 return channel;
906 fail:
907 if (channel->xeh) {
908 qemu_xen_evtchn_close(channel->xeh);
911 g_free(channel);
913 return NULL;
916 void xen_device_notify_event_channel(XenDevice *xendev,
917 XenEventChannel *channel,
918 Error **errp)
920 if (!channel) {
921 error_setg(errp, "bad channel");
922 return;
925 if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
926 error_setg_errno(errp, errno, "xenevtchn_notify failed");
930 unsigned int xen_event_channel_get_local_port(XenEventChannel *channel)
932 return channel->local_port;
935 void xen_device_unbind_event_channel(XenDevice *xendev,
936 XenEventChannel *channel,
937 Error **errp)
939 if (!channel) {
940 error_setg(errp, "bad channel");
941 return;
944 QLIST_REMOVE(channel, list);
946 if (channel->ctx) {
947 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
948 NULL, NULL, NULL, NULL, NULL);
951 if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
952 error_setg_errno(errp, errno, "xenevtchn_unbind failed");
955 qemu_xen_evtchn_close(channel->xeh);
956 g_free(channel);
959 static void xen_device_unrealize(DeviceState *dev)
961 XenDevice *xendev = XEN_DEVICE(dev);
962 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
963 const char *type = object_get_typename(OBJECT(xendev));
964 XenEventChannel *channel, *next;
966 if (!xendev->name) {
967 return;
970 trace_xen_device_unrealize(type, xendev->name);
972 if (xendev->exit.notify) {
973 qemu_remove_exit_notifier(&xendev->exit);
974 xendev->exit.notify = NULL;
977 if (xendev_class->unrealize) {
978 xendev_class->unrealize(xendev);
981 /* Make sure all event channels are cleaned up */
982 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
983 xen_device_unbind_event_channel(xendev, channel, NULL);
986 xen_device_frontend_destroy(xendev);
987 xen_device_backend_destroy(xendev);
989 if (xendev->xgth) {
990 qemu_xen_gnttab_close(xendev->xgth);
991 xendev->xgth = NULL;
994 if (xendev->xsh) {
995 qemu_xen_xs_close(xendev->xsh);
996 xendev->xsh = NULL;
999 g_free(xendev->name);
1000 xendev->name = NULL;
1003 static void xen_device_exit(Notifier *n, void *data)
1005 XenDevice *xendev = container_of(n, XenDevice, exit);
1007 xen_device_unrealize(DEVICE(xendev));
1010 static void xen_device_realize(DeviceState *dev, Error **errp)
1012 ERRP_GUARD();
1013 XenDevice *xendev = XEN_DEVICE(dev);
1014 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
1015 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
1016 const char *type = object_get_typename(OBJECT(xendev));
1018 if (xendev->frontend_id == DOMID_INVALID) {
1019 xendev->frontend_id = xen_domid;
1022 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1023 error_setg(errp, "invalid frontend-id");
1024 goto unrealize;
1027 if (!xendev_class->get_name) {
1028 error_setg(errp, "get_name method not implemented");
1029 goto unrealize;
1032 xendev->name = xendev_class->get_name(xendev, errp);
1033 if (*errp) {
1034 error_prepend(errp, "failed to get device name: ");
1035 goto unrealize;
1038 trace_xen_device_realize(type, xendev->name);
1040 xendev->xsh = qemu_xen_xs_open();
1041 if (!xendev->xsh) {
1042 error_setg_errno(errp, errno, "failed xs_open");
1043 goto unrealize;
1046 xendev->xgth = qemu_xen_gnttab_open();
1047 if (!xendev->xgth) {
1048 error_setg_errno(errp, errno, "failed xengnttab_open");
1049 goto unrealize;
1052 xen_device_backend_create(xendev, errp);
1053 if (*errp) {
1054 goto unrealize;
1057 xen_device_frontend_create(xendev, errp);
1058 if (*errp) {
1059 goto unrealize;
1062 xen_device_backend_printf(xendev, "frontend", "%s",
1063 xendev->frontend_path);
1064 xen_device_backend_printf(xendev, "frontend-id", "%u",
1065 xendev->frontend_id);
1066 xen_device_backend_printf(xendev, "hotplug-status", "connected");
1068 xen_device_backend_set_online(xendev, true);
1069 xen_device_backend_set_state(xendev, XenbusStateInitWait);
1071 if (!xen_device_frontend_exists(xendev)) {
1072 xen_device_frontend_printf(xendev, "backend", "%s",
1073 xendev->backend_path);
1074 xen_device_frontend_printf(xendev, "backend-id", "%u",
1075 xenbus->backend_id);
1077 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1080 if (xendev_class->realize) {
1081 xendev_class->realize(xendev, errp);
1082 if (*errp) {
1083 goto unrealize;
1087 xendev->exit.notify = xen_device_exit;
1088 qemu_add_exit_notifier(&xendev->exit);
1089 return;
1091 unrealize:
1092 xen_device_unrealize(dev);
1095 static Property xen_device_props[] = {
1096 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1097 DOMID_INVALID),
1098 DEFINE_PROP_END_OF_LIST()
1101 static void xen_device_class_init(ObjectClass *class, void *data)
1103 DeviceClass *dev_class = DEVICE_CLASS(class);
1105 dev_class->realize = xen_device_realize;
1106 dev_class->unrealize = xen_device_unrealize;
1107 device_class_set_props(dev_class, xen_device_props);
1108 dev_class->bus_type = TYPE_XEN_BUS;
1111 static const TypeInfo xen_device_type_info = {
1112 .name = TYPE_XEN_DEVICE,
1113 .parent = TYPE_DEVICE,
1114 .instance_size = sizeof(XenDevice),
1115 .abstract = true,
1116 .class_size = sizeof(XenDeviceClass),
1117 .class_init = xen_device_class_init,
1120 typedef struct XenBridge {
1121 SysBusDevice busdev;
1122 } XenBridge;
1124 #define TYPE_XEN_BRIDGE "xen-bridge"
1126 static const TypeInfo xen_bridge_type_info = {
1127 .name = TYPE_XEN_BRIDGE,
1128 .parent = TYPE_SYS_BUS_DEVICE,
1129 .instance_size = sizeof(XenBridge),
1132 static void xen_register_types(void)
1134 type_register_static(&xen_bridge_type_info);
1135 type_register_static(&xen_bus_type_info);
1136 type_register_static(&xen_device_type_info);
1139 type_init(xen_register_types)
1141 void xen_bus_init(void)
1143 DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1144 BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
1146 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1147 qbus_set_bus_hotplug_handler(bus);
1149 qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device",
1150 "xen", "xen-net-device");