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"
25 static char *xen_device_get_backend_path(XenDevice
*xendev
)
27 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
28 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
29 const char *type
= object_get_typename(OBJECT(xendev
));
30 const char *backend
= xendev_class
->backend
;
36 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
37 xenbus
->backend_id
, backend
, xendev
->frontend_id
,
41 static char *xen_device_get_frontend_path(XenDevice
*xendev
)
43 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
44 const char *type
= object_get_typename(OBJECT(xendev
));
45 const char *device
= xendev_class
->device
;
51 return g_strdup_printf("/local/domain/%u/device/%s/%s",
52 xendev
->frontend_id
, device
, xendev
->name
);
55 static void xen_device_unplug(XenDevice
*xendev
, Error
**errp
)
58 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
59 const char *type
= object_get_typename(OBJECT(xendev
));
62 trace_xen_device_unplug(type
, xendev
->name
);
64 /* Mimic the way the Xen toolstack does an unplug */
66 tid
= qemu_xen_xs_transaction_start(xenbus
->xsh
);
67 if (tid
== XBT_NULL
) {
68 error_setg_errno(errp
, errno
, "failed xs_transaction_start");
72 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "online",
78 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "state",
79 errp
, "%u", XenbusStateClosing
);
84 if (!qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, false)) {
85 if (errno
== EAGAIN
) {
89 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
96 * We only abort if there is already a failure so ignore any error
97 * from ending the transaction.
99 qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, true);
102 static void xen_bus_print_dev(Monitor
*mon
, DeviceState
*dev
, int indent
)
104 XenDevice
*xendev
= XEN_DEVICE(dev
);
106 monitor_printf(mon
, "%*sname = '%s' frontend_id = %u\n",
107 indent
, "", xendev
->name
, xendev
->frontend_id
);
110 static char *xen_bus_get_dev_path(DeviceState
*dev
)
112 return xen_device_get_backend_path(XEN_DEVICE(dev
));
115 static void xen_bus_backend_create(XenBus
*xenbus
, const char *type
,
116 const char *name
, char *path
,
120 xs_transaction_t tid
;
125 trace_xen_bus_backend_create(type
, path
);
128 tid
= qemu_xen_xs_transaction_start(xenbus
->xsh
);
129 if (tid
== XBT_NULL
) {
130 error_setg(errp
, "failed xs_transaction_start");
134 key
= qemu_xen_xs_directory(xenbus
->xsh
, tid
, path
, &n
);
136 if (!qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, true)) {
137 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
143 for (i
= 0; i
< n
; i
++) {
147 * Assume anything found in the xenstore backend area, other than
148 * the keys created for a generic XenDevice, are parameters
149 * to be used to configure the backend.
151 if (!strcmp(key
[i
], "state") ||
152 !strcmp(key
[i
], "online") ||
153 !strcmp(key
[i
], "frontend") ||
154 !strcmp(key
[i
], "frontend-id") ||
155 !strcmp(key
[i
], "hotplug-status"))
158 if (xs_node_scanf(xenbus
->xsh
, tid
, path
, key
[i
], NULL
, "%ms",
160 qdict_put_str(opts
, key
[i
], val
);
167 if (!qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, false)) {
170 if (errno
== EAGAIN
) {
174 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
178 xen_backend_device_create(xenbus
, type
, name
, opts
, errp
);
182 error_prepend(errp
, "failed to create '%s' device '%s': ", type
, name
);
186 static void xen_bus_type_enumerate(XenBus
*xenbus
, const char *type
)
188 char *domain_path
= g_strdup_printf("backend/%s/%u", type
, xen_domid
);
192 trace_xen_bus_type_enumerate(type
);
194 backend
= qemu_xen_xs_directory(xenbus
->xsh
, XBT_NULL
, domain_path
, &n
);
199 for (i
= 0; i
< n
; i
++) {
200 char *backend_path
= g_strdup_printf("%s/%s", domain_path
,
202 enum xenbus_state state
;
205 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "state",
206 NULL
, "%u", &state
) != 1)
207 state
= XenbusStateUnknown
;
209 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "online",
210 NULL
, "%u", &online
) != 1)
213 if (online
&& state
== XenbusStateInitialising
&&
214 !xen_backend_exists(type
, backend
[i
])) {
215 Error
*local_err
= NULL
;
217 xen_bus_backend_create(xenbus
, type
, backend
[i
], backend_path
,
220 error_report_err(local_err
);
224 g_free(backend_path
);
233 static void xen_bus_enumerate(XenBus
*xenbus
)
238 trace_xen_bus_enumerate();
240 type
= qemu_xen_xs_directory(xenbus
->xsh
, XBT_NULL
, "backend", &n
);
245 for (i
= 0; i
< n
; i
++) {
246 xen_bus_type_enumerate(xenbus
, type
[i
]);
252 static void xen_bus_device_cleanup(XenDevice
*xendev
)
254 const char *type
= object_get_typename(OBJECT(xendev
));
255 Error
*local_err
= NULL
;
257 trace_xen_bus_device_cleanup(type
, xendev
->name
);
259 g_assert(!xendev
->backend_online
);
261 if (!xen_backend_try_device_destroy(xendev
, &local_err
)) {
262 object_unparent(OBJECT(xendev
));
266 error_report_err(local_err
);
270 static void xen_bus_cleanup(XenBus
*xenbus
)
272 XenDevice
*xendev
, *next
;
274 trace_xen_bus_cleanup();
276 QLIST_FOREACH_SAFE(xendev
, &xenbus
->inactive_devices
, list
, next
) {
277 g_assert(xendev
->inactive
);
278 QLIST_REMOVE(xendev
, list
);
279 xen_bus_device_cleanup(xendev
);
283 static void xen_bus_backend_changed(void *opaque
, const char *path
)
285 XenBus
*xenbus
= opaque
;
287 xen_bus_enumerate(xenbus
);
288 xen_bus_cleanup(xenbus
);
291 static void xen_bus_unrealize(BusState
*bus
)
293 XenBus
*xenbus
= XEN_BUS(bus
);
295 trace_xen_bus_unrealize();
297 if (xenbus
->backend_watch
) {
300 for (i
= 0; i
< xenbus
->backend_types
; i
++) {
301 if (xenbus
->backend_watch
[i
]) {
302 xs_node_unwatch(xenbus
->xsh
, xenbus
->backend_watch
[i
]);
306 g_free(xenbus
->backend_watch
);
307 xenbus
->backend_watch
= NULL
;
311 qemu_xen_xs_close(xenbus
->xsh
);
315 static void xen_bus_realize(BusState
*bus
, Error
**errp
)
317 char *key
= g_strdup_printf("%u", xen_domid
);
318 XenBus
*xenbus
= XEN_BUS(bus
);
322 Error
*local_err
= NULL
;
324 trace_xen_bus_realize();
326 xenbus
->xsh
= qemu_xen_xs_open();
328 error_setg_errno(errp
, errno
, "failed xs_open");
332 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, "", /* domain root node */
333 "domid", NULL
, "%u", &domid
) == 1) {
334 xenbus
->backend_id
= domid
;
336 xenbus
->backend_id
= 0; /* Assume lack of node means dom0 */
339 module_call_init(MODULE_INIT_XEN_BACKEND
);
341 type
= xen_backend_get_types(&xenbus
->backend_types
);
342 xenbus
->backend_watch
= g_new(struct qemu_xs_watch
*,
343 xenbus
->backend_types
);
345 for (i
= 0; i
< xenbus
->backend_types
; i
++) {
346 char *node
= g_strdup_printf("backend/%s", type
[i
]);
348 xenbus
->backend_watch
[i
] =
349 xs_node_watch(xenbus
->xsh
, node
, key
, xen_bus_backend_changed
,
352 /* This need not be treated as a hard error so don't propagate */
353 error_reportf_err(local_err
,
354 "failed to set up '%s' enumeration watch: ",
366 xen_bus_unrealize(bus
);
370 static void xen_bus_unplug_request(HotplugHandler
*hotplug
,
374 XenDevice
*xendev
= XEN_DEVICE(dev
);
376 xen_device_unplug(xendev
, errp
);
379 static void xen_bus_class_init(ObjectClass
*class, void *data
)
381 BusClass
*bus_class
= BUS_CLASS(class);
382 HotplugHandlerClass
*hotplug_class
= HOTPLUG_HANDLER_CLASS(class);
384 bus_class
->print_dev
= xen_bus_print_dev
;
385 bus_class
->get_dev_path
= xen_bus_get_dev_path
;
386 bus_class
->realize
= xen_bus_realize
;
387 bus_class
->unrealize
= xen_bus_unrealize
;
389 hotplug_class
->unplug_request
= xen_bus_unplug_request
;
392 static const TypeInfo xen_bus_type_info
= {
393 .name
= TYPE_XEN_BUS
,
395 .instance_size
= sizeof(XenBus
),
396 .class_size
= sizeof(XenBusClass
),
397 .class_init
= xen_bus_class_init
,
398 .interfaces
= (InterfaceInfo
[]) {
399 { TYPE_HOTPLUG_HANDLER
},
404 void xen_device_backend_printf(XenDevice
*xendev
, const char *key
,
405 const char *fmt
, ...)
407 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
408 Error
*local_err
= NULL
;
411 g_assert(xenbus
->xsh
);
414 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
415 &local_err
, fmt
, ap
);
419 error_report_err(local_err
);
424 static int xen_device_backend_scanf(XenDevice
*xendev
, const char *key
,
425 const char *fmt
, ...)
427 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
431 g_assert(xenbus
->xsh
);
434 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
441 void xen_device_backend_set_state(XenDevice
*xendev
,
442 enum xenbus_state state
)
444 const char *type
= object_get_typename(OBJECT(xendev
));
446 if (xendev
->backend_state
== state
) {
450 trace_xen_device_backend_state(type
, xendev
->name
,
453 xendev
->backend_state
= state
;
454 xen_device_backend_printf(xendev
, "state", "%u", state
);
457 enum xenbus_state
xen_device_backend_get_state(XenDevice
*xendev
)
459 return xendev
->backend_state
;
462 static void xen_device_backend_set_online(XenDevice
*xendev
, bool online
)
464 const char *type
= object_get_typename(OBJECT(xendev
));
466 if (xendev
->backend_online
== online
) {
470 trace_xen_device_backend_online(type
, xendev
->name
, online
);
472 xendev
->backend_online
= online
;
473 xen_device_backend_printf(xendev
, "online", "%u", online
);
477 * Tell from the state whether the frontend is likely alive,
478 * i.e. it will react to a change of state of the backend.
480 static bool xen_device_frontend_is_active(XenDevice
*xendev
)
482 switch (xendev
->frontend_state
) {
483 case XenbusStateInitWait
:
484 case XenbusStateInitialised
:
485 case XenbusStateConnected
:
486 case XenbusStateClosing
:
493 static void xen_device_backend_changed(void *opaque
, const char *path
)
495 XenDevice
*xendev
= opaque
;
496 const char *type
= object_get_typename(OBJECT(xendev
));
497 enum xenbus_state state
;
500 trace_xen_device_backend_changed(type
, xendev
->name
);
502 if (xen_device_backend_scanf(xendev
, "state", "%u", &state
) != 1) {
503 state
= XenbusStateUnknown
;
506 xen_device_backend_set_state(xendev
, state
);
508 if (xen_device_backend_scanf(xendev
, "online", "%u", &online
) != 1) {
512 xen_device_backend_set_online(xendev
, !!online
);
515 * If the toolstack (or unplug request callback) has set the backend
516 * state to Closing, but there is no active frontend then set the
517 * backend state to Closed.
519 if (state
== XenbusStateClosing
&&
520 !xen_device_frontend_is_active(xendev
)) {
521 xen_device_backend_set_state(xendev
, XenbusStateClosed
);
525 * If a backend is still 'online' then we should leave it alone but,
526 * if a backend is not 'online', then the device is a candidate
527 * for destruction. Hence add it to the 'inactive' list to be cleaned
528 * by xen_bus_cleanup().
531 (state
== XenbusStateClosed
|| state
== XenbusStateInitialising
||
532 state
== XenbusStateInitWait
|| state
== XenbusStateUnknown
) &&
534 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
536 xendev
->inactive
= true;
537 QLIST_INSERT_HEAD(&xenbus
->inactive_devices
, xendev
, list
);
540 * Re-write the state to cause a XenBus backend_watch notification,
541 * resulting in a call to xen_bus_cleanup().
543 xen_device_backend_printf(xendev
, "state", "%u", state
);
547 static void xen_device_backend_create(XenDevice
*xendev
, Error
**errp
)
550 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
552 xendev
->backend_path
= xen_device_get_backend_path(xendev
);
554 g_assert(xenbus
->xsh
);
556 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
557 xenbus
->backend_id
, xendev
->frontend_id
, XS_PERM_READ
, errp
);
559 error_prepend(errp
, "failed to create backend: ");
563 xendev
->backend_state_watch
=
564 xs_node_watch(xendev
->xsh
, xendev
->backend_path
,
565 "state", xen_device_backend_changed
, xendev
,
568 error_prepend(errp
, "failed to watch backend state: ");
572 xendev
->backend_online_watch
=
573 xs_node_watch(xendev
->xsh
, xendev
->backend_path
,
574 "online", xen_device_backend_changed
, xendev
,
577 error_prepend(errp
, "failed to watch backend online: ");
582 static void xen_device_backend_destroy(XenDevice
*xendev
)
584 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
585 Error
*local_err
= NULL
;
587 if (xendev
->backend_online_watch
) {
588 xs_node_unwatch(xendev
->xsh
, xendev
->backend_online_watch
);
589 xendev
->backend_online_watch
= NULL
;
592 if (xendev
->backend_state_watch
) {
593 xs_node_unwatch(xendev
->xsh
, xendev
->backend_state_watch
);
594 xendev
->backend_state_watch
= NULL
;
597 if (!xendev
->backend_path
) {
601 g_assert(xenbus
->xsh
);
603 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
605 g_free(xendev
->backend_path
);
606 xendev
->backend_path
= NULL
;
609 error_report_err(local_err
);
613 void xen_device_frontend_printf(XenDevice
*xendev
, const char *key
,
614 const char *fmt
, ...)
616 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
617 Error
*local_err
= NULL
;
620 g_assert(xenbus
->xsh
);
623 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
624 &local_err
, fmt
, ap
);
628 error_report_err(local_err
);
632 int xen_device_frontend_scanf(XenDevice
*xendev
, const char *key
,
633 const char *fmt
, ...)
635 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
639 g_assert(xenbus
->xsh
);
642 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
649 static void xen_device_frontend_set_state(XenDevice
*xendev
,
650 enum xenbus_state state
,
653 const char *type
= object_get_typename(OBJECT(xendev
));
655 if (xendev
->frontend_state
== state
) {
659 trace_xen_device_frontend_state(type
, xendev
->name
,
662 xendev
->frontend_state
= state
;
664 xen_device_frontend_printf(xendev
, "state", "%u", state
);
668 static void xen_device_frontend_changed(void *opaque
, const char *path
)
670 XenDevice
*xendev
= opaque
;
671 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
672 const char *type
= object_get_typename(OBJECT(xendev
));
673 enum xenbus_state state
;
675 trace_xen_device_frontend_changed(type
, xendev
->name
);
677 if (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) != 1) {
678 state
= XenbusStateUnknown
;
681 xen_device_frontend_set_state(xendev
, state
, false);
683 if (state
== XenbusStateInitialising
&&
684 xendev
->backend_state
== XenbusStateClosed
&&
685 xendev
->backend_online
) {
687 * The frontend is re-initializing so switch back to
690 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
694 if (xendev_class
->frontend_changed
) {
695 Error
*local_err
= NULL
;
697 xendev_class
->frontend_changed(xendev
, state
, &local_err
);
700 error_reportf_err(local_err
, "frontend change error: ");
705 static bool xen_device_frontend_exists(XenDevice
*xendev
)
707 enum xenbus_state state
;
709 return (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) == 1);
712 static void xen_device_frontend_create(XenDevice
*xendev
, Error
**errp
)
715 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
716 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
718 if (xendev_class
->get_frontend_path
) {
719 xendev
->frontend_path
= xendev_class
->get_frontend_path(xendev
, errp
);
720 if (!xendev
->frontend_path
) {
721 error_prepend(errp
, "failed to create frontend: ");
725 xendev
->frontend_path
= xen_device_get_frontend_path(xendev
);
729 * The frontend area may have already been created by a legacy
732 if (!xen_device_frontend_exists(xendev
)) {
733 g_assert(xenbus
->xsh
);
735 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
,
736 xendev
->frontend_id
, xenbus
->backend_id
,
737 XS_PERM_READ
| XS_PERM_WRITE
, errp
);
739 error_prepend(errp
, "failed to create frontend: ");
744 xendev
->frontend_state_watch
=
745 xs_node_watch(xendev
->xsh
, xendev
->frontend_path
, "state",
746 xen_device_frontend_changed
, xendev
, errp
);
748 error_prepend(errp
, "failed to watch frontend state: ");
752 static void xen_device_frontend_destroy(XenDevice
*xendev
)
754 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
755 Error
*local_err
= NULL
;
757 if (xendev
->frontend_state_watch
) {
758 xs_node_unwatch(xendev
->xsh
, xendev
->frontend_state_watch
);
759 xendev
->frontend_state_watch
= NULL
;
762 if (!xendev
->frontend_path
) {
766 g_assert(xenbus
->xsh
);
768 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
,
770 g_free(xendev
->frontend_path
);
771 xendev
->frontend_path
= NULL
;
774 error_report_err(local_err
);
778 void xen_device_set_max_grant_refs(XenDevice
*xendev
, unsigned int nr_refs
,
781 if (qemu_xen_gnttab_set_max_grants(xendev
->xgth
, nr_refs
)) {
782 error_setg_errno(errp
, errno
, "xengnttab_set_max_grants failed");
786 void *xen_device_map_grant_refs(XenDevice
*xendev
, uint32_t *refs
,
787 unsigned int nr_refs
, int prot
,
790 void *map
= qemu_xen_gnttab_map_refs(xendev
->xgth
, nr_refs
,
791 xendev
->frontend_id
, refs
, prot
);
794 error_setg_errno(errp
, errno
,
795 "xengnttab_map_domain_grant_refs failed");
801 void xen_device_unmap_grant_refs(XenDevice
*xendev
, void *map
, uint32_t *refs
,
802 unsigned int nr_refs
, Error
**errp
)
804 if (qemu_xen_gnttab_unmap(xendev
->xgth
, map
, refs
, nr_refs
)) {
805 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
809 void xen_device_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
810 XenDeviceGrantCopySegment segs
[],
811 unsigned int nr_segs
, Error
**errp
)
813 qemu_xen_gnttab_grant_copy(xendev
->xgth
, to_domain
, xendev
->frontend_id
,
814 (XenGrantCopySegment
*)segs
, nr_segs
, errp
);
817 struct XenEventChannel
{
818 QLIST_ENTRY(XenEventChannel
) list
;
820 xenevtchn_handle
*xeh
;
821 evtchn_port_t local_port
;
822 XenEventHandler handler
;
826 static bool xen_device_poll(void *opaque
)
828 XenEventChannel
*channel
= opaque
;
830 return channel
->handler(channel
->opaque
);
833 static void xen_device_event(void *opaque
)
835 XenEventChannel
*channel
= opaque
;
836 unsigned long port
= qemu_xen_evtchn_pending(channel
->xeh
);
838 if (port
== channel
->local_port
) {
839 xen_device_poll(channel
);
841 qemu_xen_evtchn_unmask(channel
->xeh
, port
);
845 void xen_device_set_event_channel_context(XenDevice
*xendev
,
846 XenEventChannel
*channel
,
851 error_setg(errp
, "bad channel");
856 aio_set_fd_handler(channel
->ctx
, qemu_xen_evtchn_fd(channel
->xeh
),
857 NULL
, NULL
, NULL
, NULL
, NULL
);
861 aio_set_fd_handler(channel
->ctx
, qemu_xen_evtchn_fd(channel
->xeh
),
862 xen_device_event
, NULL
, xen_device_poll
, NULL
,
867 XenEventChannel
*xen_device_bind_event_channel(XenDevice
*xendev
,
869 XenEventHandler handler
,
870 void *opaque
, Error
**errp
)
872 XenEventChannel
*channel
= g_new0(XenEventChannel
, 1);
873 xenevtchn_port_or_error_t local_port
;
875 channel
->xeh
= qemu_xen_evtchn_open();
877 error_setg_errno(errp
, errno
, "failed xenevtchn_open");
881 local_port
= qemu_xen_evtchn_bind_interdomain(channel
->xeh
,
884 if (local_port
< 0) {
885 error_setg_errno(errp
, errno
, "xenevtchn_bind_interdomain failed");
889 channel
->local_port
= local_port
;
890 channel
->handler
= handler
;
891 channel
->opaque
= opaque
;
893 /* Only reason for failure is a NULL channel */
894 xen_device_set_event_channel_context(xendev
, channel
,
895 qemu_get_aio_context(),
898 QLIST_INSERT_HEAD(&xendev
->event_channels
, channel
, list
);
904 qemu_xen_evtchn_close(channel
->xeh
);
912 void xen_device_notify_event_channel(XenDevice
*xendev
,
913 XenEventChannel
*channel
,
917 error_setg(errp
, "bad channel");
921 if (qemu_xen_evtchn_notify(channel
->xeh
, channel
->local_port
) < 0) {
922 error_setg_errno(errp
, errno
, "xenevtchn_notify failed");
926 unsigned int xen_event_channel_get_local_port(XenEventChannel
*channel
)
928 return channel
->local_port
;
931 void xen_device_unbind_event_channel(XenDevice
*xendev
,
932 XenEventChannel
*channel
,
936 error_setg(errp
, "bad channel");
940 QLIST_REMOVE(channel
, list
);
943 aio_set_fd_handler(channel
->ctx
, qemu_xen_evtchn_fd(channel
->xeh
),
944 NULL
, NULL
, NULL
, NULL
, NULL
);
947 if (qemu_xen_evtchn_unbind(channel
->xeh
, channel
->local_port
) < 0) {
948 error_setg_errno(errp
, errno
, "xenevtchn_unbind failed");
951 qemu_xen_evtchn_close(channel
->xeh
);
955 static void xen_device_unrealize(DeviceState
*dev
)
957 XenDevice
*xendev
= XEN_DEVICE(dev
);
958 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
959 const char *type
= object_get_typename(OBJECT(xendev
));
960 XenEventChannel
*channel
, *next
;
966 trace_xen_device_unrealize(type
, xendev
->name
);
968 if (xendev
->exit
.notify
) {
969 qemu_remove_exit_notifier(&xendev
->exit
);
970 xendev
->exit
.notify
= NULL
;
973 if (xendev_class
->unrealize
) {
974 xendev_class
->unrealize(xendev
);
977 /* Make sure all event channels are cleaned up */
978 QLIST_FOREACH_SAFE(channel
, &xendev
->event_channels
, list
, next
) {
979 xen_device_unbind_event_channel(xendev
, channel
, NULL
);
982 xen_device_frontend_destroy(xendev
);
983 xen_device_backend_destroy(xendev
);
986 qemu_xen_gnttab_close(xendev
->xgth
);
991 qemu_xen_xs_close(xendev
->xsh
);
995 g_free(xendev
->name
);
999 static void xen_device_exit(Notifier
*n
, void *data
)
1001 XenDevice
*xendev
= container_of(n
, XenDevice
, exit
);
1003 xen_device_unrealize(DEVICE(xendev
));
1006 static void xen_device_realize(DeviceState
*dev
, Error
**errp
)
1009 XenDevice
*xendev
= XEN_DEVICE(dev
);
1010 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1011 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
1012 const char *type
= object_get_typename(OBJECT(xendev
));
1014 if (xendev
->frontend_id
== DOMID_INVALID
) {
1015 xendev
->frontend_id
= xen_domid
;
1018 if (xendev
->frontend_id
>= DOMID_FIRST_RESERVED
) {
1019 error_setg(errp
, "invalid frontend-id");
1023 if (!xendev_class
->get_name
) {
1024 error_setg(errp
, "get_name method not implemented");
1028 xendev
->name
= xendev_class
->get_name(xendev
, errp
);
1030 error_prepend(errp
, "failed to get device name: ");
1034 trace_xen_device_realize(type
, xendev
->name
);
1036 xendev
->xsh
= qemu_xen_xs_open();
1038 error_setg_errno(errp
, errno
, "failed xs_open");
1042 xendev
->xgth
= qemu_xen_gnttab_open();
1043 if (!xendev
->xgth
) {
1044 error_setg_errno(errp
, errno
, "failed xengnttab_open");
1048 xen_device_backend_create(xendev
, errp
);
1053 xen_device_frontend_create(xendev
, errp
);
1058 xen_device_backend_printf(xendev
, "frontend", "%s",
1059 xendev
->frontend_path
);
1060 xen_device_backend_printf(xendev
, "frontend-id", "%u",
1061 xendev
->frontend_id
);
1062 xen_device_backend_printf(xendev
, "hotplug-status", "connected");
1064 xen_device_backend_set_online(xendev
, true);
1065 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
1067 if (!xen_device_frontend_exists(xendev
)) {
1068 xen_device_frontend_printf(xendev
, "backend", "%s",
1069 xendev
->backend_path
);
1070 xen_device_frontend_printf(xendev
, "backend-id", "%u",
1071 xenbus
->backend_id
);
1073 xen_device_frontend_set_state(xendev
, XenbusStateInitialising
, true);
1076 if (xendev_class
->realize
) {
1077 xendev_class
->realize(xendev
, errp
);
1083 xendev
->exit
.notify
= xen_device_exit
;
1084 qemu_add_exit_notifier(&xendev
->exit
);
1088 xen_device_unrealize(dev
);
1091 static Property xen_device_props
[] = {
1092 DEFINE_PROP_UINT16("frontend-id", XenDevice
, frontend_id
,
1094 DEFINE_PROP_END_OF_LIST()
1097 static void xen_device_class_init(ObjectClass
*class, void *data
)
1099 DeviceClass
*dev_class
= DEVICE_CLASS(class);
1101 dev_class
->realize
= xen_device_realize
;
1102 dev_class
->unrealize
= xen_device_unrealize
;
1103 device_class_set_props(dev_class
, xen_device_props
);
1104 dev_class
->bus_type
= TYPE_XEN_BUS
;
1107 static const TypeInfo xen_device_type_info
= {
1108 .name
= TYPE_XEN_DEVICE
,
1109 .parent
= TYPE_DEVICE
,
1110 .instance_size
= sizeof(XenDevice
),
1112 .class_size
= sizeof(XenDeviceClass
),
1113 .class_init
= xen_device_class_init
,
1116 typedef struct XenBridge
{
1117 SysBusDevice busdev
;
1120 #define TYPE_XEN_BRIDGE "xen-bridge"
1122 static const TypeInfo xen_bridge_type_info
= {
1123 .name
= TYPE_XEN_BRIDGE
,
1124 .parent
= TYPE_SYS_BUS_DEVICE
,
1125 .instance_size
= sizeof(XenBridge
),
1128 static void xen_register_types(void)
1130 type_register_static(&xen_bridge_type_info
);
1131 type_register_static(&xen_bus_type_info
);
1132 type_register_static(&xen_device_type_info
);
1135 type_init(xen_register_types
)
1137 void xen_bus_init(void)
1139 DeviceState
*dev
= qdev_new(TYPE_XEN_BRIDGE
);
1140 BusState
*bus
= qbus_new(TYPE_XEN_BUS
, dev
, NULL
);
1142 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
1143 qbus_set_bus_hotplug_handler(bus
);
1145 qemu_create_nic_bus_devices(bus
, TYPE_XEN_DEVICE
, "xen-net-device",
1146 "xen", "xen-net-device");