]> git.proxmox.com Git - mirror_qemu.git/blob - hw/xen/xen-bus.c
slirp: Allow non-local DNS address when restrict is off
[mirror_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 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 }