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