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-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"
26 static char *xen_device_get_backend_path(XenDevice
*xendev
)
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
;
37 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
38 xenbus
->backend_id
, backend
, xendev
->frontend_id
,
42 static char *xen_device_get_frontend_path(XenDevice
*xendev
)
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
;
52 return g_strdup_printf("/local/domain/%u/device/%s/%s",
53 xendev
->frontend_id
, device
, xendev
->name
);
56 static void xen_device_unplug(XenDevice
*xendev
, Error
**errp
)
59 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
60 const char *type
= object_get_typename(OBJECT(xendev
));
63 trace_xen_device_unplug(type
, xendev
->name
);
65 /* Mimic the way the Xen toolstack does an unplug */
67 tid
= qemu_xen_xs_transaction_start(xenbus
->xsh
);
68 if (tid
== XBT_NULL
) {
69 error_setg_errno(errp
, errno
, "failed xs_transaction_start");
73 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "online",
79 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "state",
80 errp
, "%u", XenbusStateClosing
);
85 if (!qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, false)) {
86 if (errno
== EAGAIN
) {
90 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
97 * We only abort if there is already a failure so ignore any error
98 * from ending the transaction.
100 qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, true);
103 static void xen_bus_print_dev(Monitor
*mon
, DeviceState
*dev
, int indent
)
105 XenDevice
*xendev
= XEN_DEVICE(dev
);
107 monitor_printf(mon
, "%*sname = '%s' frontend_id = %u\n",
108 indent
, "", xendev
->name
, xendev
->frontend_id
);
111 static char *xen_bus_get_dev_path(DeviceState
*dev
)
113 return xen_device_get_backend_path(XEN_DEVICE(dev
));
116 static void xen_bus_backend_create(XenBus
*xenbus
, const char *type
,
117 const char *name
, char *path
,
121 xs_transaction_t tid
;
126 trace_xen_bus_backend_create(type
, path
);
129 tid
= qemu_xen_xs_transaction_start(xenbus
->xsh
);
130 if (tid
== XBT_NULL
) {
131 error_setg(errp
, "failed xs_transaction_start");
135 key
= qemu_xen_xs_directory(xenbus
->xsh
, tid
, path
, &n
);
137 if (!qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, true)) {
138 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
144 for (i
= 0; i
< n
; i
++) {
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.
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"))
159 if (xs_node_scanf(xenbus
->xsh
, tid
, path
, key
[i
], NULL
, "%ms",
161 qdict_put_str(opts
, key
[i
], val
);
168 if (!qemu_xen_xs_transaction_end(xenbus
->xsh
, tid
, false)) {
171 if (errno
== EAGAIN
) {
175 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
179 xen_backend_device_create(xenbus
, type
, name
, opts
, errp
);
183 error_prepend(errp
, "failed to create '%s' device '%s': ", type
, name
);
187 static void xen_bus_type_enumerate(XenBus
*xenbus
, const char *type
)
189 char *domain_path
= g_strdup_printf("backend/%s/%u", type
, xen_domid
);
193 trace_xen_bus_type_enumerate(type
);
195 backend
= qemu_xen_xs_directory(xenbus
->xsh
, XBT_NULL
, domain_path
, &n
);
200 for (i
= 0; i
< n
; i
++) {
201 char *backend_path
= g_strdup_printf("%s/%s", domain_path
,
203 enum xenbus_state state
;
206 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "state",
207 NULL
, "%u", &state
) != 1)
208 state
= XenbusStateUnknown
;
210 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "online",
211 NULL
, "%u", &online
) != 1)
214 if (online
&& state
== XenbusStateInitialising
&&
215 !xen_backend_exists(type
, backend
[i
])) {
216 Error
*local_err
= NULL
;
218 xen_bus_backend_create(xenbus
, type
, backend
[i
], backend_path
,
221 error_report_err(local_err
);
225 g_free(backend_path
);
234 static void xen_bus_enumerate(XenBus
*xenbus
)
239 trace_xen_bus_enumerate();
241 type
= qemu_xen_xs_directory(xenbus
->xsh
, XBT_NULL
, "backend", &n
);
246 for (i
= 0; i
< n
; i
++) {
247 xen_bus_type_enumerate(xenbus
, type
[i
]);
253 static void xen_bus_device_cleanup(XenDevice
*xendev
)
255 const char *type
= object_get_typename(OBJECT(xendev
));
256 Error
*local_err
= NULL
;
258 trace_xen_bus_device_cleanup(type
, xendev
->name
);
260 g_assert(!xendev
->backend_online
);
262 if (!xen_backend_try_device_destroy(xendev
, &local_err
)) {
263 object_unparent(OBJECT(xendev
));
267 error_report_err(local_err
);
271 static void xen_bus_cleanup(XenBus
*xenbus
)
273 XenDevice
*xendev
, *next
;
275 trace_xen_bus_cleanup();
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
);
284 static void xen_bus_backend_changed(void *opaque
, const char *path
)
286 XenBus
*xenbus
= opaque
;
288 xen_bus_enumerate(xenbus
);
289 xen_bus_cleanup(xenbus
);
292 static void xen_bus_unrealize(BusState
*bus
)
294 XenBus
*xenbus
= XEN_BUS(bus
);
296 trace_xen_bus_unrealize();
298 if (xenbus
->backend_watch
) {
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
]);
307 g_free(xenbus
->backend_watch
);
308 xenbus
->backend_watch
= NULL
;
312 qemu_xen_xs_close(xenbus
->xsh
);
316 static void xen_bus_realize(BusState
*bus
, Error
**errp
)
318 char *key
= g_strdup_printf("%u", xen_domid
);
319 XenBus
*xenbus
= XEN_BUS(bus
);
323 Error
*local_err
= NULL
;
325 trace_xen_bus_realize();
327 xenbus
->xsh
= qemu_xen_xs_open();
329 error_setg_errno(errp
, errno
, "failed xs_open");
333 /* Initialize legacy backend core & drivers */
336 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, "", /* domain root node */
337 "domid", NULL
, "%u", &domid
) == 1) {
338 xenbus
->backend_id
= domid
;
340 xenbus
->backend_id
= 0; /* Assume lack of node means dom0 */
343 module_call_init(MODULE_INIT_XEN_BACKEND
);
345 type
= xen_backend_get_types(&xenbus
->backend_types
);
346 xenbus
->backend_watch
= g_new(struct qemu_xs_watch
*,
347 xenbus
->backend_types
);
349 for (i
= 0; i
< xenbus
->backend_types
; i
++) {
350 char *node
= g_strdup_printf("backend/%s", type
[i
]);
352 xenbus
->backend_watch
[i
] =
353 xs_node_watch(xenbus
->xsh
, node
, key
, xen_bus_backend_changed
,
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: ",
370 xen_bus_unrealize(bus
);
374 static void xen_bus_unplug_request(HotplugHandler
*hotplug
,
378 XenDevice
*xendev
= XEN_DEVICE(dev
);
380 xen_device_unplug(xendev
, errp
);
383 static void xen_bus_class_init(ObjectClass
*class, void *data
)
385 BusClass
*bus_class
= BUS_CLASS(class);
386 HotplugHandlerClass
*hotplug_class
= HOTPLUG_HANDLER_CLASS(class);
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
;
393 hotplug_class
->unplug_request
= xen_bus_unplug_request
;
396 static const TypeInfo xen_bus_type_info
= {
397 .name
= TYPE_XEN_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
},
408 void xen_device_backend_printf(XenDevice
*xendev
, const char *key
,
409 const char *fmt
, ...)
411 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
412 Error
*local_err
= NULL
;
415 g_assert(xenbus
->xsh
);
418 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
419 &local_err
, fmt
, ap
);
423 error_report_err(local_err
);
428 static int xen_device_backend_scanf(XenDevice
*xendev
, const char *key
,
429 const char *fmt
, ...)
431 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
435 g_assert(xenbus
->xsh
);
438 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
445 void xen_device_backend_set_state(XenDevice
*xendev
,
446 enum xenbus_state state
)
448 const char *type
= object_get_typename(OBJECT(xendev
));
450 if (xendev
->backend_state
== state
) {
454 trace_xen_device_backend_state(type
, xendev
->name
,
457 xendev
->backend_state
= state
;
458 xen_device_backend_printf(xendev
, "state", "%u", state
);
461 enum xenbus_state
xen_device_backend_get_state(XenDevice
*xendev
)
463 return xendev
->backend_state
;
466 static void xen_device_backend_set_online(XenDevice
*xendev
, bool online
)
468 const char *type
= object_get_typename(OBJECT(xendev
));
470 if (xendev
->backend_online
== online
) {
474 trace_xen_device_backend_online(type
, xendev
->name
, online
);
476 xendev
->backend_online
= online
;
477 xen_device_backend_printf(xendev
, "online", "%u", online
);
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.
484 static bool xen_device_frontend_is_active(XenDevice
*xendev
)
486 switch (xendev
->frontend_state
) {
487 case XenbusStateInitWait
:
488 case XenbusStateInitialised
:
489 case XenbusStateConnected
:
490 case XenbusStateClosing
:
497 static void xen_device_backend_changed(void *opaque
, const char *path
)
499 XenDevice
*xendev
= opaque
;
500 const char *type
= object_get_typename(OBJECT(xendev
));
501 enum xenbus_state state
;
504 trace_xen_device_backend_changed(type
, xendev
->name
);
506 if (xen_device_backend_scanf(xendev
, "state", "%u", &state
) != 1) {
507 state
= XenbusStateUnknown
;
510 xen_device_backend_set_state(xendev
, state
);
512 if (xen_device_backend_scanf(xendev
, "online", "%u", &online
) != 1) {
516 xen_device_backend_set_online(xendev
, !!online
);
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.
523 if (state
== XenbusStateClosing
&&
524 !xen_device_frontend_is_active(xendev
)) {
525 xen_device_backend_set_state(xendev
, XenbusStateClosed
);
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().
535 (state
== XenbusStateClosed
|| state
== XenbusStateInitialising
||
536 state
== XenbusStateInitWait
|| state
== XenbusStateUnknown
) &&
538 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
540 xendev
->inactive
= true;
541 QLIST_INSERT_HEAD(&xenbus
->inactive_devices
, xendev
, list
);
544 * Re-write the state to cause a XenBus backend_watch notification,
545 * resulting in a call to xen_bus_cleanup().
547 xen_device_backend_printf(xendev
, "state", "%u", state
);
551 static void xen_device_backend_create(XenDevice
*xendev
, Error
**errp
)
554 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
556 xendev
->backend_path
= xen_device_get_backend_path(xendev
);
558 g_assert(xenbus
->xsh
);
560 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
561 xenbus
->backend_id
, xendev
->frontend_id
, XS_PERM_READ
, errp
);
563 error_prepend(errp
, "failed to create backend: ");
567 xendev
->backend_state_watch
=
568 xs_node_watch(xendev
->xsh
, xendev
->backend_path
,
569 "state", xen_device_backend_changed
, xendev
,
572 error_prepend(errp
, "failed to watch backend state: ");
576 xendev
->backend_online_watch
=
577 xs_node_watch(xendev
->xsh
, xendev
->backend_path
,
578 "online", xen_device_backend_changed
, xendev
,
581 error_prepend(errp
, "failed to watch backend online: ");
586 static void xen_device_backend_destroy(XenDevice
*xendev
)
588 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
589 Error
*local_err
= NULL
;
591 if (xendev
->backend_online_watch
) {
592 xs_node_unwatch(xendev
->xsh
, xendev
->backend_online_watch
);
593 xendev
->backend_online_watch
= NULL
;
596 if (xendev
->backend_state_watch
) {
597 xs_node_unwatch(xendev
->xsh
, xendev
->backend_state_watch
);
598 xendev
->backend_state_watch
= NULL
;
601 if (!xendev
->backend_path
) {
605 g_assert(xenbus
->xsh
);
607 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
609 g_free(xendev
->backend_path
);
610 xendev
->backend_path
= NULL
;
613 error_report_err(local_err
);
617 void xen_device_frontend_printf(XenDevice
*xendev
, const char *key
,
618 const char *fmt
, ...)
620 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
621 Error
*local_err
= NULL
;
624 g_assert(xenbus
->xsh
);
627 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
628 &local_err
, fmt
, ap
);
632 error_report_err(local_err
);
636 int xen_device_frontend_scanf(XenDevice
*xendev
, const char *key
,
637 const char *fmt
, ...)
639 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
643 g_assert(xenbus
->xsh
);
646 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
653 static void xen_device_frontend_set_state(XenDevice
*xendev
,
654 enum xenbus_state state
,
657 const char *type
= object_get_typename(OBJECT(xendev
));
659 if (xendev
->frontend_state
== state
) {
663 trace_xen_device_frontend_state(type
, xendev
->name
,
666 xendev
->frontend_state
= state
;
668 xen_device_frontend_printf(xendev
, "state", "%u", state
);
672 static void xen_device_frontend_changed(void *opaque
, const char *path
)
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
;
679 trace_xen_device_frontend_changed(type
, xendev
->name
);
681 if (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) != 1) {
682 state
= XenbusStateUnknown
;
685 xen_device_frontend_set_state(xendev
, state
, false);
687 if (state
== XenbusStateInitialising
&&
688 xendev
->backend_state
== XenbusStateClosed
&&
689 xendev
->backend_online
) {
691 * The frontend is re-initializing so switch back to
694 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
698 if (xendev_class
->frontend_changed
) {
699 Error
*local_err
= NULL
;
701 xendev_class
->frontend_changed(xendev
, state
, &local_err
);
704 error_reportf_err(local_err
, "frontend change error: ");
709 static bool xen_device_frontend_exists(XenDevice
*xendev
)
711 enum xenbus_state state
;
713 return (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) == 1);
716 static void xen_device_frontend_create(XenDevice
*xendev
, Error
**errp
)
719 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
720 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
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: ");
729 xendev
->frontend_path
= xen_device_get_frontend_path(xendev
);
733 * The frontend area may have already been created by a legacy
736 if (!xen_device_frontend_exists(xendev
)) {
737 g_assert(xenbus
->xsh
);
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
);
743 error_prepend(errp
, "failed to create frontend: ");
748 xendev
->frontend_state_watch
=
749 xs_node_watch(xendev
->xsh
, xendev
->frontend_path
, "state",
750 xen_device_frontend_changed
, xendev
, errp
);
752 error_prepend(errp
, "failed to watch frontend state: ");
756 static void xen_device_frontend_destroy(XenDevice
*xendev
)
758 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
759 Error
*local_err
= NULL
;
761 if (xendev
->frontend_state_watch
) {
762 xs_node_unwatch(xendev
->xsh
, xendev
->frontend_state_watch
);
763 xendev
->frontend_state_watch
= NULL
;
766 if (!xendev
->frontend_path
) {
770 g_assert(xenbus
->xsh
);
772 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
,
774 g_free(xendev
->frontend_path
);
775 xendev
->frontend_path
= NULL
;
778 error_report_err(local_err
);
782 void xen_device_set_max_grant_refs(XenDevice
*xendev
, unsigned int nr_refs
,
785 if (qemu_xen_gnttab_set_max_grants(xendev
->xgth
, nr_refs
)) {
786 error_setg_errno(errp
, errno
, "xengnttab_set_max_grants failed");
790 void *xen_device_map_grant_refs(XenDevice
*xendev
, uint32_t *refs
,
791 unsigned int nr_refs
, int prot
,
794 void *map
= qemu_xen_gnttab_map_refs(xendev
->xgth
, nr_refs
,
795 xendev
->frontend_id
, refs
, prot
);
798 error_setg_errno(errp
, errno
,
799 "xengnttab_map_domain_grant_refs failed");
805 void xen_device_unmap_grant_refs(XenDevice
*xendev
, void *map
, uint32_t *refs
,
806 unsigned int nr_refs
, Error
**errp
)
808 if (qemu_xen_gnttab_unmap(xendev
->xgth
, map
, refs
, nr_refs
)) {
809 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
813 void xen_device_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
814 XenDeviceGrantCopySegment segs
[],
815 unsigned int nr_segs
, Error
**errp
)
817 qemu_xen_gnttab_grant_copy(xendev
->xgth
, to_domain
, xendev
->frontend_id
,
818 (XenGrantCopySegment
*)segs
, nr_segs
, errp
);
821 struct XenEventChannel
{
822 QLIST_ENTRY(XenEventChannel
) list
;
824 xenevtchn_handle
*xeh
;
825 evtchn_port_t local_port
;
826 XenEventHandler handler
;
830 static bool xen_device_poll(void *opaque
)
832 XenEventChannel
*channel
= opaque
;
834 return channel
->handler(channel
->opaque
);
837 static void xen_device_event(void *opaque
)
839 XenEventChannel
*channel
= opaque
;
840 unsigned long port
= qemu_xen_evtchn_pending(channel
->xeh
);
842 if (port
== channel
->local_port
) {
843 xen_device_poll(channel
);
845 qemu_xen_evtchn_unmask(channel
->xeh
, port
);
849 void xen_device_set_event_channel_context(XenDevice
*xendev
,
850 XenEventChannel
*channel
,
855 error_setg(errp
, "bad channel");
860 aio_set_fd_handler(channel
->ctx
, qemu_xen_evtchn_fd(channel
->xeh
),
861 NULL
, NULL
, NULL
, NULL
, NULL
);
865 aio_set_fd_handler(channel
->ctx
, qemu_xen_evtchn_fd(channel
->xeh
),
866 xen_device_event
, NULL
, xen_device_poll
, NULL
,
871 XenEventChannel
*xen_device_bind_event_channel(XenDevice
*xendev
,
873 XenEventHandler handler
,
874 void *opaque
, Error
**errp
)
876 XenEventChannel
*channel
= g_new0(XenEventChannel
, 1);
877 xenevtchn_port_or_error_t local_port
;
879 channel
->xeh
= qemu_xen_evtchn_open();
881 error_setg_errno(errp
, errno
, "failed xenevtchn_open");
885 local_port
= qemu_xen_evtchn_bind_interdomain(channel
->xeh
,
888 if (local_port
< 0) {
889 error_setg_errno(errp
, errno
, "xenevtchn_bind_interdomain failed");
893 channel
->local_port
= local_port
;
894 channel
->handler
= handler
;
895 channel
->opaque
= opaque
;
897 /* Only reason for failure is a NULL channel */
898 xen_device_set_event_channel_context(xendev
, channel
,
899 qemu_get_aio_context(),
902 QLIST_INSERT_HEAD(&xendev
->event_channels
, channel
, list
);
908 qemu_xen_evtchn_close(channel
->xeh
);
916 void xen_device_notify_event_channel(XenDevice
*xendev
,
917 XenEventChannel
*channel
,
921 error_setg(errp
, "bad channel");
925 if (qemu_xen_evtchn_notify(channel
->xeh
, channel
->local_port
) < 0) {
926 error_setg_errno(errp
, errno
, "xenevtchn_notify failed");
930 unsigned int xen_event_channel_get_local_port(XenEventChannel
*channel
)
932 return channel
->local_port
;
935 void xen_device_unbind_event_channel(XenDevice
*xendev
,
936 XenEventChannel
*channel
,
940 error_setg(errp
, "bad channel");
944 QLIST_REMOVE(channel
, list
);
947 aio_set_fd_handler(channel
->ctx
, qemu_xen_evtchn_fd(channel
->xeh
),
948 NULL
, NULL
, NULL
, NULL
, NULL
);
951 if (qemu_xen_evtchn_unbind(channel
->xeh
, channel
->local_port
) < 0) {
952 error_setg_errno(errp
, errno
, "xenevtchn_unbind failed");
955 qemu_xen_evtchn_close(channel
->xeh
);
959 static void xen_device_unrealize(DeviceState
*dev
)
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
;
970 trace_xen_device_unrealize(type
, xendev
->name
);
972 if (xendev
->exit
.notify
) {
973 qemu_remove_exit_notifier(&xendev
->exit
);
974 xendev
->exit
.notify
= NULL
;
977 if (xendev_class
->unrealize
) {
978 xendev_class
->unrealize(xendev
);
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
);
986 xen_device_frontend_destroy(xendev
);
987 xen_device_backend_destroy(xendev
);
990 qemu_xen_gnttab_close(xendev
->xgth
);
995 qemu_xen_xs_close(xendev
->xsh
);
999 g_free(xendev
->name
);
1000 xendev
->name
= NULL
;
1003 static void xen_device_exit(Notifier
*n
, void *data
)
1005 XenDevice
*xendev
= container_of(n
, XenDevice
, exit
);
1007 xen_device_unrealize(DEVICE(xendev
));
1010 static void xen_device_realize(DeviceState
*dev
, Error
**errp
)
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
));
1018 if (xendev
->frontend_id
== DOMID_INVALID
) {
1019 xendev
->frontend_id
= xen_domid
;
1022 if (xendev
->frontend_id
>= DOMID_FIRST_RESERVED
) {
1023 error_setg(errp
, "invalid frontend-id");
1027 if (!xendev_class
->get_name
) {
1028 error_setg(errp
, "get_name method not implemented");
1032 xendev
->name
= xendev_class
->get_name(xendev
, errp
);
1034 error_prepend(errp
, "failed to get device name: ");
1038 trace_xen_device_realize(type
, xendev
->name
);
1040 xendev
->xsh
= qemu_xen_xs_open();
1042 error_setg_errno(errp
, errno
, "failed xs_open");
1046 xendev
->xgth
= qemu_xen_gnttab_open();
1047 if (!xendev
->xgth
) {
1048 error_setg_errno(errp
, errno
, "failed xengnttab_open");
1052 xen_device_backend_create(xendev
, errp
);
1057 xen_device_frontend_create(xendev
, errp
);
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");
1068 xen_device_backend_set_online(xendev
, true);
1069 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
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
);
1077 xen_device_frontend_set_state(xendev
, XenbusStateInitialising
, true);
1080 if (xendev_class
->realize
) {
1081 xendev_class
->realize(xendev
, errp
);
1087 xendev
->exit
.notify
= xen_device_exit
;
1088 qemu_add_exit_notifier(&xendev
->exit
);
1092 xen_device_unrealize(dev
);
1095 static Property xen_device_props
[] = {
1096 DEFINE_PROP_UINT16("frontend-id", XenDevice
, frontend_id
,
1098 DEFINE_PROP_END_OF_LIST()
1101 static void xen_device_class_init(ObjectClass
*class, void *data
)
1103 DeviceClass
*dev_class
= DEVICE_CLASS(class);
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
;
1111 static const TypeInfo xen_device_type_info
= {
1112 .name
= TYPE_XEN_DEVICE
,
1113 .parent
= TYPE_DEVICE
,
1114 .instance_size
= sizeof(XenDevice
),
1116 .class_size
= sizeof(XenDeviceClass
),
1117 .class_init
= xen_device_class_init
,
1120 typedef struct XenBridge
{
1121 SysBusDevice busdev
;
1124 #define TYPE_XEN_BRIDGE "xen-bridge"
1126 static const TypeInfo xen_bridge_type_info
= {
1127 .name
= TYPE_XEN_BRIDGE
,
1128 .parent
= TYPE_SYS_BUS_DEVICE
,
1129 .instance_size
= sizeof(XenBridge
),
1132 static void xen_register_types(void)
1134 type_register_static(&xen_bridge_type_info
);
1135 type_register_static(&xen_bus_type_info
);
1136 type_register_static(&xen_device_type_info
);
1139 type_init(xen_register_types
)
1141 void xen_bus_init(void)
1143 DeviceState
*dev
= qdev_new(TYPE_XEN_BRIDGE
);
1144 BusState
*bus
= qbus_new(TYPE_XEN_BUS
, dev
, NULL
);
1146 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
1147 qbus_set_bus_hotplug_handler(bus
);
1149 qemu_create_nic_bus_devices(bus
, TYPE_XEN_DEVICE
, "xen-net-device",
1150 "xen", "xen-net-device");