xref: /openbmc/qemu/hw/xen/xen-bus.c (revision e9206163)
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 "net/net.h"
23 #include "trace.h"
24 
25 static char *xen_device_get_backend_path(XenDevice *xendev)
26 {
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;
31 
32     if (!backend) {
33         backend = type;
34     }
35 
36     return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
37                            xenbus->backend_id, backend, xendev->frontend_id,
38                            xendev->name);
39 }
40 
41 static char *xen_device_get_frontend_path(XenDevice *xendev)
42 {
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;
46 
47     if (!device) {
48         device = type;
49     }
50 
51     return g_strdup_printf("/local/domain/%u/device/%s/%s",
52                            xendev->frontend_id, device, xendev->name);
53 }
54 
55 static void xen_device_unplug(XenDevice *xendev, Error **errp)
56 {
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;
61 
62     trace_xen_device_unplug(type, xendev->name);
63 
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;
70     }
71 
72     xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online",
73                    errp, "%u", 0);
74     if (*errp) {
75         goto abort;
76     }
77 
78     xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state",
79                    errp, "%u", XenbusStateClosing);
80     if (*errp) {
81         goto abort;
82     }
83 
84     if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
85         if (errno == EAGAIN) {
86             goto again;
87         }
88 
89         error_setg_errno(errp, errno, "failed xs_transaction_end");
90     }
91 
92     return;
93 
94 abort:
95     /*
96      * We only abort if there is already a failure so ignore any error
97      * from ending the transaction.
98      */
99     qemu_xen_xs_transaction_end(xenbus->xsh, tid, true);
100 }
101 
102 static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent)
103 {
104     XenDevice *xendev = XEN_DEVICE(dev);
105 
106     monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n",
107                    indent, "", xendev->name, xendev->frontend_id);
108 }
109 
110 static char *xen_bus_get_dev_path(DeviceState *dev)
111 {
112     return xen_device_get_backend_path(XEN_DEVICE(dev));
113 }
114 
115 static void xen_bus_backend_create(XenBus *xenbus, const char *type,
116                                    const char *name, char *path,
117                                    Error **errp)
118 {
119     ERRP_GUARD();
120     xs_transaction_t tid;
121     char **key;
122     QDict *opts;
123     unsigned int i, n;
124 
125     trace_xen_bus_backend_create(type, path);
126 
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;
132     }
133 
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");
138         }
139         return;
140     }
141 
142     opts = qdict_new();
143     for (i = 0; i < n; i++) {
144         char *val;
145 
146         /*
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.
150          */
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;
157 
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);
162         }
163     }
164 
165     free(key);
166 
167     if (!qemu_xen_xs_transaction_end(xenbus->xsh, tid, false)) {
168         qobject_unref(opts);
169 
170         if (errno == EAGAIN) {
171             goto again;
172         }
173 
174         error_setg_errno(errp, errno, "failed xs_transaction_end");
175         return;
176     }
177 
178     xen_backend_device_create(xenbus, type, name, opts, errp);
179     qobject_unref(opts);
180 
181     if (*errp) {
182         error_prepend(errp, "failed to create '%s' device '%s': ", type, name);
183     }
184 }
185 
186 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type)
187 {
188     char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid);
189     char **backend;
190     unsigned int i, n;
191 
192     trace_xen_bus_type_enumerate(type);
193 
194     backend = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n);
195     if (!backend) {
196         goto out;
197     }
198 
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;
204 
205         if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state",
206                           NULL, "%u", &state) != 1)
207             state = XenbusStateUnknown;
208 
209         if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online",
210                           NULL, "%u", &online) != 1)
211             online = 0;
212 
213         if (online && state == XenbusStateInitialising &&
214             !xen_backend_exists(type, backend[i])) {
215             Error *local_err = NULL;
216 
217             xen_bus_backend_create(xenbus, type, backend[i], backend_path,
218                                    &local_err);
219             if (local_err) {
220                 error_report_err(local_err);
221             }
222         }
223 
224         g_free(backend_path);
225     }
226 
227     free(backend);
228 
229 out:
230     g_free(domain_path);
231 }
232 
233 static void xen_bus_enumerate(XenBus *xenbus)
234 {
235     char **type;
236     unsigned int i, n;
237 
238     trace_xen_bus_enumerate();
239 
240     type = qemu_xen_xs_directory(xenbus->xsh, XBT_NULL, "backend", &n);
241     if (!type) {
242         return;
243     }
244 
245     for (i = 0; i < n; i++) {
246         xen_bus_type_enumerate(xenbus, type[i]);
247     }
248 
249     free(type);
250 }
251 
252 static void xen_bus_device_cleanup(XenDevice *xendev)
253 {
254     const char *type = object_get_typename(OBJECT(xendev));
255     Error *local_err = NULL;
256 
257     trace_xen_bus_device_cleanup(type, xendev->name);
258 
259     g_assert(!xendev->backend_online);
260 
261     if (!xen_backend_try_device_destroy(xendev, &local_err)) {
262         object_unparent(OBJECT(xendev));
263     }
264 
265     if (local_err) {
266         error_report_err(local_err);
267     }
268 }
269 
270 static void xen_bus_cleanup(XenBus *xenbus)
271 {
272     XenDevice *xendev, *next;
273 
274     trace_xen_bus_cleanup();
275 
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);
280     }
281 }
282 
283 static void xen_bus_backend_changed(void *opaque, const char *path)
284 {
285     XenBus *xenbus = opaque;
286 
287     xen_bus_enumerate(xenbus);
288     xen_bus_cleanup(xenbus);
289 }
290 
291 static void xen_bus_unrealize(BusState *bus)
292 {
293     XenBus *xenbus = XEN_BUS(bus);
294 
295     trace_xen_bus_unrealize();
296 
297     if (xenbus->backend_watch) {
298         unsigned int i;
299 
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]);
303             }
304         }
305 
306         g_free(xenbus->backend_watch);
307         xenbus->backend_watch = NULL;
308     }
309 
310     if (xenbus->xsh) {
311         qemu_xen_xs_close(xenbus->xsh);
312     }
313 }
314 
315 static void xen_bus_realize(BusState *bus, Error **errp)
316 {
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;
323 
324     trace_xen_bus_realize();
325 
326     xenbus->xsh = qemu_xen_xs_open();
327     if (!xenbus->xsh) {
328         error_setg_errno(errp, errno, "failed xs_open");
329         goto fail;
330     }
331 
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 */
337     }
338 
339     module_call_init(MODULE_INIT_XEN_BACKEND);
340 
341     type = xen_backend_get_types(&xenbus->backend_types);
342     xenbus->backend_watch = g_new(struct qemu_xs_watch *,
343                                   xenbus->backend_types);
344 
345     for (i = 0; i < xenbus->backend_types; i++) {
346         char *node = g_strdup_printf("backend/%s", type[i]);
347 
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]);
356         }
357 
358         g_free(node);
359     }
360 
361     g_free(type);
362     g_free(key);
363     return;
364 
365 fail:
366     xen_bus_unrealize(bus);
367     g_free(key);
368 }
369 
370 static void xen_bus_unplug_request(HotplugHandler *hotplug,
371                                    DeviceState *dev,
372                                    Error **errp)
373 {
374     XenDevice *xendev = XEN_DEVICE(dev);
375 
376     xen_device_unplug(xendev, errp);
377 }
378 
379 static void xen_bus_class_init(ObjectClass *class, void *data)
380 {
381     BusClass *bus_class = BUS_CLASS(class);
382     HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class);
383 
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;
388 
389     hotplug_class->unplug_request = xen_bus_unplug_request;
390 }
391 
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 },
400         { }
401     },
402 };
403 
404 void xen_device_backend_printf(XenDevice *xendev, const char *key,
405                                const char *fmt, ...)
406 {
407     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
408     Error *local_err = NULL;
409     va_list ap;
410 
411     g_assert(xenbus->xsh);
412 
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);
417 
418     if (local_err) {
419         error_report_err(local_err);
420     }
421 }
422 
423 G_GNUC_SCANF(3, 4)
424 static int xen_device_backend_scanf(XenDevice *xendev, const char *key,
425                                     const char *fmt, ...)
426 {
427     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
428     va_list ap;
429     int rc;
430 
431     g_assert(xenbus->xsh);
432 
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);
437 
438     return rc;
439 }
440 
441 void xen_device_backend_set_state(XenDevice *xendev,
442                                   enum xenbus_state state)
443 {
444     const char *type = object_get_typename(OBJECT(xendev));
445 
446     if (xendev->backend_state == state) {
447         return;
448     }
449 
450     trace_xen_device_backend_state(type, xendev->name,
451                                    xs_strstate(state));
452 
453     xendev->backend_state = state;
454     xen_device_backend_printf(xendev, "state", "%u", state);
455 }
456 
457 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev)
458 {
459     return xendev->backend_state;
460 }
461 
462 static void xen_device_backend_set_online(XenDevice *xendev, bool online)
463 {
464     const char *type = object_get_typename(OBJECT(xendev));
465 
466     if (xendev->backend_online == online) {
467         return;
468     }
469 
470     trace_xen_device_backend_online(type, xendev->name, online);
471 
472     xendev->backend_online = online;
473     xen_device_backend_printf(xendev, "online", "%u", online);
474 }
475 
476 /*
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.
479  */
480 static bool xen_device_frontend_is_active(XenDevice *xendev)
481 {
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;
490     }
491 }
492 
493 static void xen_device_backend_changed(void *opaque, const char *path)
494 {
495     XenDevice *xendev = opaque;
496     const char *type = object_get_typename(OBJECT(xendev));
497     enum xenbus_state state;
498     unsigned int online;
499 
500     trace_xen_device_backend_changed(type, xendev->name);
501 
502     if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) {
503         state = XenbusStateUnknown;
504     }
505 
506     xen_device_backend_set_state(xendev, state);
507 
508     if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) {
509         online = 0;
510     }
511 
512     xen_device_backend_set_online(xendev, !!online);
513 
514     /*
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.
518      */
519     if (state == XenbusStateClosing &&
520         !xen_device_frontend_is_active(xendev)) {
521         xen_device_backend_set_state(xendev, XenbusStateClosed);
522     }
523 
524     /*
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().
529      */
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)));
535 
536         xendev->inactive = true;
537         QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list);
538 
539         /*
540          * Re-write the state to cause a XenBus backend_watch notification,
541          * resulting in a call to xen_bus_cleanup().
542          */
543         xen_device_backend_printf(xendev, "state", "%u", state);
544     }
545 }
546 
547 static void xen_device_backend_create(XenDevice *xendev, Error **errp)
548 {
549     ERRP_GUARD();
550     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
551 
552     xendev->backend_path = xen_device_get_backend_path(xendev);
553 
554     g_assert(xenbus->xsh);
555 
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;
561     }
562 
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;
570     }
571 
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;
579     }
580 }
581 
582 static void xen_device_backend_destroy(XenDevice *xendev)
583 {
584     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
585     Error *local_err = NULL;
586 
587     if (xendev->backend_online_watch) {
588         xs_node_unwatch(xendev->xsh, xendev->backend_online_watch);
589         xendev->backend_online_watch = NULL;
590     }
591 
592     if (xendev->backend_state_watch) {
593         xs_node_unwatch(xendev->xsh, xendev->backend_state_watch);
594         xendev->backend_state_watch = NULL;
595     }
596 
597     if (!xendev->backend_path) {
598         return;
599     }
600 
601     g_assert(xenbus->xsh);
602 
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;
607 
608     if (local_err) {
609         error_report_err(local_err);
610     }
611 }
612 
613 void xen_device_frontend_printf(XenDevice *xendev, const char *key,
614                                 const char *fmt, ...)
615 {
616     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
617     Error *local_err = NULL;
618     va_list ap;
619 
620     g_assert(xenbus->xsh);
621 
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);
626 
627     if (local_err) {
628         error_report_err(local_err);
629     }
630 }
631 
632 int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
633                               const char *fmt, ...)
634 {
635     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
636     va_list ap;
637     int rc;
638 
639     g_assert(xenbus->xsh);
640 
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);
645 
646     return rc;
647 }
648 
649 static void xen_device_frontend_set_state(XenDevice *xendev,
650                                           enum xenbus_state state,
651                                           bool publish)
652 {
653     const char *type = object_get_typename(OBJECT(xendev));
654 
655     if (xendev->frontend_state == state) {
656         return;
657     }
658 
659     trace_xen_device_frontend_state(type, xendev->name,
660                                     xs_strstate(state));
661 
662     xendev->frontend_state = state;
663     if (publish) {
664         xen_device_frontend_printf(xendev, "state", "%u", state);
665     }
666 }
667 
668 static void xen_device_frontend_changed(void *opaque, const char *path)
669 {
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;
674 
675     trace_xen_device_frontend_changed(type, xendev->name);
676 
677     if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
678         state = XenbusStateUnknown;
679     }
680 
681     xen_device_frontend_set_state(xendev, state, false);
682 
683     if (state == XenbusStateInitialising &&
684         xendev->backend_state == XenbusStateClosed &&
685         xendev->backend_online) {
686         /*
687          * The frontend is re-initializing so switch back to
688          * InitWait.
689          */
690         xen_device_backend_set_state(xendev, XenbusStateInitWait);
691         return;
692     }
693 
694     if (xendev_class->frontend_changed) {
695         Error *local_err = NULL;
696 
697         xendev_class->frontend_changed(xendev, state, &local_err);
698 
699         if (local_err) {
700             error_reportf_err(local_err, "frontend change error: ");
701         }
702     }
703 }
704 
705 static bool xen_device_frontend_exists(XenDevice *xendev)
706 {
707     enum xenbus_state state;
708 
709     return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
710 }
711 
712 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
713 {
714     ERRP_GUARD();
715     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
716     XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
717 
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;
723         }
724     } else {
725         xendev->frontend_path = xen_device_get_frontend_path(xendev);
726     }
727 
728     /*
729      * The frontend area may have already been created by a legacy
730      * toolstack.
731      */
732     if (!xen_device_frontend_exists(xendev)) {
733         g_assert(xenbus->xsh);
734 
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;
741         }
742     }
743 
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: ");
749     }
750 }
751 
752 static void xen_device_frontend_destroy(XenDevice *xendev)
753 {
754     XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
755     Error *local_err = NULL;
756 
757     if (xendev->frontend_state_watch) {
758         xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
759         xendev->frontend_state_watch = NULL;
760     }
761 
762     if (!xendev->frontend_path) {
763         return;
764     }
765 
766     g_assert(xenbus->xsh);
767 
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;
772 
773     if (local_err) {
774         error_report_err(local_err);
775     }
776 }
777 
778 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
779                                    Error **errp)
780 {
781     if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
782         error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
783     }
784 }
785 
786 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
787                                 unsigned int nr_refs, int prot,
788                                 Error **errp)
789 {
790     void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
791                                          xendev->frontend_id, refs, prot);
792 
793     if (!map) {
794         error_setg_errno(errp, errno,
795                          "xengnttab_map_domain_grant_refs failed");
796     }
797 
798     return map;
799 }
800 
801 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
802                                  unsigned int nr_refs, Error **errp)
803 {
804     if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
805         error_setg_errno(errp, errno, "xengnttab_unmap failed");
806     }
807 }
808 
809 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
810                                 XenDeviceGrantCopySegment segs[],
811                                 unsigned int nr_segs, Error **errp)
812 {
813     qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
814                                (XenGrantCopySegment *)segs, nr_segs, errp);
815 }
816 
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;
824 };
825 
826 static bool xen_device_poll(void *opaque)
827 {
828     XenEventChannel *channel = opaque;
829 
830     return channel->handler(channel->opaque);
831 }
832 
833 static void xen_device_event(void *opaque)
834 {
835     XenEventChannel *channel = opaque;
836     unsigned long port = qemu_xen_evtchn_pending(channel->xeh);
837 
838     if (port == channel->local_port) {
839         xen_device_poll(channel);
840 
841         qemu_xen_evtchn_unmask(channel->xeh, port);
842     }
843 }
844 
845 void xen_device_set_event_channel_context(XenDevice *xendev,
846                                           XenEventChannel *channel,
847                                           AioContext *ctx,
848                                           Error **errp)
849 {
850     if (!channel) {
851         error_setg(errp, "bad channel");
852         return;
853     }
854 
855     if (channel->ctx)
856         aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
857                            NULL, NULL, NULL, NULL, NULL);
858 
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);
864     }
865 }
866 
867 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
868                                                unsigned int port,
869                                                XenEventHandler handler,
870                                                void *opaque, Error **errp)
871 {
872     XenEventChannel *channel = g_new0(XenEventChannel, 1);
873     xenevtchn_port_or_error_t local_port;
874 
875     channel->xeh = qemu_xen_evtchn_open();
876     if (!channel->xeh) {
877         error_setg_errno(errp, errno, "failed xenevtchn_open");
878         goto fail;
879     }
880 
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;
887     }
888 
889     channel->local_port = local_port;
890     channel->handler = handler;
891     channel->opaque = opaque;
892 
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);
897 
898     QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
899 
900     return channel;
901 
902 fail:
903     if (channel->xeh) {
904         qemu_xen_evtchn_close(channel->xeh);
905     }
906 
907     g_free(channel);
908 
909     return NULL;
910 }
911 
912 void xen_device_notify_event_channel(XenDevice *xendev,
913                                      XenEventChannel *channel,
914                                      Error **errp)
915 {
916     if (!channel) {
917         error_setg(errp, "bad channel");
918         return;
919     }
920 
921     if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
922         error_setg_errno(errp, errno, "xenevtchn_notify failed");
923     }
924 }
925 
926 unsigned int xen_event_channel_get_local_port(XenEventChannel *channel)
927 {
928     return channel->local_port;
929 }
930 
931 void xen_device_unbind_event_channel(XenDevice *xendev,
932                                      XenEventChannel *channel,
933                                      Error **errp)
934 {
935     if (!channel) {
936         error_setg(errp, "bad channel");
937         return;
938     }
939 
940     QLIST_REMOVE(channel, list);
941 
942     if (channel->ctx) {
943         aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
944                            NULL, NULL, NULL, NULL, NULL);
945     }
946 
947     if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
948         error_setg_errno(errp, errno, "xenevtchn_unbind failed");
949     }
950 
951     qemu_xen_evtchn_close(channel->xeh);
952     g_free(channel);
953 }
954 
955 static void xen_device_unrealize(DeviceState *dev)
956 {
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;
961 
962     if (!xendev->name) {
963         return;
964     }
965 
966     trace_xen_device_unrealize(type, xendev->name);
967 
968     if (xendev->exit.notify) {
969         qemu_remove_exit_notifier(&xendev->exit);
970         xendev->exit.notify = NULL;
971     }
972 
973     if (xendev_class->unrealize) {
974         xendev_class->unrealize(xendev);
975     }
976 
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);
980     }
981 
982     xen_device_frontend_destroy(xendev);
983     xen_device_backend_destroy(xendev);
984 
985     if (xendev->xgth) {
986         qemu_xen_gnttab_close(xendev->xgth);
987         xendev->xgth = NULL;
988     }
989 
990     if (xendev->xsh) {
991         qemu_xen_xs_close(xendev->xsh);
992         xendev->xsh = NULL;
993     }
994 
995     g_free(xendev->name);
996     xendev->name = NULL;
997 }
998 
999 static void xen_device_exit(Notifier *n, void *data)
1000 {
1001     XenDevice *xendev = container_of(n, XenDevice, exit);
1002 
1003     xen_device_unrealize(DEVICE(xendev));
1004 }
1005 
1006 static void xen_device_realize(DeviceState *dev, Error **errp)
1007 {
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));
1013 
1014     if (xendev->frontend_id == DOMID_INVALID) {
1015         xendev->frontend_id = xen_domid;
1016     }
1017 
1018     if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1019         error_setg(errp, "invalid frontend-id");
1020         goto unrealize;
1021     }
1022 
1023     if (!xendev_class->get_name) {
1024         error_setg(errp, "get_name method not implemented");
1025         goto unrealize;
1026     }
1027 
1028     xendev->name = xendev_class->get_name(xendev, errp);
1029     if (*errp) {
1030         error_prepend(errp, "failed to get device name: ");
1031         goto unrealize;
1032     }
1033 
1034     trace_xen_device_realize(type, xendev->name);
1035 
1036     xendev->xsh = qemu_xen_xs_open();
1037     if (!xendev->xsh) {
1038         error_setg_errno(errp, errno, "failed xs_open");
1039         goto unrealize;
1040     }
1041 
1042     xendev->xgth = qemu_xen_gnttab_open();
1043     if (!xendev->xgth) {
1044         error_setg_errno(errp, errno, "failed xengnttab_open");
1045         goto unrealize;
1046     }
1047 
1048     xen_device_backend_create(xendev, errp);
1049     if (*errp) {
1050         goto unrealize;
1051     }
1052 
1053     xen_device_frontend_create(xendev, errp);
1054     if (*errp) {
1055         goto unrealize;
1056     }
1057 
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");
1063 
1064     xen_device_backend_set_online(xendev, true);
1065     xen_device_backend_set_state(xendev, XenbusStateInitWait);
1066 
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);
1072 
1073         xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1074     }
1075 
1076     if (xendev_class->realize) {
1077         xendev_class->realize(xendev, errp);
1078         if (*errp) {
1079             goto unrealize;
1080         }
1081     }
1082 
1083     xendev->exit.notify = xen_device_exit;
1084     qemu_add_exit_notifier(&xendev->exit);
1085     return;
1086 
1087 unrealize:
1088     xen_device_unrealize(dev);
1089 }
1090 
1091 static Property xen_device_props[] = {
1092     DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1093                        DOMID_INVALID),
1094     DEFINE_PROP_END_OF_LIST()
1095 };
1096 
1097 static void xen_device_class_init(ObjectClass *class, void *data)
1098 {
1099     DeviceClass *dev_class = DEVICE_CLASS(class);
1100 
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;
1105 }
1106 
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,
1114 };
1115 
1116 typedef struct XenBridge {
1117     SysBusDevice busdev;
1118 } XenBridge;
1119 
1120 #define TYPE_XEN_BRIDGE "xen-bridge"
1121 
1122 static const TypeInfo xen_bridge_type_info = {
1123     .name = TYPE_XEN_BRIDGE,
1124     .parent = TYPE_SYS_BUS_DEVICE,
1125     .instance_size = sizeof(XenBridge),
1126 };
1127 
1128 static void xen_register_types(void)
1129 {
1130     type_register_static(&xen_bridge_type_info);
1131     type_register_static(&xen_bus_type_info);
1132     type_register_static(&xen_device_type_info);
1133 }
1134 
1135 type_init(xen_register_types)
1136 
1137 void xen_bus_init(void)
1138 {
1139     DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1140     BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
1141 
1142     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1143     qbus_set_bus_hotplug_handler(bus);
1144 
1145     qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device",
1146                                 "xen", "xen-net-device");
1147 }
1148