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