xref: /qemu/hw/xen/xen-bus.c (revision ec6f3fc3)
1 /*
2  * Copyright (c) 2018  Citrix Systems Inc.
3  *
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  */
7 
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 "trace.h"
23 
24 static char *xen_device_get_backend_path(XenDevice *xendev)
25 {
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;
30 
31     if (!backend) {
32         backend = type;
33     }
34 
35     return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
36                            xenbus->backend_id, backend, xendev->frontend_id,
37                            xendev->name);
38 }
39 
40 static char *xen_device_get_frontend_path(XenDevice *xendev)
41 {
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;
45 
46     if (!device) {
47         device = type;
48     }
49 
50     return g_strdup_printf("/local/domain/%u/device/%s/%s",
51                            xendev->frontend_id, device, xendev->name);
52 }
53 
54 static void xen_device_unplug(XenDevice *xendev, Error **errp)
55 {
56     ERRP_GUARD();
57     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
58     const char *type = object_get_typename(OBJECT(xendev));
59     xs_transaction_t tid;
60 
61     trace_xen_device_unplug(type, xendev->name);
62 
63     /* Mimic the way the Xen toolstack does an unplug */
64 again:
65     tid = qemu_xen_xs_transaction_start(xenbus->xsh);
66     if (tid == XBT_NULL) {
67         error_setg_errno(errp, errno, "failed xs_transaction_start");
68         return;
69     }
70 
71     xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
72                    errp, "%u", 0);
73     if (*errp) {
74         goto abort;
75     }
76 
77     xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
78                    errp, "%u", XenbusStateClosing);
79     if (*errp) {
80         goto abort;
81     }
82 
83     if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
84         if (errno == EAGAIN) {
85             goto again;
86         }
87 
88         error_setg_errno(errp, errno, "failed xs_transaction_end");
89     }
90 
91     return;
92 
93 abort:
94     /*
95      * We only abort if there is already a failure so ignore any error
96      * from ending the transaction.
97      */
98     qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
99 }
100 
101 static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
102 {
103     XenDevice *xendev = XEN_DEVICE(dev);
104 
105     monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
106                    indent, "", xendev->name, xendev->frontend_id);
107 }
108 
109 static char *xen_bus_get_dev_path(DeviceState *dev)
110 {
111     return xen_device_get_backend_path(XEN_DEVICE(dev));
112 }
113 
114 static void xen_bus_backend_create(XenBus *xenbus, const char *type,
115                                    const char *name, char *path,
116                                    Error **errp)
117 {
118     ERRP_GUARD();
119     xs_transaction_t tid;
120     char **key;
121     QDict *opts;
122     unsigned int i, n;
123 
124     trace_xen_bus_backend_create(type, path);
125 
126 again:
127     tid = qemu_xen_xs_transaction_start(xenbus->xsh);
128     if (tid == XBT_NULL) {
129         error_setg(errp, "failed xs_transaction_start");
130         return;
131     }
132 
133     key = qemu_xen_xs_directory(xenbus->xsh, tid, path, &n);
134     if (!key) {
135         if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, true)) {
136             error_setg_errno(errp, errno, "failed xs_transaction_end");
137         }
138         return;
139     }
140 
141     opts = qdict_new();
142     for (i = 0; i < n; i++) {
143         char *val;
144 
145         /*
146          * Assume anything found in the xenstore backend area, other than
147          * the keys created for a generic XenDevice, are parameters
148          * to be used to configure the backend.
149          */
150         if (!strcmp(key[i], "state") ||
151             !strcmp(key[i], "online") ||
152             !strcmp(key[i], "frontend") ||
153             !strcmp(key[i], "frontend-id") ||
154             !strcmp(key[i], "hotplug-status"))
155             continue;
156 
157         if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms",
158                           &val) == 1) {
159             qdict_put_str(opts, key[i], val);
160             free(val);
161         }
162     }
163 
164     free(key);
165 
166     if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
167         qobject_unref(opts);
168 
169         if (errno == EAGAIN) {
170             goto again;
171         }
172 
173         error_setg_errno(errp, errno, "failed xs_transaction_end");
174         return;
175     }
176 
177     xen_backend_device_create(xenbus, type, name, opts, errp);
178     qobject_unref(opts);
179 
180     if (*errp) {
181         error_prepend(errp, "failed to create '%s' device '%s': ", type, name);
182     }
183 }
184 
185 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
186 {
187     char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
188     char **backend;
189     unsigned int i, n;
190 
191     trace_xen_bus_type_enumerate(type);
192 
193     backend = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
194     if (!backend) {
195         goto out;
196     }
197 
198     for (i = 0; i < n; i++) {
199         char *backend_path = g_strdup_printf("%s/%s", domain_path,
200                                              backend[i]);
201         enum xenbus_state state;
202         unsigned int online;
203 
204         if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
205                           NULL, "%u", &state) != 1)
206             state = XenbusStateUnknown;
207 
208         if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
209                           NULL, "%u", &online) != 1)
210             online = 0;
211 
212         if (online && state == XenbusStateInitialising &&
213             !xen_backend_exists(type, backend[i])) {
214             Error *local_err = NULL;
215 
216             xen_bus_backend_create(xenbus, type, backend[i], backend_path,
217                                    &local_err);
218             if (local_err) {
219                 error_report_err(local_err);
220             }
221         }
222 
223         g_free(backend_path);
224     }
225 
226     free(backend);
227 
228 out:
229     g_free(domain_path);
230 }
231 
232 static void xen_bus_enumerate(XenBus *xenbus)
233 {
234     char **type;
235     unsigned int i, n;
236 
237     trace_xen_bus_enumerate();
238 
239     type = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
240     if (!type) {
241         return;
242     }
243 
244     for (i = 0; i < n; i++) {
245         xen_bus_type_enumerate(xenbus, type[i]);
246     }
247 
248     free(type);
249 }
250 
251 static void xen_bus_device_cleanup(XenDevice *xendev)
252 {
253     const char *type = object_get_typename(OBJECT(xendev));
254     Error *local_err = NULL;
255 
256     trace_xen_bus_device_cleanup(type, xendev->name);
257 
258     g_assert(!xendev->backend_online);
259 
260     if (!xen_backend_try_device_destroy(xendev, &local_err)) {
261         object_unparent(OBJECT(xendev));
262     }
263 
264     if (local_err) {
265         error_report_err(local_err);
266     }
267 }
268 
269 static void xen_bus_cleanup(XenBus *xenbus)
270 {
271     XenDevice *xendev, *next;
272 
273     trace_xen_bus_cleanup();
274 
275     QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) {
276         g_assert(xendev->inactive);
277         QLIST_REMOVE(xendev, list);
278         xen_bus_device_cleanup(xendev);
279     }
280 }
281 
282 static void xen_bus_backend_changed(void *opaque, const char *path)
283 {
284     XenBus *xenbus = opaque;
285 
286     xen_bus_enumerate(xenbus);
287     xen_bus_cleanup(xenbus);
288 }
289 
290 static void xen_bus_unrealize(BusState *bus)
291 {
292     XenBus *xenbus = XEN_BUS(bus);
293 
294     trace_xen_bus_unrealize();
295 
296     if (xenbus->backend_watch) {
297         unsigned int i;
298 
299         for (i = 0; i < xenbus->backend_types; i++) {
300             if (xenbus->backend_watch[i]) {
301                 xs_node_unwatch(xenbus->xsh, xenbus->backend_watch[i]);
302             }
303         }
304 
305         g_free(xenbus->backend_watch);
306         xenbus->backend_watch = NULL;
307     }
308 
309     if (xenbus->xsh) {
310         qemu_xen_xs_close(xenbus->xsh);
311     }
312 }
313 
314 static void xen_bus_realize(BusState *bus, Error **errp)
315 {
316     char *key = g_strdup_printf("%u", xen_domid);
317     XenBus *xenbus = XEN_BUS(bus);
318     unsigned int domid;
319     const char **type;
320     unsigned int i;
321     Error *local_err = NULL;
322 
323     trace_xen_bus_realize();
324 
325     xenbus->xsh = qemu_xen_xs_open();
326     if (!xenbus->xsh) {
327         error_setg_errno(errp, errno, "failed xs_open");
328         goto fail;
329     }
330 
331     if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */
332                       "domid", NULL, "%u", &domid) == 1) {
333         xenbus->backend_id = domid;
334     } else {
335         xenbus->backend_id = 0; /* Assume lack of node means dom0 */
336     }
337 
338     module_call_init(MODULE_INIT_XEN_BACKEND);
339 
340     type = xen_backend_get_types(&xenbus->backend_types);
341     xenbus->backend_watch = g_new(struct qemu_xs_watch *,
342                                   xenbus->backend_types);
343 
344     for (i = 0; i < xenbus->backend_types; i++) {
345         char *node = g_strdup_printf("backend/%s", type[i]);
346 
347         xenbus->backend_watch[i] =
348             xs_node_watch(xenbus->xsh, node, key, xen_bus_backend_changed,
349                           xenbus, &local_err);
350         if (local_err) {
351             /* This need not be treated as a hard error so don't propagate */
352             error_reportf_err(local_err,
353                               "failed to set up '%s' enumeration watch: ",
354                               type[i]);
355         }
356 
357         g_free(node);
358     }
359 
360     g_free(type);
361     g_free(key);
362     return;
363 
364 fail:
365     xen_bus_unrealize(bus);
366     g_free(key);
367 }
368 
369 static void xen_bus_unplug_request(HotplugHandler *hotplug,
370                                    DeviceState *dev,
371                                    Error **errp)
372 {
373     XenDevice *xendev = XEN_DEVICE(dev);
374 
375     xen_device_unplug(xendev, errp);
376 }
377 
378 static void xen_bus_class_init(ObjectClass *class, void *data)
379 {
380     BusClass *bus_class = BUS_CLASS(class);
381     HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
382 
383     bus_class->print_dev = xen_bus_print_dev;
384     bus_class->get_dev_path = xen_bus_get_dev_path;
385     bus_class->realize = xen_bus_realize;
386     bus_class->unrealize = xen_bus_unrealize;
387 
388     hotplug_class->unplug_request = xen_bus_unplug_request;
389 }
390 
391 static const TypeInfo xen_bus_type_info = {
392     .name = TYPE_XEN_BUS,
393     .parent = TYPE_BUS,
394     .instance_size = sizeof(XenBus),
395     .class_size = sizeof(XenBusClass),
396     .class_init = xen_bus_class_init,
397     .interfaces = (InterfaceInfo[]) {
398         { TYPE_HOTPLUG_HANDLER },
399         { }
400     },
401 };
402 
403 void xen_device_backend_printf(XenDevice *xendev, const char *key,
404                                const char *fmt, ...)
405 {
406     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
407     Error *local_err = NULL;
408     va_list ap;
409 
410     g_assert(xenbus->xsh);
411 
412     va_start(ap, fmt);
413     xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
414                     &local_err, fmt, ap);
415     va_end(ap);
416 
417     if (local_err) {
418         error_report_err(local_err);
419     }
420 }
421 
422 G_GNUC_SCANF(3, 4)
423 static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
424                                     const char *fmt, ...)
425 {
426     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
427     va_list ap;
428     int rc;
429 
430     g_assert(xenbus->xsh);
431 
432     va_start(ap, fmt);
433     rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key,
434                         NULL, fmt, ap);
435     va_end(ap);
436 
437     return rc;
438 }
439 
440 void xen_device_backend_set_state(XenDevice *xendev,
441                                   enum xenbus_state state)
442 {
443     const char *type = object_get_typename(OBJECT(xendev));
444 
445     if (xendev->backend_state == state) {
446         return;
447     }
448 
449     trace_xen_device_backend_state(type, xendev->name,
450                                    xs_strstate(state));
451 
452     xendev->backend_state = state;
453     xen_device_backend_printf(xendev, "state", "%u", state);
454 }
455 
456 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
457 {
458     return xendev->backend_state;
459 }
460 
461 static void xen_device_backend_set_online(XenDevice *xendev, bool online)
462 {
463     const char *type = object_get_typename(OBJECT(xendev));
464 
465     if (xendev->backend_online == online) {
466         return;
467     }
468 
469     trace_xen_device_backend_online(type, xendev->name, online);
470 
471     xendev->backend_online = online;
472     xen_device_backend_printf(xendev, "online", "%u", online);
473 }
474 
475 /*
476  * Tell from the state whether the frontend is likely alive,
477  * i.e. it will react to a change of state of the backend.
478  */
479 static bool xen_device_frontend_is_active(XenDevice *xendev)
480 {
481     switch (xendev->frontend_state) {
482     case XenbusStateInitWait:
483     case XenbusStateInitialised:
484     case XenbusStateConnected:
485     case XenbusStateClosing:
486         return true;
487     default:
488         return false;
489     }
490 }
491 
492 static void xen_device_backend_changed(void *opaque, const char *path)
493 {
494     XenDevice *xendev = opaque;
495     const char *type = object_get_typename(OBJECT(xendev));
496     enum xenbus_state state;
497     unsigned int online;
498 
499     trace_xen_device_backend_changed(type, xendev->name);
500 
501     if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
502         state = XenbusStateUnknown;
503     }
504 
505     xen_device_backend_set_state(xendev, state);
506 
507     if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
508         online = 0;
509     }
510 
511     xen_device_backend_set_online(xendev, !!online);
512 
513     /*
514      * If the toolstack (or unplug request callback) has set the backend
515      * state to Closing, but there is no active frontend then set the
516      * backend state to Closed.
517      */
518     if (state == XenbusStateClosing &&
519         !xen_device_frontend_is_active(xendev)) {
520         xen_device_backend_set_state(xendev, XenbusStateClosed);
521     }
522 
523     /*
524      * If a backend is still 'online' then we should leave it alone but,
525      * if a backend is not 'online', then the device is a candidate
526      * for destruction. Hence add it to the 'inactive' list to be cleaned
527      * by xen_bus_cleanup().
528      */
529     if (!online &&
530         (state == XenbusStateClosed ||  state == XenbusStateInitialising ||
531          state == XenbusStateInitWait || state == XenbusStateUnknown) &&
532         !xendev->inactive) {
533         XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
534 
535         xendev->inactive = true;
536         QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);
537 
538         /*
539          * Re-write the state to cause a XenBus backend_watch notification,
540          * resulting in a call to xen_bus_cleanup().
541          */
542         xen_device_backend_printf(xendev, "state", "%u", state);
543     }
544 }
545 
546 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
547 {
548     ERRP_GUARD();
549     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
550 
551     xendev->backend_path = xen_device_get_backend_path(xendev);
552 
553     g_assert(xenbus->xsh);
554 
555     xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path,
556                    xenbus->backend_id, xendev->frontend_id, XS_PERM_READ, errp);
557     if (*errp) {
558         error_prepend(errp, "failed to create backend: ");
559         return;
560     }
561 
562     xendev->backend_state_watch =
563         xs_node_watch(xendev->xsh, xendev->backend_path,
564                       "state", xen_device_backend_changed, xendev,
565                       errp);
566     if (*errp) {
567         error_prepend(errp, "failed to watch backend state: ");
568         return;
569     }
570 
571     xendev->backend_online_watch =
572         xs_node_watch(xendev->xsh, xendev->backend_path,
573                       "online", xen_device_backend_changed, xendev,
574                       errp);
575     if (*errp) {
576         error_prepend(errp, "failed to watch backend online: ");
577         return;
578     }
579 }
580 
581 static void xen_device_backend_destroy(XenDevice *xendev)
582 {
583     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
584     Error *local_err = NULL;
585 
586     if (xendev->backend_online_watch) {
587         xs_node_unwatch(xendev->xsh, xendev->backend_online_watch);
588         xendev->backend_online_watch = NULL;
589     }
590 
591     if (xendev->backend_state_watch) {
592         xs_node_unwatch(xendev->xsh, xendev->backend_state_watch);
593         xendev->backend_state_watch = NULL;
594     }
595 
596     if (!xendev->backend_path) {
597         return;
598     }
599 
600     g_assert(xenbus->xsh);
601 
602     xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path,
603                     &local_err);
604     g_free(xendev->backend_path);
605     xendev->backend_path = NULL;
606 
607     if (local_err) {
608         error_report_err(local_err);
609     }
610 }
611 
612 void xen_device_frontend_printf(XenDevice *xendev, const char *key,
613                                 const char *fmt, ...)
614 {
615     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
616     Error *local_err = NULL;
617     va_list ap;
618 
619     g_assert(xenbus->xsh);
620 
621     va_start(ap, fmt);
622     xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
623                     &local_err, fmt, ap);
624     va_end(ap);
625 
626     if (local_err) {
627         error_report_err(local_err);
628     }
629 }
630 
631 int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
632                               const char *fmt, ...)
633 {
634     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
635     va_list ap;
636     int rc;
637 
638     g_assert(xenbus->xsh);
639 
640     va_start(ap, fmt);
641     rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key,
642                         NULL, fmt, ap);
643     va_end(ap);
644 
645     return rc;
646 }
647 
648 static void xen_device_frontend_set_state(XenDevice *xendev,
649                                           enum xenbus_state state,
650                                           bool publish)
651 {
652     const char *type = object_get_typename(OBJECT(xendev));
653 
654     if (xendev->frontend_state == state) {
655         return;
656     }
657 
658     trace_xen_device_frontend_state(type, xendev->name,
659                                     xs_strstate(state));
660 
661     xendev->frontend_state = state;
662     if (publish) {
663         xen_device_frontend_printf(xendev, "state", "%u", state);
664     }
665 }
666 
667 static void xen_device_frontend_changed(void *opaque, const char *path)
668 {
669     XenDevice *xendev = opaque;
670     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
671     const char *type = object_get_typename(OBJECT(xendev));
672     enum xenbus_state state;
673 
674     trace_xen_device_frontend_changed(type, xendev->name);
675 
676     if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
677         state = XenbusStateUnknown;
678     }
679 
680     xen_device_frontend_set_state(xendev, state, false);
681 
682     if (state == XenbusStateInitialising &&
683         xendev->backend_state == XenbusStateClosed &&
684         xendev->backend_online) {
685         /*
686          * The frontend is re-initializing so switch back to
687          * InitWait.
688          */
689         xen_device_backend_set_state(xendev, XenbusStateInitWait);
690         return;
691     }
692 
693     if (xendev_class->frontend_changed) {
694         Error *local_err = NULL;
695 
696         xendev_class->frontend_changed(xendev, state, &local_err);
697 
698         if (local_err) {
699             error_reportf_err(local_err, "frontend change error: ");
700         }
701     }
702 }
703 
704 static bool xen_device_frontend_exists(XenDevice *xendev)
705 {
706     enum xenbus_state state;
707 
708     return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
709 }
710 
711 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
712 {
713     ERRP_GUARD();
714     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
715     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
716 
717     if (xendev_class->get_frontend_path) {
718         xendev->frontend_path = xendev_class->get_frontend_path(xendev, errp);
719         if (!xendev->frontend_path) {
720             error_prepend(errp, "failed to create frontend: ");
721             return;
722         }
723     } else {
724         xendev->frontend_path = xen_device_get_frontend_path(xendev);
725     }
726 
727     /*
728      * The frontend area may have already been created by a legacy
729      * toolstack.
730      */
731     if (!xen_device_frontend_exists(xendev)) {
732         g_assert(xenbus->xsh);
733 
734         xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path,
735                        xendev->frontend_id, xenbus->backend_id,
736                        XS_PERM_READ | XS_PERM_WRITE, errp);
737         if (*errp) {
738             error_prepend(errp, "failed to create frontend: ");
739             return;
740         }
741     }
742 
743     xendev->frontend_state_watch =
744         xs_node_watch(xendev->xsh, xendev->frontend_path, "state",
745                       xen_device_frontend_changed, xendev, errp);
746     if (*errp) {
747         error_prepend(errp, "failed to watch frontend state: ");
748     }
749 }
750 
751 static void xen_device_frontend_destroy(XenDevice *xendev)
752 {
753     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
754     Error *local_err = NULL;
755 
756     if (xendev->frontend_state_watch) {
757         xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
758         xendev->frontend_state_watch = NULL;
759     }
760 
761     if (!xendev->frontend_path) {
762         return;
763     }
764 
765     g_assert(xenbus->xsh);
766 
767     xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
768                     &local_err);
769     g_free(xendev->frontend_path);
770     xendev->frontend_path = NULL;
771 
772     if (local_err) {
773         error_report_err(local_err);
774     }
775 }
776 
777 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
778                                    Error **errp)
779 {
780     if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
781         error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
782     }
783 }
784 
785 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
786                                 unsigned int nr_refs, int prot,
787                                 Error **errp)
788 {
789     void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
790                                          xendev->frontend_id, refs, prot);
791 
792     if (!map) {
793         error_setg_errno(errp, errno,
794                          "xengnttab_map_domain_grant_refs failed");
795     }
796 
797     return map;
798 }
799 
800 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
801                                  unsigned int nr_refs, Error **errp)
802 {
803     if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
804         error_setg_errno(errp, errno, "xengnttab_unmap failed");
805     }
806 }
807 
808 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
809                                 XenDeviceGrantCopySegment segs[],
810                                 unsigned int nr_segs, Error **errp)
811 {
812     qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
813                                (XenGrantCopySegment *)segs, nr_segs, errp);
814 }
815 
816 struct XenEventChannel {
817     QLIST_ENTRY(XenEventChannel) list;
818     AioContext *ctx;
819     xenevtchn_handle *xeh;
820     evtchn_port_t local_port;
821     XenEventHandler handler;
822     void *opaque;
823 };
824 
825 static bool xen_device_poll(void *opaque)
826 {
827     XenEventChannel *channel = opaque;
828 
829     return channel->handler(channel->opaque);
830 }
831 
832 static void xen_device_event(void *opaque)
833 {
834     XenEventChannel *channel = opaque;
835     unsigned long port = qemu_xen_evtchn_pending(channel->xeh);
836 
837     if (port == channel->local_port) {
838         xen_device_poll(channel);
839 
840         qemu_xen_evtchn_unmask(channel->xeh, port);
841     }
842 }
843 
844 void xen_device_set_event_channel_context(XenDevice *xendev,
845                                           XenEventChannel *channel,
846                                           AioContext *ctx,
847                                           Error **errp)
848 {
849     if (!channel) {
850         error_setg(errp, "bad channel");
851         return;
852     }
853 
854     if (channel->ctx)
855         aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
856                            NULL, NULL, NULL, NULL, NULL);
857 
858     channel->ctx = ctx;
859     if (ctx) {
860         aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
861                            xen_device_event, NULL, xen_device_poll, NULL,
862                            channel);
863     }
864 }
865 
866 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
867                                                unsigned int port,
868                                                XenEventHandler handler,
869                                                void *opaque, Error **errp)
870 {
871     XenEventChannel *channel = g_new0(XenEventChannel, 1);
872     xenevtchn_port_or_error_t local_port;
873 
874     channel->xeh = qemu_xen_evtchn_open();
875     if (!channel->xeh) {
876         error_setg_errno(errp, errno, "failed xenevtchn_open");
877         goto fail;
878     }
879 
880     local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh,
881                                             xendev->frontend_id,
882                                             port);
883     if (local_port < 0) {
884         error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
885         goto fail;
886     }
887 
888     channel->local_port = local_port;
889     channel->handler = handler;
890     channel->opaque = opaque;
891 
892     /* Only reason for failure is a NULL channel */
893     xen_device_set_event_channel_context(xendev, channel,
894                                          qemu_get_aio_context(),
895                                          &error_abort);
896 
897     QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
898 
899     return channel;
900 
901 fail:
902     if (channel->xeh) {
903         qemu_xen_evtchn_close(channel->xeh);
904     }
905 
906     g_free(channel);
907 
908     return NULL;
909 }
910 
911 void xen_device_notify_event_channel(XenDevice *xendev,
912                                      XenEventChannel *channel,
913                                      Error **errp)
914 {
915     if (!channel) {
916         error_setg(errp, "bad channel");
917         return;
918     }
919 
920     if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
921         error_setg_errno(errp, errno, "xenevtchn_notify failed");
922     }
923 }
924 
925 unsigned int xen_event_channel_get_local_port(XenEventChannel *channel)
926 {
927     return channel->local_port;
928 }
929 
930 void xen_device_unbind_event_channel(XenDevice *xendev,
931                                      XenEventChannel *channel,
932                                      Error **errp)
933 {
934     if (!channel) {
935         error_setg(errp, "bad channel");
936         return;
937     }
938 
939     QLIST_REMOVE(channel, list);
940 
941     if (channel->ctx) {
942         aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
943                            NULL, NULL, NULL, NULL, NULL);
944     }
945 
946     if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
947         error_setg_errno(errp, errno, "xenevtchn_unbind failed");
948     }
949 
950     qemu_xen_evtchn_close(channel->xeh);
951     g_free(channel);
952 }
953 
954 static void xen_device_unrealize(DeviceState *dev)
955 {
956     XenDevice *xendev = XEN_DEVICE(dev);
957     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
958     const char *type = object_get_typename(OBJECT(xendev));
959     XenEventChannel *channel, *next;
960 
961     if (!xendev->name) {
962         return;
963     }
964 
965     trace_xen_device_unrealize(type, xendev->name);
966 
967     if (xendev->exit.notify) {
968         qemu_remove_exit_notifier(&xendev->exit);
969         xendev->exit.notify = NULL;
970     }
971 
972     if (xendev_class->unrealize) {
973         xendev_class->unrealize(xendev);
974     }
975 
976     /* Make sure all event channels are cleaned up */
977     QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
978         xen_device_unbind_event_channel(xendev, channel, NULL);
979     }
980 
981     xen_device_frontend_destroy(xendev);
982     xen_device_backend_destroy(xendev);
983 
984     if (xendev->xgth) {
985         qemu_xen_gnttab_close(xendev->xgth);
986         xendev->xgth = NULL;
987     }
988 
989     if (xendev->xsh) {
990         qemu_xen_xs_close(xendev->xsh);
991         xendev->xsh = NULL;
992     }
993 
994     g_free(xendev->name);
995     xendev->name = NULL;
996 }
997 
998 static void xen_device_exit(Notifier *n, void *data)
999 {
1000     XenDevice *xendev = container_of(n, XenDevice, exit);
1001 
1002     xen_device_unrealize(DEVICE(xendev));
1003 }
1004 
1005 static void xen_device_realize(DeviceState *dev, Error **errp)
1006 {
1007     ERRP_GUARD();
1008     XenDevice *xendev = XEN_DEVICE(dev);
1009     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
1010     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
1011     const char *type = object_get_typename(OBJECT(xendev));
1012 
1013     if (xendev->frontend_id == DOMID_INVALID) {
1014         xendev->frontend_id = xen_domid;
1015     }
1016 
1017     if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1018         error_setg(errp, "invalid frontend-id");
1019         goto unrealize;
1020     }
1021 
1022     if (!xendev_class->get_name) {
1023         error_setg(errp, "get_name method not implemented");
1024         goto unrealize;
1025     }
1026 
1027     xendev->name = xendev_class->get_name(xendev, errp);
1028     if (*errp) {
1029         error_prepend(errp, "failed to get device name: ");
1030         goto unrealize;
1031     }
1032 
1033     trace_xen_device_realize(type, xendev->name);
1034 
1035     xendev->xsh = qemu_xen_xs_open();
1036     if (!xendev->xsh) {
1037         error_setg_errno(errp, errno, "failed xs_open");
1038         goto unrealize;
1039     }
1040 
1041     xendev->xgth = qemu_xen_gnttab_open();
1042     if (!xendev->xgth) {
1043         error_setg_errno(errp, errno, "failed xengnttab_open");
1044         goto unrealize;
1045     }
1046 
1047     xen_device_backend_create(xendev, errp);
1048     if (*errp) {
1049         goto unrealize;
1050     }
1051 
1052     xen_device_frontend_create(xendev, errp);
1053     if (*errp) {
1054         goto unrealize;
1055     }
1056 
1057     xen_device_backend_printf(xendev, "frontend", "%s",
1058                               xendev->frontend_path);
1059     xen_device_backend_printf(xendev, "frontend-id", "%u",
1060                               xendev->frontend_id);
1061     xen_device_backend_printf(xendev, "hotplug-status", "connected");
1062 
1063     xen_device_backend_set_online(xendev, true);
1064     xen_device_backend_set_state(xendev, XenbusStateInitWait);
1065 
1066     if (!xen_device_frontend_exists(xendev)) {
1067         xen_device_frontend_printf(xendev, "backend", "%s",
1068                                    xendev->backend_path);
1069         xen_device_frontend_printf(xendev, "backend-id", "%u",
1070                                    xenbus->backend_id);
1071 
1072         xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1073     }
1074 
1075     if (xendev_class->realize) {
1076         xendev_class->realize(xendev, errp);
1077         if (*errp) {
1078             goto unrealize;
1079         }
1080     }
1081 
1082     xendev->exit.notify = xen_device_exit;
1083     qemu_add_exit_notifier(&xendev->exit);
1084     return;
1085 
1086 unrealize:
1087     xen_device_unrealize(dev);
1088 }
1089 
1090 static Property xen_device_props[] = {
1091     DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1092                        DOMID_INVALID),
1093     DEFINE_PROP_END_OF_LIST()
1094 };
1095 
1096 static void xen_device_class_init(ObjectClass *class, void *data)
1097 {
1098     DeviceClass *dev_class = DEVICE_CLASS(class);
1099 
1100     dev_class->realize = xen_device_realize;
1101     dev_class->unrealize = xen_device_unrealize;
1102     device_class_set_props(dev_class, xen_device_props);
1103     dev_class->bus_type = TYPE_XEN_BUS;
1104 }
1105 
1106 static const TypeInfo xen_device_type_info = {
1107     .name = TYPE_XEN_DEVICE,
1108     .parent = TYPE_DEVICE,
1109     .instance_size = sizeof(XenDevice),
1110     .abstract = true,
1111     .class_size = sizeof(XenDeviceClass),
1112     .class_init = xen_device_class_init,
1113 };
1114 
1115 typedef struct XenBridge {
1116     SysBusDevice busdev;
1117 } XenBridge;
1118 
1119 #define TYPE_XEN_BRIDGE "xen-bridge"
1120 
1121 static const TypeInfo xen_bridge_type_info = {
1122     .name = TYPE_XEN_BRIDGE,
1123     .parent = TYPE_SYS_BUS_DEVICE,
1124     .instance_size = sizeof(XenBridge),
1125 };
1126 
1127 static void xen_register_types(void)
1128 {
1129     type_register_static(&xen_bridge_type_info);
1130     type_register_static(&xen_bus_type_info);
1131     type_register_static(&xen_device_type_info);
1132 }
1133 
1134 type_init(xen_register_types)
1135 
1136 BusState *xen_bus_init(void)
1137 {
1138     DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1139     BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
1140 
1141     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1142     qbus_set_bus_hotplug_handler(bus);
1143 
1144     return bus;
1145 }
1146