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