2 * Copyright (c) 2018 Citrix Systems Inc.
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.
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"
24 static char *xen_device_get_backend_path(XenDevice
*xendev
)
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
;
35 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
36 xenbus
->backend_id
, backend
, xendev
->frontend_id
,
40 static char *xen_device_get_frontend_path(XenDevice
*xendev
)
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
;
50 return g_strdup_printf("/local/domain/%u/device/%s/%s",
51 xendev
->frontend_id
, device
, xendev
->name
);
54 static void xen_device_unplug(XenDevice
*xendev
, Error
**errp
)
57 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
58 const char *type
= object_get_typename(OBJECT(xendev
));
61 trace_xen_device_unplug(type
, xendev
->name
);
63 /* Mimic the way the Xen toolstack does an unplug */
65 tid
= xs_transaction_start(xenbus
->xsh
);
66 if (tid
== XBT_NULL
) {
67 error_setg_errno(errp
, errno
, "failed xs_transaction_start");
71 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "online",
77 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "state",
78 errp
, "%u", XenbusStateClosing
);
83 if (!xs_transaction_end(xenbus
->xsh
, tid
, false)) {
84 if (errno
== EAGAIN
) {
88 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
95 * We only abort if there is already a failure so ignore any error
96 * from ending the transaction.
98 xs_transaction_end(xenbus
->xsh
, tid
, true);
101 static void xen_bus_print_dev(Monitor
*mon
, DeviceState
*dev
, int indent
)
103 XenDevice
*xendev
= XEN_DEVICE(dev
);
105 monitor_printf(mon
, "%*sname = '%s' frontend_id = %u\n",
106 indent
, "", xendev
->name
, xendev
->frontend_id
);
109 static char *xen_bus_get_dev_path(DeviceState
*dev
)
111 return xen_device_get_backend_path(XEN_DEVICE(dev
));
117 XenWatchHandler handler
;
122 static void watch_notify(Notifier
*n
, void *data
)
124 XenWatch
*watch
= container_of(n
, XenWatch
, notifier
);
125 const char *token
= data
;
127 if (!strcmp(watch
->token
, token
)) {
128 watch
->handler(watch
->opaque
);
132 static XenWatch
*new_watch(const char *node
, const char *key
,
133 XenWatchHandler handler
, void *opaque
)
135 XenWatch
*watch
= g_new0(XenWatch
, 1);
138 qemu_uuid_generate(&uuid
);
140 watch
->token
= qemu_uuid_unparse_strdup(&uuid
);
141 watch
->node
= g_strdup(node
);
142 watch
->key
= g_strdup(key
);
143 watch
->handler
= handler
;
144 watch
->opaque
= opaque
;
145 watch
->notifier
.notify
= watch_notify
;
150 static void free_watch(XenWatch
*watch
)
152 g_free(watch
->token
);
159 struct XenWatchList
{
160 struct xs_handle
*xsh
;
161 NotifierList notifiers
;
164 static void watch_list_event(void *opaque
)
166 XenWatchList
*watch_list
= opaque
;
170 v
= xs_check_watch(watch_list
->xsh
);
175 token
= v
[XS_WATCH_TOKEN
];
177 notifier_list_notify(&watch_list
->notifiers
, (void *)token
);
182 static XenWatchList
*watch_list_create(struct xs_handle
*xsh
)
184 XenWatchList
*watch_list
= g_new0(XenWatchList
, 1);
188 watch_list
->xsh
= xsh
;
189 notifier_list_init(&watch_list
->notifiers
);
190 qemu_set_fd_handler(xs_fileno(watch_list
->xsh
), watch_list_event
, NULL
,
196 static void watch_list_destroy(XenWatchList
*watch_list
)
198 g_assert(notifier_list_empty(&watch_list
->notifiers
));
199 qemu_set_fd_handler(xs_fileno(watch_list
->xsh
), NULL
, NULL
, NULL
);
203 static XenWatch
*watch_list_add(XenWatchList
*watch_list
, const char *node
,
204 const char *key
, XenWatchHandler handler
,
205 void *opaque
, Error
**errp
)
208 XenWatch
*watch
= new_watch(node
, key
, handler
, opaque
);
210 notifier_list_add(&watch_list
->notifiers
, &watch
->notifier
);
212 xs_node_watch(watch_list
->xsh
, node
, key
, watch
->token
, errp
);
214 notifier_remove(&watch
->notifier
);
223 static void watch_list_remove(XenWatchList
*watch_list
, XenWatch
*watch
,
226 xs_node_unwatch(watch_list
->xsh
, watch
->node
, watch
->key
, watch
->token
,
229 notifier_remove(&watch
->notifier
);
233 static XenWatch
*xen_bus_add_watch(XenBus
*xenbus
, const char *node
,
234 const char *key
, XenWatchHandler handler
,
237 trace_xen_bus_add_watch(node
, key
);
239 return watch_list_add(xenbus
->watch_list
, node
, key
, handler
, xenbus
,
243 static void xen_bus_remove_watch(XenBus
*xenbus
, XenWatch
*watch
,
246 trace_xen_bus_remove_watch(watch
->node
, watch
->key
);
248 watch_list_remove(xenbus
->watch_list
, watch
, errp
);
251 static void xen_bus_backend_create(XenBus
*xenbus
, const char *type
,
252 const char *name
, char *path
,
256 xs_transaction_t tid
;
261 trace_xen_bus_backend_create(type
, path
);
264 tid
= xs_transaction_start(xenbus
->xsh
);
265 if (tid
== XBT_NULL
) {
266 error_setg(errp
, "failed xs_transaction_start");
270 key
= xs_directory(xenbus
->xsh
, tid
, path
, &n
);
272 if (!xs_transaction_end(xenbus
->xsh
, tid
, true)) {
273 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
279 for (i
= 0; i
< n
; i
++) {
283 * Assume anything found in the xenstore backend area, other than
284 * the keys created for a generic XenDevice, are parameters
285 * to be used to configure the backend.
287 if (!strcmp(key
[i
], "state") ||
288 !strcmp(key
[i
], "online") ||
289 !strcmp(key
[i
], "frontend") ||
290 !strcmp(key
[i
], "frontend-id") ||
291 !strcmp(key
[i
], "hotplug-status"))
294 if (xs_node_scanf(xenbus
->xsh
, tid
, path
, key
[i
], NULL
, "%ms",
296 qdict_put_str(opts
, key
[i
], val
);
303 if (!xs_transaction_end(xenbus
->xsh
, tid
, false)) {
306 if (errno
== EAGAIN
) {
310 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
314 xen_backend_device_create(xenbus
, type
, name
, opts
, errp
);
318 error_prepend(errp
, "failed to create '%s' device '%s': ", type
, name
);
322 static void xen_bus_type_enumerate(XenBus
*xenbus
, const char *type
)
324 char *domain_path
= g_strdup_printf("backend/%s/%u", type
, xen_domid
);
328 trace_xen_bus_type_enumerate(type
);
330 backend
= xs_directory(xenbus
->xsh
, XBT_NULL
, domain_path
, &n
);
335 for (i
= 0; i
< n
; i
++) {
336 char *backend_path
= g_strdup_printf("%s/%s", domain_path
,
338 enum xenbus_state state
;
341 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "state",
342 NULL
, "%u", &state
) != 1)
343 state
= XenbusStateUnknown
;
345 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "online",
346 NULL
, "%u", &online
) != 1)
349 if (online
&& state
== XenbusStateInitialising
) {
350 Error
*local_err
= NULL
;
352 xen_bus_backend_create(xenbus
, type
, backend
[i
], backend_path
,
355 error_report_err(local_err
);
359 g_free(backend_path
);
368 static void xen_bus_enumerate(XenBus
*xenbus
)
373 trace_xen_bus_enumerate();
375 type
= xs_directory(xenbus
->xsh
, XBT_NULL
, "backend", &n
);
380 for (i
= 0; i
< n
; i
++) {
381 xen_bus_type_enumerate(xenbus
, type
[i
]);
387 static void xen_bus_device_cleanup(XenDevice
*xendev
)
389 const char *type
= object_get_typename(OBJECT(xendev
));
390 Error
*local_err
= NULL
;
392 trace_xen_bus_device_cleanup(type
, xendev
->name
);
394 g_assert(!xendev
->backend_online
);
396 if (!xen_backend_try_device_destroy(xendev
, &local_err
)) {
397 object_unparent(OBJECT(xendev
));
401 error_report_err(local_err
);
405 static void xen_bus_cleanup(XenBus
*xenbus
)
407 XenDevice
*xendev
, *next
;
409 trace_xen_bus_cleanup();
411 QLIST_FOREACH_SAFE(xendev
, &xenbus
->inactive_devices
, list
, next
) {
412 g_assert(xendev
->inactive
);
413 QLIST_REMOVE(xendev
, list
);
414 xen_bus_device_cleanup(xendev
);
418 static void xen_bus_backend_changed(void *opaque
)
420 XenBus
*xenbus
= opaque
;
422 xen_bus_enumerate(xenbus
);
423 xen_bus_cleanup(xenbus
);
426 static void xen_bus_unrealize(BusState
*bus
)
428 XenBus
*xenbus
= XEN_BUS(bus
);
430 trace_xen_bus_unrealize();
432 if (xenbus
->backend_watch
) {
435 for (i
= 0; i
< xenbus
->backend_types
; i
++) {
436 if (xenbus
->backend_watch
[i
]) {
437 xen_bus_remove_watch(xenbus
, xenbus
->backend_watch
[i
], NULL
);
441 g_free(xenbus
->backend_watch
);
442 xenbus
->backend_watch
= NULL
;
445 if (xenbus
->watch_list
) {
446 watch_list_destroy(xenbus
->watch_list
);
447 xenbus
->watch_list
= NULL
;
451 xs_close(xenbus
->xsh
);
455 static void xen_bus_realize(BusState
*bus
, Error
**errp
)
457 char *key
= g_strdup_printf("%u", xen_domid
);
458 XenBus
*xenbus
= XEN_BUS(bus
);
462 Error
*local_err
= NULL
;
464 trace_xen_bus_realize();
466 xenbus
->xsh
= xs_open(0);
468 error_setg_errno(errp
, errno
, "failed xs_open");
472 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, "", /* domain root node */
473 "domid", NULL
, "%u", &domid
) == 1) {
474 xenbus
->backend_id
= domid
;
476 xenbus
->backend_id
= 0; /* Assume lack of node means dom0 */
479 xenbus
->watch_list
= watch_list_create(xenbus
->xsh
);
481 module_call_init(MODULE_INIT_XEN_BACKEND
);
483 type
= xen_backend_get_types(&xenbus
->backend_types
);
484 xenbus
->backend_watch
= g_new(XenWatch
*, xenbus
->backend_types
);
486 for (i
= 0; i
< xenbus
->backend_types
; i
++) {
487 char *node
= g_strdup_printf("backend/%s", type
[i
]);
489 xenbus
->backend_watch
[i
] =
490 xen_bus_add_watch(xenbus
, node
, key
, xen_bus_backend_changed
,
493 /* This need not be treated as a hard error so don't propagate */
494 error_reportf_err(local_err
,
495 "failed to set up '%s' enumeration watch: ",
507 xen_bus_unrealize(bus
);
511 static void xen_bus_unplug_request(HotplugHandler
*hotplug
,
515 XenDevice
*xendev
= XEN_DEVICE(dev
);
517 xen_device_unplug(xendev
, errp
);
520 static void xen_bus_class_init(ObjectClass
*class, void *data
)
522 BusClass
*bus_class
= BUS_CLASS(class);
523 HotplugHandlerClass
*hotplug_class
= HOTPLUG_HANDLER_CLASS(class);
525 bus_class
->print_dev
= xen_bus_print_dev
;
526 bus_class
->get_dev_path
= xen_bus_get_dev_path
;
527 bus_class
->realize
= xen_bus_realize
;
528 bus_class
->unrealize
= xen_bus_unrealize
;
530 hotplug_class
->unplug_request
= xen_bus_unplug_request
;
533 static const TypeInfo xen_bus_type_info
= {
534 .name
= TYPE_XEN_BUS
,
536 .instance_size
= sizeof(XenBus
),
537 .class_size
= sizeof(XenBusClass
),
538 .class_init
= xen_bus_class_init
,
539 .interfaces
= (InterfaceInfo
[]) {
540 { TYPE_HOTPLUG_HANDLER
},
545 void xen_device_backend_printf(XenDevice
*xendev
, const char *key
,
546 const char *fmt
, ...)
548 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
549 Error
*local_err
= NULL
;
552 g_assert(xenbus
->xsh
);
555 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
556 &local_err
, fmt
, ap
);
560 error_report_err(local_err
);
565 static int xen_device_backend_scanf(XenDevice
*xendev
, const char *key
,
566 const char *fmt
, ...)
568 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
572 g_assert(xenbus
->xsh
);
575 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
582 void xen_device_backend_set_state(XenDevice
*xendev
,
583 enum xenbus_state state
)
585 const char *type
= object_get_typename(OBJECT(xendev
));
587 if (xendev
->backend_state
== state
) {
591 trace_xen_device_backend_state(type
, xendev
->name
,
594 xendev
->backend_state
= state
;
595 xen_device_backend_printf(xendev
, "state", "%u", state
);
598 enum xenbus_state
xen_device_backend_get_state(XenDevice
*xendev
)
600 return xendev
->backend_state
;
603 static void xen_device_backend_set_online(XenDevice
*xendev
, bool online
)
605 const char *type
= object_get_typename(OBJECT(xendev
));
607 if (xendev
->backend_online
== online
) {
611 trace_xen_device_backend_online(type
, xendev
->name
, online
);
613 xendev
->backend_online
= online
;
614 xen_device_backend_printf(xendev
, "online", "%u", online
);
618 * Tell from the state whether the frontend is likely alive,
619 * i.e. it will react to a change of state of the backend.
621 static bool xen_device_frontend_is_active(XenDevice
*xendev
)
623 switch (xendev
->frontend_state
) {
624 case XenbusStateInitWait
:
625 case XenbusStateInitialised
:
626 case XenbusStateConnected
:
627 case XenbusStateClosing
:
634 static void xen_device_backend_changed(void *opaque
)
636 XenDevice
*xendev
= opaque
;
637 const char *type
= object_get_typename(OBJECT(xendev
));
638 enum xenbus_state state
;
641 trace_xen_device_backend_changed(type
, xendev
->name
);
643 if (xen_device_backend_scanf(xendev
, "state", "%u", &state
) != 1) {
644 state
= XenbusStateUnknown
;
647 xen_device_backend_set_state(xendev
, state
);
649 if (xen_device_backend_scanf(xendev
, "online", "%u", &online
) != 1) {
653 xen_device_backend_set_online(xendev
, !!online
);
656 * If the toolstack (or unplug request callback) has set the backend
657 * state to Closing, but there is no active frontend then set the
658 * backend state to Closed.
660 if (state
== XenbusStateClosing
&&
661 !xen_device_frontend_is_active(xendev
)) {
662 xen_device_backend_set_state(xendev
, XenbusStateClosed
);
666 * If a backend is still 'online' then we should leave it alone but,
667 * if a backend is not 'online', then the device is a candidate
668 * for destruction. Hence add it to the 'inactive' list to be cleaned
669 * by xen_bus_cleanup().
672 (state
== XenbusStateClosed
|| state
== XenbusStateInitialising
||
673 state
== XenbusStateInitWait
|| state
== XenbusStateUnknown
) &&
675 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
677 xendev
->inactive
= true;
678 QLIST_INSERT_HEAD(&xenbus
->inactive_devices
, xendev
, list
);
681 * Re-write the state to cause a XenBus backend_watch notification,
682 * resulting in a call to xen_bus_cleanup().
684 xen_device_backend_printf(xendev
, "state", "%u", state
);
688 static XenWatch
*xen_device_add_watch(XenDevice
*xendev
, const char *node
,
690 XenWatchHandler handler
,
693 const char *type
= object_get_typename(OBJECT(xendev
));
695 trace_xen_device_add_watch(type
, xendev
->name
, node
, key
);
697 return watch_list_add(xendev
->watch_list
, node
, key
, handler
, xendev
,
701 static void xen_device_remove_watch(XenDevice
*xendev
, XenWatch
*watch
,
704 const char *type
= object_get_typename(OBJECT(xendev
));
706 trace_xen_device_remove_watch(type
, xendev
->name
, watch
->node
,
709 watch_list_remove(xendev
->watch_list
, watch
, errp
);
713 static void xen_device_backend_create(XenDevice
*xendev
, Error
**errp
)
716 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
717 struct xs_permissions perms
[2];
719 xendev
->backend_path
= xen_device_get_backend_path(xendev
);
721 perms
[0].id
= xenbus
->backend_id
;
722 perms
[0].perms
= XS_PERM_NONE
;
723 perms
[1].id
= xendev
->frontend_id
;
724 perms
[1].perms
= XS_PERM_READ
;
726 g_assert(xenbus
->xsh
);
728 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, perms
,
729 ARRAY_SIZE(perms
), errp
);
731 error_prepend(errp
, "failed to create backend: ");
735 xendev
->backend_state_watch
=
736 xen_device_add_watch(xendev
, xendev
->backend_path
,
737 "state", xen_device_backend_changed
,
740 error_prepend(errp
, "failed to watch backend state: ");
744 xendev
->backend_online_watch
=
745 xen_device_add_watch(xendev
, xendev
->backend_path
,
746 "online", xen_device_backend_changed
,
749 error_prepend(errp
, "failed to watch backend online: ");
754 static void xen_device_backend_destroy(XenDevice
*xendev
)
756 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
757 Error
*local_err
= NULL
;
759 if (xendev
->backend_online_watch
) {
760 xen_device_remove_watch(xendev
, xendev
->backend_online_watch
, NULL
);
761 xendev
->backend_online_watch
= NULL
;
764 if (xendev
->backend_state_watch
) {
765 xen_device_remove_watch(xendev
, xendev
->backend_state_watch
, NULL
);
766 xendev
->backend_state_watch
= NULL
;
769 if (!xendev
->backend_path
) {
773 g_assert(xenbus
->xsh
);
775 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
777 g_free(xendev
->backend_path
);
778 xendev
->backend_path
= NULL
;
781 error_report_err(local_err
);
785 void xen_device_frontend_printf(XenDevice
*xendev
, const char *key
,
786 const char *fmt
, ...)
788 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
789 Error
*local_err
= NULL
;
792 g_assert(xenbus
->xsh
);
795 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
796 &local_err
, fmt
, ap
);
800 error_report_err(local_err
);
804 int xen_device_frontend_scanf(XenDevice
*xendev
, const char *key
,
805 const char *fmt
, ...)
807 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
811 g_assert(xenbus
->xsh
);
814 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
821 static void xen_device_frontend_set_state(XenDevice
*xendev
,
822 enum xenbus_state state
,
825 const char *type
= object_get_typename(OBJECT(xendev
));
827 if (xendev
->frontend_state
== state
) {
831 trace_xen_device_frontend_state(type
, xendev
->name
,
834 xendev
->frontend_state
= state
;
836 xen_device_frontend_printf(xendev
, "state", "%u", state
);
840 static void xen_device_frontend_changed(void *opaque
)
842 XenDevice
*xendev
= opaque
;
843 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
844 const char *type
= object_get_typename(OBJECT(xendev
));
845 enum xenbus_state state
;
847 trace_xen_device_frontend_changed(type
, xendev
->name
);
849 if (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) != 1) {
850 state
= XenbusStateUnknown
;
853 xen_device_frontend_set_state(xendev
, state
, false);
855 if (state
== XenbusStateInitialising
&&
856 xendev
->backend_state
== XenbusStateClosed
&&
857 xendev
->backend_online
) {
859 * The frontend is re-initializing so switch back to
862 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
866 if (xendev_class
->frontend_changed
) {
867 Error
*local_err
= NULL
;
869 xendev_class
->frontend_changed(xendev
, state
, &local_err
);
872 error_reportf_err(local_err
, "frontend change error: ");
877 static bool xen_device_frontend_exists(XenDevice
*xendev
)
879 enum xenbus_state state
;
881 return (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) == 1);
884 static void xen_device_frontend_create(XenDevice
*xendev
, Error
**errp
)
887 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
888 struct xs_permissions perms
[2];
890 xendev
->frontend_path
= xen_device_get_frontend_path(xendev
);
893 * The frontend area may have already been created by a legacy
896 if (!xen_device_frontend_exists(xendev
)) {
897 perms
[0].id
= xendev
->frontend_id
;
898 perms
[0].perms
= XS_PERM_NONE
;
899 perms
[1].id
= xenbus
->backend_id
;
900 perms
[1].perms
= XS_PERM_READ
| XS_PERM_WRITE
;
902 g_assert(xenbus
->xsh
);
904 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, perms
,
905 ARRAY_SIZE(perms
), errp
);
907 error_prepend(errp
, "failed to create frontend: ");
912 xendev
->frontend_state_watch
=
913 xen_device_add_watch(xendev
, xendev
->frontend_path
, "state",
914 xen_device_frontend_changed
, errp
);
916 error_prepend(errp
, "failed to watch frontend state: ");
920 static void xen_device_frontend_destroy(XenDevice
*xendev
)
922 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
923 Error
*local_err
= NULL
;
925 if (xendev
->frontend_state_watch
) {
926 xen_device_remove_watch(xendev
, xendev
->frontend_state_watch
,
928 xendev
->frontend_state_watch
= NULL
;
931 if (!xendev
->frontend_path
) {
935 g_assert(xenbus
->xsh
);
937 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
,
939 g_free(xendev
->frontend_path
);
940 xendev
->frontend_path
= NULL
;
943 error_report_err(local_err
);
947 void xen_device_set_max_grant_refs(XenDevice
*xendev
, unsigned int nr_refs
,
950 if (xengnttab_set_max_grants(xendev
->xgth
, nr_refs
)) {
951 error_setg_errno(errp
, errno
, "xengnttab_set_max_grants failed");
955 void *xen_device_map_grant_refs(XenDevice
*xendev
, uint32_t *refs
,
956 unsigned int nr_refs
, int prot
,
959 void *map
= xengnttab_map_domain_grant_refs(xendev
->xgth
, nr_refs
,
960 xendev
->frontend_id
, refs
,
964 error_setg_errno(errp
, errno
,
965 "xengnttab_map_domain_grant_refs failed");
971 void xen_device_unmap_grant_refs(XenDevice
*xendev
, void *map
,
972 unsigned int nr_refs
, Error
**errp
)
974 if (xengnttab_unmap(xendev
->xgth
, map
, nr_refs
)) {
975 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
979 static void compat_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
980 XenDeviceGrantCopySegment segs
[],
981 unsigned int nr_segs
, Error
**errp
)
983 uint32_t *refs
= g_new(uint32_t, nr_segs
);
984 int prot
= to_domain
? PROT_WRITE
: PROT_READ
;
988 for (i
= 0; i
< nr_segs
; i
++) {
989 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
991 refs
[i
] = to_domain
? seg
->dest
.foreign
.ref
:
992 seg
->source
.foreign
.ref
;
995 map
= xengnttab_map_domain_grant_refs(xendev
->xgth
, nr_segs
,
996 xendev
->frontend_id
, refs
,
999 error_setg_errno(errp
, errno
,
1000 "xengnttab_map_domain_grant_refs failed");
1004 for (i
= 0; i
< nr_segs
; i
++) {
1005 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
1006 void *page
= map
+ (i
* XC_PAGE_SIZE
);
1009 memcpy(page
+ seg
->dest
.foreign
.offset
, seg
->source
.virt
,
1012 memcpy(seg
->dest
.virt
, page
+ seg
->source
.foreign
.offset
,
1017 if (xengnttab_unmap(xendev
->xgth
, map
, nr_segs
)) {
1018 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
1025 void xen_device_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
1026 XenDeviceGrantCopySegment segs
[],
1027 unsigned int nr_segs
, Error
**errp
)
1029 xengnttab_grant_copy_segment_t
*xengnttab_segs
;
1032 if (!xendev
->feature_grant_copy
) {
1033 compat_copy_grant_refs(xendev
, to_domain
, segs
, nr_segs
, errp
);
1037 xengnttab_segs
= g_new0(xengnttab_grant_copy_segment_t
, nr_segs
);
1039 for (i
= 0; i
< nr_segs
; i
++) {
1040 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
1041 xengnttab_grant_copy_segment_t
*xengnttab_seg
= &xengnttab_segs
[i
];
1044 xengnttab_seg
->flags
= GNTCOPY_dest_gref
;
1045 xengnttab_seg
->dest
.foreign
.domid
= xendev
->frontend_id
;
1046 xengnttab_seg
->dest
.foreign
.ref
= seg
->dest
.foreign
.ref
;
1047 xengnttab_seg
->dest
.foreign
.offset
= seg
->dest
.foreign
.offset
;
1048 xengnttab_seg
->source
.virt
= seg
->source
.virt
;
1050 xengnttab_seg
->flags
= GNTCOPY_source_gref
;
1051 xengnttab_seg
->source
.foreign
.domid
= xendev
->frontend_id
;
1052 xengnttab_seg
->source
.foreign
.ref
= seg
->source
.foreign
.ref
;
1053 xengnttab_seg
->source
.foreign
.offset
=
1054 seg
->source
.foreign
.offset
;
1055 xengnttab_seg
->dest
.virt
= seg
->dest
.virt
;
1058 xengnttab_seg
->len
= seg
->len
;
1061 if (xengnttab_grant_copy(xendev
->xgth
, nr_segs
, xengnttab_segs
)) {
1062 error_setg_errno(errp
, errno
, "xengnttab_grant_copy failed");
1066 for (i
= 0; i
< nr_segs
; i
++) {
1067 xengnttab_grant_copy_segment_t
*xengnttab_seg
= &xengnttab_segs
[i
];
1069 if (xengnttab_seg
->status
!= GNTST_okay
) {
1070 error_setg(errp
, "xengnttab_grant_copy seg[%u] failed", i
);
1076 g_free(xengnttab_segs
);
1079 struct XenEventChannel
{
1080 QLIST_ENTRY(XenEventChannel
) list
;
1082 xenevtchn_handle
*xeh
;
1083 evtchn_port_t local_port
;
1084 XenEventHandler handler
;
1088 static bool xen_device_poll(void *opaque
)
1090 XenEventChannel
*channel
= opaque
;
1092 return channel
->handler(channel
->opaque
);
1095 static void xen_device_event(void *opaque
)
1097 XenEventChannel
*channel
= opaque
;
1098 unsigned long port
= xenevtchn_pending(channel
->xeh
);
1100 if (port
== channel
->local_port
) {
1101 xen_device_poll(channel
);
1103 xenevtchn_unmask(channel
->xeh
, port
);
1107 void xen_device_set_event_channel_context(XenDevice
*xendev
,
1108 XenEventChannel
*channel
,
1113 error_setg(errp
, "bad channel");
1118 aio_set_fd_handler(channel
->ctx
, xenevtchn_fd(channel
->xeh
), true,
1119 NULL
, NULL
, NULL
, NULL
, NULL
);
1122 aio_set_fd_handler(channel
->ctx
, xenevtchn_fd(channel
->xeh
), true,
1123 xen_device_event
, NULL
, xen_device_poll
, NULL
, channel
);
1126 XenEventChannel
*xen_device_bind_event_channel(XenDevice
*xendev
,
1128 XenEventHandler handler
,
1129 void *opaque
, Error
**errp
)
1131 XenEventChannel
*channel
= g_new0(XenEventChannel
, 1);
1132 xenevtchn_port_or_error_t local_port
;
1134 channel
->xeh
= xenevtchn_open(NULL
, 0);
1135 if (!channel
->xeh
) {
1136 error_setg_errno(errp
, errno
, "failed xenevtchn_open");
1140 local_port
= xenevtchn_bind_interdomain(channel
->xeh
,
1141 xendev
->frontend_id
,
1143 if (local_port
< 0) {
1144 error_setg_errno(errp
, errno
, "xenevtchn_bind_interdomain failed");
1148 channel
->local_port
= local_port
;
1149 channel
->handler
= handler
;
1150 channel
->opaque
= opaque
;
1152 /* Only reason for failure is a NULL channel */
1153 xen_device_set_event_channel_context(xendev
, channel
,
1154 qemu_get_aio_context(),
1157 QLIST_INSERT_HEAD(&xendev
->event_channels
, channel
, list
);
1163 xenevtchn_close(channel
->xeh
);
1171 void xen_device_notify_event_channel(XenDevice
*xendev
,
1172 XenEventChannel
*channel
,
1176 error_setg(errp
, "bad channel");
1180 if (xenevtchn_notify(channel
->xeh
, channel
->local_port
) < 0) {
1181 error_setg_errno(errp
, errno
, "xenevtchn_notify failed");
1185 void xen_device_unbind_event_channel(XenDevice
*xendev
,
1186 XenEventChannel
*channel
,
1190 error_setg(errp
, "bad channel");
1194 QLIST_REMOVE(channel
, list
);
1196 aio_set_fd_handler(channel
->ctx
, xenevtchn_fd(channel
->xeh
), true,
1197 NULL
, NULL
, NULL
, NULL
, NULL
);
1199 if (xenevtchn_unbind(channel
->xeh
, channel
->local_port
) < 0) {
1200 error_setg_errno(errp
, errno
, "xenevtchn_unbind failed");
1203 xenevtchn_close(channel
->xeh
);
1207 static void xen_device_unrealize(DeviceState
*dev
)
1209 XenDevice
*xendev
= XEN_DEVICE(dev
);
1210 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1211 const char *type
= object_get_typename(OBJECT(xendev
));
1212 XenEventChannel
*channel
, *next
;
1214 if (!xendev
->name
) {
1218 trace_xen_device_unrealize(type
, xendev
->name
);
1220 if (xendev
->exit
.notify
) {
1221 qemu_remove_exit_notifier(&xendev
->exit
);
1222 xendev
->exit
.notify
= NULL
;
1225 if (xendev_class
->unrealize
) {
1226 xendev_class
->unrealize(xendev
);
1229 /* Make sure all event channels are cleaned up */
1230 QLIST_FOREACH_SAFE(channel
, &xendev
->event_channels
, list
, next
) {
1231 xen_device_unbind_event_channel(xendev
, channel
, NULL
);
1234 xen_device_frontend_destroy(xendev
);
1235 xen_device_backend_destroy(xendev
);
1238 xengnttab_close(xendev
->xgth
);
1239 xendev
->xgth
= NULL
;
1242 if (xendev
->watch_list
) {
1243 watch_list_destroy(xendev
->watch_list
);
1244 xendev
->watch_list
= NULL
;
1248 xs_close(xendev
->xsh
);
1252 g_free(xendev
->name
);
1253 xendev
->name
= NULL
;
1256 static void xen_device_exit(Notifier
*n
, void *data
)
1258 XenDevice
*xendev
= container_of(n
, XenDevice
, exit
);
1260 xen_device_unrealize(DEVICE(xendev
));
1263 static void xen_device_realize(DeviceState
*dev
, Error
**errp
)
1266 XenDevice
*xendev
= XEN_DEVICE(dev
);
1267 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1268 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
1269 const char *type
= object_get_typename(OBJECT(xendev
));
1271 if (xendev
->frontend_id
== DOMID_INVALID
) {
1272 xendev
->frontend_id
= xen_domid
;
1275 if (xendev
->frontend_id
>= DOMID_FIRST_RESERVED
) {
1276 error_setg(errp
, "invalid frontend-id");
1280 if (!xendev_class
->get_name
) {
1281 error_setg(errp
, "get_name method not implemented");
1285 xendev
->name
= xendev_class
->get_name(xendev
, errp
);
1287 error_prepend(errp
, "failed to get device name: ");
1291 trace_xen_device_realize(type
, xendev
->name
);
1293 xendev
->xsh
= xs_open(0);
1295 error_setg_errno(errp
, errno
, "failed xs_open");
1299 xendev
->watch_list
= watch_list_create(xendev
->xsh
);
1301 xendev
->xgth
= xengnttab_open(NULL
, 0);
1302 if (!xendev
->xgth
) {
1303 error_setg_errno(errp
, errno
, "failed xengnttab_open");
1307 xendev
->feature_grant_copy
=
1308 (xengnttab_grant_copy(xendev
->xgth
, 0, NULL
) == 0);
1310 xen_device_backend_create(xendev
, errp
);
1315 xen_device_frontend_create(xendev
, errp
);
1320 if (xendev_class
->realize
) {
1321 xendev_class
->realize(xendev
, errp
);
1327 xen_device_backend_printf(xendev
, "frontend", "%s",
1328 xendev
->frontend_path
);
1329 xen_device_backend_printf(xendev
, "frontend-id", "%u",
1330 xendev
->frontend_id
);
1331 xen_device_backend_printf(xendev
, "hotplug-status", "connected");
1333 xen_device_backend_set_online(xendev
, true);
1334 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
1336 if (!xen_device_frontend_exists(xendev
)) {
1337 xen_device_frontend_printf(xendev
, "backend", "%s",
1338 xendev
->backend_path
);
1339 xen_device_frontend_printf(xendev
, "backend-id", "%u",
1340 xenbus
->backend_id
);
1342 xen_device_frontend_set_state(xendev
, XenbusStateInitialising
, true);
1345 xendev
->exit
.notify
= xen_device_exit
;
1346 qemu_add_exit_notifier(&xendev
->exit
);
1350 xen_device_unrealize(dev
);
1353 static Property xen_device_props
[] = {
1354 DEFINE_PROP_UINT16("frontend-id", XenDevice
, frontend_id
,
1356 DEFINE_PROP_END_OF_LIST()
1359 static void xen_device_class_init(ObjectClass
*class, void *data
)
1361 DeviceClass
*dev_class
= DEVICE_CLASS(class);
1363 dev_class
->realize
= xen_device_realize
;
1364 dev_class
->unrealize
= xen_device_unrealize
;
1365 device_class_set_props(dev_class
, xen_device_props
);
1366 dev_class
->bus_type
= TYPE_XEN_BUS
;
1369 static const TypeInfo xen_device_type_info
= {
1370 .name
= TYPE_XEN_DEVICE
,
1371 .parent
= TYPE_DEVICE
,
1372 .instance_size
= sizeof(XenDevice
),
1374 .class_size
= sizeof(XenDeviceClass
),
1375 .class_init
= xen_device_class_init
,
1378 typedef struct XenBridge
{
1379 SysBusDevice busdev
;
1382 #define TYPE_XEN_BRIDGE "xen-bridge"
1384 static const TypeInfo xen_bridge_type_info
= {
1385 .name
= TYPE_XEN_BRIDGE
,
1386 .parent
= TYPE_SYS_BUS_DEVICE
,
1387 .instance_size
= sizeof(XenBridge
),
1390 static void xen_register_types(void)
1392 type_register_static(&xen_bridge_type_info
);
1393 type_register_static(&xen_bus_type_info
);
1394 type_register_static(&xen_device_type_info
);
1397 type_init(xen_register_types
)
1399 void xen_bus_init(void)
1401 DeviceState
*dev
= qdev_new(TYPE_XEN_BRIDGE
);
1402 BusState
*bus
= qbus_new(TYPE_XEN_BUS
, dev
, NULL
);
1404 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
1405 qbus_set_bus_hotplug_handler(bus
);