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