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 "qobject/qdict.h"
22 #include "system/system.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 val = xs_node_read(xenbus->xsh, tid, NULL, NULL, "%s/%s", path, key[i]);
160 if (val) {
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 warn_reportf_err(local_err,
357 "failed to set up '%s' enumeration watch: ",
358 type[i]);
359 local_err = NULL;
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,const void * data)383 static void xen_bus_class_init(ObjectClass *class, const 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 = (const 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_read(XenDevice * xendev,const char * key)653 char *xen_device_frontend_read(XenDevice *xendev, const char *key)
654 {
655 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
656
657 g_assert(xenbus->xsh);
658
659 return xs_node_read(xenbus->xsh, XBT_NULL, NULL, NULL, "%s/%s",
660 xendev->frontend_path, key);
661 }
662
xen_device_frontend_set_state(XenDevice * xendev,enum xenbus_state state,bool publish)663 static void xen_device_frontend_set_state(XenDevice *xendev,
664 enum xenbus_state state,
665 bool publish)
666 {
667 const char *type = object_get_typename(OBJECT(xendev));
668
669 if (xendev->frontend_state == state) {
670 return;
671 }
672
673 trace_xen_device_frontend_state(type, xendev->name,
674 xs_strstate(state));
675
676 xendev->frontend_state = state;
677 if (publish) {
678 xen_device_frontend_printf(xendev, "state", "%u", state);
679 }
680 }
681
xen_device_frontend_changed(void * opaque,const char * path)682 static void xen_device_frontend_changed(void *opaque, const char *path)
683 {
684 XenDevice *xendev = opaque;
685 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
686 const char *type = object_get_typename(OBJECT(xendev));
687 enum xenbus_state state;
688
689 trace_xen_device_frontend_changed(type, xendev->name);
690
691 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) {
692 state = XenbusStateUnknown;
693 }
694
695 xen_device_frontend_set_state(xendev, state, false);
696
697 if (state == XenbusStateInitialising &&
698 xendev->backend_state == XenbusStateClosed &&
699 xendev->backend_online) {
700 /*
701 * The frontend is re-initializing so switch back to
702 * InitWait.
703 */
704 xen_device_backend_set_state(xendev, XenbusStateInitWait);
705 return;
706 }
707
708 if (xendev_class->frontend_changed) {
709 Error *local_err = NULL;
710
711 xendev_class->frontend_changed(xendev, state, &local_err);
712
713 if (local_err) {
714 error_reportf_err(local_err, "frontend change error: ");
715 }
716 }
717 }
718
xen_device_frontend_exists(XenDevice * xendev)719 static bool xen_device_frontend_exists(XenDevice *xendev)
720 {
721 enum xenbus_state state;
722
723 return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1);
724 }
725
xen_device_frontend_create(XenDevice * xendev,Error ** errp)726 static void xen_device_frontend_create(XenDevice *xendev, Error **errp)
727 {
728 ERRP_GUARD();
729 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
730 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
731
732 if (xendev_class->get_frontend_path) {
733 xendev->frontend_path = xendev_class->get_frontend_path(xendev, errp);
734 if (!xendev->frontend_path) {
735 error_prepend(errp, "failed to create frontend: ");
736 return;
737 }
738 } else {
739 xendev->frontend_path = xen_device_get_frontend_path(xendev);
740 }
741
742 /*
743 * The frontend area may have already been created by a legacy
744 * toolstack.
745 */
746 if (!xen_device_frontend_exists(xendev)) {
747 g_assert(xenbus->xsh);
748
749 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path,
750 xendev->frontend_id, xenbus->backend_id,
751 XS_PERM_READ | XS_PERM_WRITE, errp);
752 if (*errp) {
753 error_prepend(errp, "failed to create frontend: ");
754 return;
755 }
756 }
757
758 xendev->frontend_state_watch =
759 xs_node_watch(xendev->xsh, xendev->frontend_path, "state",
760 xen_device_frontend_changed, xendev, errp);
761 if (*errp) {
762 error_prepend(errp, "failed to watch frontend state: ");
763 }
764 }
765
xen_device_frontend_destroy(XenDevice * xendev)766 static void xen_device_frontend_destroy(XenDevice *xendev)
767 {
768 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
769 Error *local_err = NULL;
770
771 if (xendev->frontend_state_watch) {
772 xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch);
773 xendev->frontend_state_watch = NULL;
774 }
775
776 if (!xendev->frontend_path) {
777 return;
778 }
779
780 g_assert(xenbus->xsh);
781
782 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path,
783 &local_err);
784 g_free(xendev->frontend_path);
785 xendev->frontend_path = NULL;
786
787 if (local_err) {
788 error_report_err(local_err);
789 }
790 }
791
xen_device_set_max_grant_refs(XenDevice * xendev,unsigned int nr_refs,Error ** errp)792 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
793 Error **errp)
794 {
795 if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) {
796 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed");
797 }
798 }
799
xen_device_map_grant_refs(XenDevice * xendev,uint32_t * refs,unsigned int nr_refs,int prot,Error ** errp)800 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
801 unsigned int nr_refs, int prot,
802 Error **errp)
803 {
804 void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs,
805 xendev->frontend_id, refs, prot);
806
807 if (!map) {
808 error_setg_errno(errp, errno,
809 "xengnttab_map_domain_grant_refs failed");
810 }
811
812 return map;
813 }
814
xen_device_unmap_grant_refs(XenDevice * xendev,void * map,uint32_t * refs,unsigned int nr_refs,Error ** errp)815 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs,
816 unsigned int nr_refs, Error **errp)
817 {
818 if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) {
819 error_setg_errno(errp, errno, "xengnttab_unmap failed");
820 }
821 }
822
xen_device_copy_grant_refs(XenDevice * xendev,bool to_domain,XenDeviceGrantCopySegment segs[],unsigned int nr_segs,Error ** errp)823 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
824 XenDeviceGrantCopySegment segs[],
825 unsigned int nr_segs, Error **errp)
826 {
827 qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id,
828 (XenGrantCopySegment *)segs, nr_segs, errp);
829 }
830
831 struct XenEventChannel {
832 QLIST_ENTRY(XenEventChannel) list;
833 AioContext *ctx;
834 xenevtchn_handle *xeh;
835 evtchn_port_t local_port;
836 XenEventHandler handler;
837 void *opaque;
838 };
839
xen_device_poll(void * opaque)840 static bool xen_device_poll(void *opaque)
841 {
842 XenEventChannel *channel = opaque;
843
844 return channel->handler(channel->opaque);
845 }
846
xen_device_event(void * opaque)847 static void xen_device_event(void *opaque)
848 {
849 XenEventChannel *channel = opaque;
850 unsigned long port = qemu_xen_evtchn_pending(channel->xeh);
851
852 if (port == channel->local_port) {
853 xen_device_poll(channel);
854
855 qemu_xen_evtchn_unmask(channel->xeh, port);
856 }
857 }
858
xen_device_set_event_channel_context(XenDevice * xendev,XenEventChannel * channel,AioContext * ctx,Error ** errp)859 void xen_device_set_event_channel_context(XenDevice *xendev,
860 XenEventChannel *channel,
861 AioContext *ctx,
862 Error **errp)
863 {
864 if (!channel) {
865 error_setg(errp, "bad channel");
866 return;
867 }
868
869 if (channel->ctx)
870 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
871 NULL, NULL, NULL, NULL, NULL);
872
873 channel->ctx = ctx;
874 if (ctx) {
875 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
876 xen_device_event, NULL, xen_device_poll, NULL,
877 channel);
878 }
879 }
880
xen_device_bind_event_channel(XenDevice * xendev,unsigned int port,XenEventHandler handler,void * opaque,Error ** errp)881 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
882 unsigned int port,
883 XenEventHandler handler,
884 void *opaque, Error **errp)
885 {
886 XenEventChannel *channel = g_new0(XenEventChannel, 1);
887 xenevtchn_port_or_error_t local_port;
888
889 channel->xeh = qemu_xen_evtchn_open();
890 if (!channel->xeh) {
891 error_setg_errno(errp, errno, "failed xenevtchn_open");
892 goto fail;
893 }
894
895 local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh,
896 xendev->frontend_id,
897 port);
898 if (local_port < 0) {
899 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed");
900 goto fail;
901 }
902
903 channel->local_port = local_port;
904 channel->handler = handler;
905 channel->opaque = opaque;
906
907 /* Only reason for failure is a NULL channel */
908 xen_device_set_event_channel_context(xendev, channel,
909 qemu_get_aio_context(),
910 &error_abort);
911
912 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list);
913
914 return channel;
915
916 fail:
917 if (channel->xeh) {
918 qemu_xen_evtchn_close(channel->xeh);
919 }
920
921 g_free(channel);
922
923 return NULL;
924 }
925
xen_device_notify_event_channel(XenDevice * xendev,XenEventChannel * channel,Error ** errp)926 void xen_device_notify_event_channel(XenDevice *xendev,
927 XenEventChannel *channel,
928 Error **errp)
929 {
930 if (!channel) {
931 error_setg(errp, "bad channel");
932 return;
933 }
934
935 if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) {
936 error_setg_errno(errp, errno, "xenevtchn_notify failed");
937 }
938 }
939
xen_event_channel_get_local_port(XenEventChannel * channel)940 unsigned int xen_event_channel_get_local_port(XenEventChannel *channel)
941 {
942 return channel->local_port;
943 }
944
xen_device_unbind_event_channel(XenDevice * xendev,XenEventChannel * channel,Error ** errp)945 void xen_device_unbind_event_channel(XenDevice *xendev,
946 XenEventChannel *channel,
947 Error **errp)
948 {
949 if (!channel) {
950 error_setg(errp, "bad channel");
951 return;
952 }
953
954 QLIST_REMOVE(channel, list);
955
956 if (channel->ctx) {
957 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh),
958 NULL, NULL, NULL, NULL, NULL);
959 }
960
961 if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) {
962 error_setg_errno(errp, errno, "xenevtchn_unbind failed");
963 }
964
965 qemu_xen_evtchn_close(channel->xeh);
966 g_free(channel);
967 }
968
xen_device_unrealize(DeviceState * dev)969 static void xen_device_unrealize(DeviceState *dev)
970 {
971 XenDevice *xendev = XEN_DEVICE(dev);
972 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
973 const char *type = object_get_typename(OBJECT(xendev));
974 XenEventChannel *channel, *next;
975
976 if (!xendev->name) {
977 return;
978 }
979
980 trace_xen_device_unrealize(type, xendev->name);
981
982 if (xendev->exit.notify) {
983 qemu_remove_exit_notifier(&xendev->exit);
984 xendev->exit.notify = NULL;
985 }
986
987 if (xendev_class->unrealize) {
988 xendev_class->unrealize(xendev);
989 }
990
991 /* Make sure all event channels are cleaned up */
992 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) {
993 xen_device_unbind_event_channel(xendev, channel, NULL);
994 }
995
996 xen_device_frontend_destroy(xendev);
997 xen_device_backend_destroy(xendev);
998
999 if (xendev->xgth) {
1000 qemu_xen_gnttab_close(xendev->xgth);
1001 xendev->xgth = NULL;
1002 }
1003
1004 if (xendev->xsh) {
1005 qemu_xen_xs_close(xendev->xsh);
1006 xendev->xsh = NULL;
1007 }
1008
1009 g_free(xendev->name);
1010 xendev->name = NULL;
1011 }
1012
xen_device_exit(Notifier * n,void * data)1013 static void xen_device_exit(Notifier *n, void *data)
1014 {
1015 XenDevice *xendev = container_of(n, XenDevice, exit);
1016
1017 xen_device_unrealize(DEVICE(xendev));
1018 }
1019
xen_device_realize(DeviceState * dev,Error ** errp)1020 static void xen_device_realize(DeviceState *dev, Error **errp)
1021 {
1022 ERRP_GUARD();
1023 XenDevice *xendev = XEN_DEVICE(dev);
1024 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev);
1025 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
1026 const char *type = object_get_typename(OBJECT(xendev));
1027
1028 if (xendev->frontend_id == DOMID_INVALID) {
1029 xendev->frontend_id = xen_domid;
1030 }
1031
1032 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) {
1033 error_setg(errp, "invalid frontend-id");
1034 goto unrealize;
1035 }
1036
1037 if (!xendev_class->get_name) {
1038 error_setg(errp, "get_name method not implemented");
1039 goto unrealize;
1040 }
1041
1042 xendev->name = xendev_class->get_name(xendev, errp);
1043 if (*errp) {
1044 error_prepend(errp, "failed to get device name: ");
1045 goto unrealize;
1046 }
1047
1048 trace_xen_device_realize(type, xendev->name);
1049
1050 xendev->xsh = qemu_xen_xs_open();
1051 if (!xendev->xsh) {
1052 error_setg_errno(errp, errno, "failed xs_open");
1053 goto unrealize;
1054 }
1055
1056 xendev->xgth = qemu_xen_gnttab_open();
1057 if (!xendev->xgth) {
1058 error_setg_errno(errp, errno, "failed xengnttab_open");
1059 goto unrealize;
1060 }
1061
1062 xen_device_backend_create(xendev, errp);
1063 if (*errp) {
1064 goto unrealize;
1065 }
1066
1067 xen_device_frontend_create(xendev, errp);
1068 if (*errp) {
1069 goto unrealize;
1070 }
1071
1072 xen_device_backend_printf(xendev, "frontend", "%s",
1073 xendev->frontend_path);
1074 xen_device_backend_printf(xendev, "frontend-id", "%u",
1075 xendev->frontend_id);
1076 xen_device_backend_printf(xendev, "hotplug-status", "connected");
1077
1078 xen_device_backend_set_online(xendev, true);
1079 xen_device_backend_set_state(xendev, XenbusStateInitWait);
1080
1081 if (!xen_device_frontend_exists(xendev)) {
1082 xen_device_frontend_printf(xendev, "backend", "%s",
1083 xendev->backend_path);
1084 xen_device_frontend_printf(xendev, "backend-id", "%u",
1085 xenbus->backend_id);
1086
1087 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true);
1088 }
1089
1090 if (xendev_class->realize) {
1091 xendev_class->realize(xendev, errp);
1092 if (*errp) {
1093 goto unrealize;
1094 }
1095 }
1096
1097 xendev->exit.notify = xen_device_exit;
1098 qemu_add_exit_notifier(&xendev->exit);
1099 return;
1100
1101 unrealize:
1102 xen_device_unrealize(dev);
1103 }
1104
1105 static const Property xen_device_props[] = {
1106 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id,
1107 DOMID_INVALID),
1108 };
1109
xen_device_class_init(ObjectClass * class,const void * data)1110 static void xen_device_class_init(ObjectClass *class, const void *data)
1111 {
1112 DeviceClass *dev_class = DEVICE_CLASS(class);
1113
1114 dev_class->realize = xen_device_realize;
1115 dev_class->unrealize = xen_device_unrealize;
1116 device_class_set_props(dev_class, xen_device_props);
1117 dev_class->bus_type = TYPE_XEN_BUS;
1118 }
1119
1120 static const TypeInfo xen_device_type_info = {
1121 .name = TYPE_XEN_DEVICE,
1122 .parent = TYPE_DEVICE,
1123 .instance_size = sizeof(XenDevice),
1124 .abstract = true,
1125 .class_size = sizeof(XenDeviceClass),
1126 .class_init = xen_device_class_init,
1127 };
1128
1129 typedef struct XenBridge {
1130 SysBusDevice busdev;
1131 } XenBridge;
1132
1133 #define TYPE_XEN_BRIDGE "xen-bridge"
1134
1135 static const TypeInfo xen_bridge_type_info = {
1136 .name = TYPE_XEN_BRIDGE,
1137 .parent = TYPE_SYS_BUS_DEVICE,
1138 .instance_size = sizeof(XenBridge),
1139 };
1140
xen_register_types(void)1141 static void xen_register_types(void)
1142 {
1143 type_register_static(&xen_bridge_type_info);
1144 type_register_static(&xen_bus_type_info);
1145 type_register_static(&xen_device_type_info);
1146 }
1147
type_init(xen_register_types)1148 type_init(xen_register_types)
1149
1150 void xen_bus_init(void)
1151 {
1152 DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE);
1153 BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL);
1154
1155 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
1156 qbus_set_bus_hotplug_handler(bus);
1157
1158 qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device",
1159 "xen", "xen-net-device");
1160 }
1161