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
)
56 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
57 const char *type
= object_get_typename(OBJECT(xendev
));
58 Error
*local_err
= NULL
;
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 &local_err
, "%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);
99 error_propagate(errp
, local_err
);
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
));
118 XenWatchHandler handler
;
123 static void watch_notify(Notifier
*n
, void *data
)
125 XenWatch
*watch
= container_of(n
, XenWatch
, notifier
);
126 const char *token
= data
;
128 if (!strcmp(watch
->token
, token
)) {
129 watch
->handler(watch
->opaque
);
133 static XenWatch
*new_watch(const char *node
, const char *key
,
134 XenWatchHandler handler
, void *opaque
)
136 XenWatch
*watch
= g_new0(XenWatch
, 1);
139 qemu_uuid_generate(&uuid
);
141 watch
->token
= qemu_uuid_unparse_strdup(&uuid
);
142 watch
->node
= g_strdup(node
);
143 watch
->key
= g_strdup(key
);
144 watch
->handler
= handler
;
145 watch
->opaque
= opaque
;
146 watch
->notifier
.notify
= watch_notify
;
151 static void free_watch(XenWatch
*watch
)
153 g_free(watch
->token
);
160 static XenWatch
*xen_bus_add_watch(XenBus
*xenbus
, const char *node
,
161 const char *key
, XenWatchHandler handler
,
162 void *opaque
, Error
**errp
)
164 XenWatch
*watch
= new_watch(node
, key
, handler
, opaque
);
165 Error
*local_err
= NULL
;
167 trace_xen_bus_add_watch(watch
->node
, watch
->key
, watch
->token
);
169 notifier_list_add(&xenbus
->watch_notifiers
, &watch
->notifier
);
171 xs_node_watch(xenbus
->xsh
, node
, key
, watch
->token
, &local_err
);
173 error_propagate(errp
, local_err
);
175 notifier_remove(&watch
->notifier
);
184 static void xen_bus_remove_watch(XenBus
*xenbus
, XenWatch
*watch
,
187 trace_xen_bus_remove_watch(watch
->node
, watch
->key
, watch
->token
);
189 xs_node_unwatch(xenbus
->xsh
, watch
->node
, watch
->key
, watch
->token
,
192 notifier_remove(&watch
->notifier
);
196 static void xen_bus_backend_create(XenBus
*xenbus
, const char *type
,
197 const char *name
, char *path
,
200 xs_transaction_t tid
;
204 Error
*local_err
= NULL
;
206 trace_xen_bus_backend_create(type
, path
);
209 tid
= xs_transaction_start(xenbus
->xsh
);
210 if (tid
== XBT_NULL
) {
211 error_setg(errp
, "failed xs_transaction_start");
215 key
= xs_directory(xenbus
->xsh
, tid
, path
, &n
);
217 if (!xs_transaction_end(xenbus
->xsh
, tid
, true)) {
218 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
224 for (i
= 0; i
< n
; i
++) {
228 * Assume anything found in the xenstore backend area, other than
229 * the keys created for a generic XenDevice, are parameters
230 * to be used to configure the backend.
232 if (!strcmp(key
[i
], "state") ||
233 !strcmp(key
[i
], "online") ||
234 !strcmp(key
[i
], "frontend") ||
235 !strcmp(key
[i
], "frontend-id") ||
236 !strcmp(key
[i
], "hotplug-status"))
239 if (xs_node_scanf(xenbus
->xsh
, tid
, path
, key
[i
], NULL
, "%ms",
241 qdict_put_str(opts
, key
[i
], val
);
248 if (!xs_transaction_end(xenbus
->xsh
, tid
, false)) {
251 if (errno
== EAGAIN
) {
255 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
259 xen_backend_device_create(xenbus
, type
, name
, opts
, &local_err
);
263 error_propagate_prepend(errp
, local_err
,
264 "failed to create '%s' device '%s': ",
269 static void xen_bus_type_enumerate(XenBus
*xenbus
, const char *type
)
271 char *domain_path
= g_strdup_printf("backend/%s/%u", type
, xen_domid
);
275 trace_xen_bus_type_enumerate(type
);
277 backend
= xs_directory(xenbus
->xsh
, XBT_NULL
, domain_path
, &n
);
282 for (i
= 0; i
< n
; i
++) {
283 char *backend_path
= g_strdup_printf("%s/%s", domain_path
,
285 enum xenbus_state backend_state
;
287 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "state",
288 NULL
, "%u", &backend_state
) != 1)
289 backend_state
= XenbusStateUnknown
;
291 if (backend_state
== XenbusStateInitialising
) {
292 Error
*local_err
= NULL
;
294 xen_bus_backend_create(xenbus
, type
, backend
[i
], backend_path
,
297 error_report_err(local_err
);
301 g_free(backend_path
);
310 static void xen_bus_enumerate(void *opaque
)
312 XenBus
*xenbus
= opaque
;
316 trace_xen_bus_enumerate();
318 type
= xs_directory(xenbus
->xsh
, XBT_NULL
, "backend", &n
);
323 for (i
= 0; i
< n
; i
++) {
324 xen_bus_type_enumerate(xenbus
, type
[i
]);
330 static void xen_bus_unrealize(BusState
*bus
, Error
**errp
)
332 XenBus
*xenbus
= XEN_BUS(bus
);
334 trace_xen_bus_unrealize();
336 if (xenbus
->backend_watch
) {
337 xen_bus_remove_watch(xenbus
, xenbus
->backend_watch
, NULL
);
338 xenbus
->backend_watch
= NULL
;
345 qemu_set_fd_handler(xs_fileno(xenbus
->xsh
), NULL
, NULL
, NULL
);
347 xs_close(xenbus
->xsh
);
350 static void xen_bus_watch(void *opaque
)
352 XenBus
*xenbus
= opaque
;
356 g_assert(xenbus
->xsh
);
358 v
= xs_check_watch(xenbus
->xsh
);
363 token
= v
[XS_WATCH_TOKEN
];
365 trace_xen_bus_watch(token
);
367 notifier_list_notify(&xenbus
->watch_notifiers
, (void *)token
);
372 static void xen_bus_realize(BusState
*bus
, Error
**errp
)
374 XenBus
*xenbus
= XEN_BUS(bus
);
376 Error
*local_err
= NULL
;
378 trace_xen_bus_realize();
380 xenbus
->xsh
= xs_open(0);
382 error_setg_errno(errp
, errno
, "failed xs_open");
386 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, "", /* domain root node */
387 "domid", NULL
, "%u", &domid
) == 1) {
388 xenbus
->backend_id
= domid
;
390 xenbus
->backend_id
= 0; /* Assume lack of node means dom0 */
393 notifier_list_init(&xenbus
->watch_notifiers
);
394 qemu_set_fd_handler(xs_fileno(xenbus
->xsh
), xen_bus_watch
, NULL
,
397 module_call_init(MODULE_INIT_XEN_BACKEND
);
399 xenbus
->backend_watch
=
400 xen_bus_add_watch(xenbus
, "", /* domain root node */
401 "backend", xen_bus_enumerate
, xenbus
, &local_err
);
403 /* This need not be treated as a hard error so don't propagate */
404 error_reportf_err(local_err
,
405 "failed to set up enumeration watch: ");
411 xen_bus_unrealize(bus
, &error_abort
);
414 static void xen_bus_unplug_request(HotplugHandler
*hotplug
,
418 XenDevice
*xendev
= XEN_DEVICE(dev
);
420 xen_device_unplug(xendev
, errp
);
423 static void xen_bus_class_init(ObjectClass
*class, void *data
)
425 BusClass
*bus_class
= BUS_CLASS(class);
426 HotplugHandlerClass
*hotplug_class
= HOTPLUG_HANDLER_CLASS(class);
428 bus_class
->print_dev
= xen_bus_print_dev
;
429 bus_class
->get_dev_path
= xen_bus_get_dev_path
;
430 bus_class
->realize
= xen_bus_realize
;
431 bus_class
->unrealize
= xen_bus_unrealize
;
433 hotplug_class
->unplug_request
= xen_bus_unplug_request
;
436 static const TypeInfo xen_bus_type_info
= {
437 .name
= TYPE_XEN_BUS
,
439 .instance_size
= sizeof(XenBus
),
440 .class_size
= sizeof(XenBusClass
),
441 .class_init
= xen_bus_class_init
,
442 .interfaces
= (InterfaceInfo
[]) {
443 { TYPE_HOTPLUG_HANDLER
},
448 void xen_device_backend_printf(XenDevice
*xendev
, const char *key
,
449 const char *fmt
, ...)
451 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
452 Error
*local_err
= NULL
;
455 g_assert(xenbus
->xsh
);
458 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
459 &local_err
, fmt
, ap
);
463 error_report_err(local_err
);
467 static int xen_device_backend_scanf(XenDevice
*xendev
, const char *key
,
468 const char *fmt
, ...)
470 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
474 g_assert(xenbus
->xsh
);
477 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
484 void xen_device_backend_set_state(XenDevice
*xendev
,
485 enum xenbus_state state
)
487 const char *type
= object_get_typename(OBJECT(xendev
));
489 if (xendev
->backend_state
== state
) {
493 trace_xen_device_backend_state(type
, xendev
->name
,
496 xendev
->backend_state
= state
;
497 xen_device_backend_printf(xendev
, "state", "%u", state
);
500 enum xenbus_state
xen_device_backend_get_state(XenDevice
*xendev
)
502 return xendev
->backend_state
;
505 static void xen_device_backend_set_online(XenDevice
*xendev
, bool online
)
507 const char *type
= object_get_typename(OBJECT(xendev
));
509 if (xendev
->backend_online
== online
) {
513 trace_xen_device_backend_online(type
, xendev
->name
, online
);
515 xendev
->backend_online
= online
;
516 xen_device_backend_printf(xendev
, "online", "%u", online
);
520 * Tell from the state whether the frontend is likely alive,
521 * i.e. it will react to a change of state of the backend.
523 static bool xen_device_state_is_active(enum xenbus_state state
)
526 case XenbusStateInitWait
:
527 case XenbusStateInitialised
:
528 case XenbusStateConnected
:
529 case XenbusStateClosing
:
536 static void xen_device_backend_changed(void *opaque
)
538 XenDevice
*xendev
= opaque
;
539 const char *type
= object_get_typename(OBJECT(xendev
));
540 enum xenbus_state state
;
543 trace_xen_device_backend_changed(type
, xendev
->name
);
545 if (xen_device_backend_scanf(xendev
, "state", "%u", &state
) != 1) {
546 state
= XenbusStateUnknown
;
549 xen_device_backend_set_state(xendev
, state
);
551 if (xen_device_backend_scanf(xendev
, "online", "%u", &online
) != 1) {
555 xen_device_backend_set_online(xendev
, !!online
);
558 * If the toolstack (or unplug request callback) has set the backend
559 * state to Closing, but there is no active frontend then set the
560 * backend state to Closed.
562 if (xendev
->backend_state
== XenbusStateClosing
&&
563 !xen_device_state_is_active(state
)) {
564 xen_device_backend_set_state(xendev
, XenbusStateClosed
);
568 * If a backend is still 'online' then we should leave it alone but,
569 * if a backend is not 'online', then the device should be destroyed
570 * once the state is Closed.
572 if (!xendev
->backend_online
&&
573 (xendev
->backend_state
== XenbusStateClosed
||
574 xendev
->backend_state
== XenbusStateInitialising
||
575 xendev
->backend_state
== XenbusStateInitWait
||
576 xendev
->backend_state
== XenbusStateUnknown
)) {
577 Error
*local_err
= NULL
;
579 if (!xen_backend_try_device_destroy(xendev
, &local_err
)) {
580 object_unparent(OBJECT(xendev
));
584 error_report_err(local_err
);
589 static void xen_device_backend_create(XenDevice
*xendev
, Error
**errp
)
591 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
592 struct xs_permissions perms
[2];
593 Error
*local_err
= NULL
;
595 xendev
->backend_path
= xen_device_get_backend_path(xendev
);
597 perms
[0].id
= xenbus
->backend_id
;
598 perms
[0].perms
= XS_PERM_NONE
;
599 perms
[1].id
= xendev
->frontend_id
;
600 perms
[1].perms
= XS_PERM_READ
;
602 g_assert(xenbus
->xsh
);
604 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, perms
,
605 ARRAY_SIZE(perms
), &local_err
);
607 error_propagate_prepend(errp
, local_err
,
608 "failed to create backend: ");
612 xendev
->backend_state_watch
=
613 xen_bus_add_watch(xenbus
, xendev
->backend_path
,
614 "state", xen_device_backend_changed
,
617 error_propagate_prepend(errp
, local_err
,
618 "failed to watch backend state: ");
622 xendev
->backend_online_watch
=
623 xen_bus_add_watch(xenbus
, xendev
->backend_path
,
624 "online", xen_device_backend_changed
,
627 error_propagate_prepend(errp
, local_err
,
628 "failed to watch backend online: ");
633 static void xen_device_backend_destroy(XenDevice
*xendev
)
635 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
636 Error
*local_err
= NULL
;
638 if (xendev
->backend_online_watch
) {
639 xen_bus_remove_watch(xenbus
, xendev
->backend_online_watch
, NULL
);
640 xendev
->backend_online_watch
= NULL
;
643 if (xendev
->backend_state_watch
) {
644 xen_bus_remove_watch(xenbus
, xendev
->backend_state_watch
, NULL
);
645 xendev
->backend_state_watch
= NULL
;
648 if (!xendev
->backend_path
) {
652 g_assert(xenbus
->xsh
);
654 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
656 g_free(xendev
->backend_path
);
657 xendev
->backend_path
= NULL
;
660 error_report_err(local_err
);
664 void xen_device_frontend_printf(XenDevice
*xendev
, const char *key
,
665 const char *fmt
, ...)
667 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
668 Error
*local_err
= NULL
;
671 g_assert(xenbus
->xsh
);
674 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
675 &local_err
, fmt
, ap
);
679 error_report_err(local_err
);
683 int xen_device_frontend_scanf(XenDevice
*xendev
, const char *key
,
684 const char *fmt
, ...)
686 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
690 g_assert(xenbus
->xsh
);
693 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
700 static void xen_device_frontend_set_state(XenDevice
*xendev
,
701 enum xenbus_state state
,
704 const char *type
= object_get_typename(OBJECT(xendev
));
706 if (xendev
->frontend_state
== state
) {
710 trace_xen_device_frontend_state(type
, xendev
->name
,
713 xendev
->frontend_state
= state
;
715 xen_device_frontend_printf(xendev
, "state", "%u", state
);
719 static void xen_device_frontend_changed(void *opaque
)
721 XenDevice
*xendev
= opaque
;
722 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
723 const char *type
= object_get_typename(OBJECT(xendev
));
724 enum xenbus_state state
;
726 trace_xen_device_frontend_changed(type
, xendev
->name
);
728 if (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) != 1) {
729 state
= XenbusStateUnknown
;
732 xen_device_frontend_set_state(xendev
, state
, false);
734 if (state
== XenbusStateInitialising
&&
735 xendev
->backend_state
== XenbusStateClosed
&&
736 xendev
->backend_online
) {
738 * The frontend is re-initializing so switch back to
741 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
745 if (xendev_class
->frontend_changed
) {
746 Error
*local_err
= NULL
;
748 xendev_class
->frontend_changed(xendev
, state
, &local_err
);
751 error_reportf_err(local_err
, "frontend change error: ");
756 static void xen_device_frontend_create(XenDevice
*xendev
, Error
**errp
)
758 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
759 struct xs_permissions perms
[2];
760 Error
*local_err
= NULL
;
762 xendev
->frontend_path
= xen_device_get_frontend_path(xendev
);
764 perms
[0].id
= xendev
->frontend_id
;
765 perms
[0].perms
= XS_PERM_NONE
;
766 perms
[1].id
= xenbus
->backend_id
;
767 perms
[1].perms
= XS_PERM_READ
| XS_PERM_WRITE
;
769 g_assert(xenbus
->xsh
);
771 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, perms
,
772 ARRAY_SIZE(perms
), &local_err
);
774 error_propagate_prepend(errp
, local_err
,
775 "failed to create frontend: ");
779 xendev
->frontend_state_watch
=
780 xen_bus_add_watch(xenbus
, xendev
->frontend_path
, "state",
781 xen_device_frontend_changed
, xendev
, &local_err
);
783 error_propagate_prepend(errp
, local_err
,
784 "failed to watch frontend state: ");
788 static void xen_device_frontend_destroy(XenDevice
*xendev
)
790 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
791 Error
*local_err
= NULL
;
793 if (xendev
->frontend_state_watch
) {
794 xen_bus_remove_watch(xenbus
, xendev
->frontend_state_watch
, NULL
);
795 xendev
->frontend_state_watch
= NULL
;
798 if (!xendev
->frontend_path
) {
802 g_assert(xenbus
->xsh
);
804 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
,
806 g_free(xendev
->frontend_path
);
807 xendev
->frontend_path
= NULL
;
810 error_report_err(local_err
);
814 void xen_device_set_max_grant_refs(XenDevice
*xendev
, unsigned int nr_refs
,
817 if (xengnttab_set_max_grants(xendev
->xgth
, nr_refs
)) {
818 error_setg_errno(errp
, errno
, "xengnttab_set_max_grants failed");
822 void *xen_device_map_grant_refs(XenDevice
*xendev
, uint32_t *refs
,
823 unsigned int nr_refs
, int prot
,
826 void *map
= xengnttab_map_domain_grant_refs(xendev
->xgth
, nr_refs
,
827 xendev
->frontend_id
, refs
,
831 error_setg_errno(errp
, errno
,
832 "xengnttab_map_domain_grant_refs failed");
838 void xen_device_unmap_grant_refs(XenDevice
*xendev
, void *map
,
839 unsigned int nr_refs
, Error
**errp
)
841 if (xengnttab_unmap(xendev
->xgth
, map
, nr_refs
)) {
842 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
846 static void compat_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
847 XenDeviceGrantCopySegment segs
[],
848 unsigned int nr_segs
, Error
**errp
)
850 uint32_t *refs
= g_new(uint32_t, nr_segs
);
851 int prot
= to_domain
? PROT_WRITE
: PROT_READ
;
855 for (i
= 0; i
< nr_segs
; i
++) {
856 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
858 refs
[i
] = to_domain
? seg
->dest
.foreign
.ref
:
859 seg
->source
.foreign
.ref
;
862 map
= xengnttab_map_domain_grant_refs(xendev
->xgth
, nr_segs
,
863 xendev
->frontend_id
, refs
,
866 error_setg_errno(errp
, errno
,
867 "xengnttab_map_domain_grant_refs failed");
871 for (i
= 0; i
< nr_segs
; i
++) {
872 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
873 void *page
= map
+ (i
* XC_PAGE_SIZE
);
876 memcpy(page
+ seg
->dest
.foreign
.offset
, seg
->source
.virt
,
879 memcpy(seg
->dest
.virt
, page
+ seg
->source
.foreign
.offset
,
884 if (xengnttab_unmap(xendev
->xgth
, map
, nr_segs
)) {
885 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
892 void xen_device_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
893 XenDeviceGrantCopySegment segs
[],
894 unsigned int nr_segs
, Error
**errp
)
896 xengnttab_grant_copy_segment_t
*xengnttab_segs
;
899 if (!xendev
->feature_grant_copy
) {
900 compat_copy_grant_refs(xendev
, to_domain
, segs
, nr_segs
, errp
);
904 xengnttab_segs
= g_new0(xengnttab_grant_copy_segment_t
, nr_segs
);
906 for (i
= 0; i
< nr_segs
; i
++) {
907 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
908 xengnttab_grant_copy_segment_t
*xengnttab_seg
= &xengnttab_segs
[i
];
911 xengnttab_seg
->flags
= GNTCOPY_dest_gref
;
912 xengnttab_seg
->dest
.foreign
.domid
= xendev
->frontend_id
;
913 xengnttab_seg
->dest
.foreign
.ref
= seg
->dest
.foreign
.ref
;
914 xengnttab_seg
->dest
.foreign
.offset
= seg
->dest
.foreign
.offset
;
915 xengnttab_seg
->source
.virt
= seg
->source
.virt
;
917 xengnttab_seg
->flags
= GNTCOPY_source_gref
;
918 xengnttab_seg
->source
.foreign
.domid
= xendev
->frontend_id
;
919 xengnttab_seg
->source
.foreign
.ref
= seg
->source
.foreign
.ref
;
920 xengnttab_seg
->source
.foreign
.offset
=
921 seg
->source
.foreign
.offset
;
922 xengnttab_seg
->dest
.virt
= seg
->dest
.virt
;
925 xengnttab_seg
->len
= seg
->len
;
928 if (xengnttab_grant_copy(xendev
->xgth
, nr_segs
, xengnttab_segs
)) {
929 error_setg_errno(errp
, errno
, "xengnttab_grant_copy failed");
933 for (i
= 0; i
< nr_segs
; i
++) {
934 xengnttab_grant_copy_segment_t
*xengnttab_seg
= &xengnttab_segs
[i
];
936 if (xengnttab_seg
->status
!= GNTST_okay
) {
937 error_setg(errp
, "xengnttab_grant_copy seg[%u] failed", i
);
943 g_free(xengnttab_segs
);
946 struct XenEventChannel
{
947 QLIST_ENTRY(XenEventChannel
) list
;
949 xenevtchn_handle
*xeh
;
950 evtchn_port_t local_port
;
951 XenEventHandler handler
;
955 static bool xen_device_poll(void *opaque
)
957 XenEventChannel
*channel
= opaque
;
959 return channel
->handler(channel
->opaque
);
962 static void xen_device_event(void *opaque
)
964 XenEventChannel
*channel
= opaque
;
965 unsigned long port
= xenevtchn_pending(channel
->xeh
);
967 if (port
== channel
->local_port
) {
968 xen_device_poll(channel
);
970 xenevtchn_unmask(channel
->xeh
, port
);
974 XenEventChannel
*xen_device_bind_event_channel(XenDevice
*xendev
,
977 XenEventHandler handler
,
978 void *opaque
, Error
**errp
)
980 XenEventChannel
*channel
= g_new0(XenEventChannel
, 1);
981 xenevtchn_port_or_error_t local_port
;
983 channel
->xeh
= xenevtchn_open(NULL
, 0);
985 error_setg_errno(errp
, errno
, "failed xenevtchn_open");
989 local_port
= xenevtchn_bind_interdomain(channel
->xeh
,
992 if (local_port
< 0) {
993 error_setg_errno(errp
, errno
, "xenevtchn_bind_interdomain failed");
997 channel
->local_port
= local_port
;
998 channel
->handler
= handler
;
999 channel
->opaque
= opaque
;
1002 aio_set_fd_handler(channel
->ctx
, xenevtchn_fd(channel
->xeh
), true,
1003 xen_device_event
, NULL
, xen_device_poll
, channel
);
1005 QLIST_INSERT_HEAD(&xendev
->event_channels
, channel
, list
);
1011 xenevtchn_close(channel
->xeh
);
1019 void xen_device_notify_event_channel(XenDevice
*xendev
,
1020 XenEventChannel
*channel
,
1024 error_setg(errp
, "bad channel");
1028 if (xenevtchn_notify(channel
->xeh
, channel
->local_port
) < 0) {
1029 error_setg_errno(errp
, errno
, "xenevtchn_notify failed");
1033 void xen_device_unbind_event_channel(XenDevice
*xendev
,
1034 XenEventChannel
*channel
,
1038 error_setg(errp
, "bad channel");
1042 QLIST_REMOVE(channel
, list
);
1044 aio_set_fd_handler(channel
->ctx
, xenevtchn_fd(channel
->xeh
), true,
1045 NULL
, NULL
, NULL
, NULL
);
1047 if (xenevtchn_unbind(channel
->xeh
, channel
->local_port
) < 0) {
1048 error_setg_errno(errp
, errno
, "xenevtchn_unbind failed");
1051 xenevtchn_close(channel
->xeh
);
1055 static void xen_device_unrealize(DeviceState
*dev
, Error
**errp
)
1057 XenDevice
*xendev
= XEN_DEVICE(dev
);
1058 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1059 const char *type
= object_get_typename(OBJECT(xendev
));
1060 XenEventChannel
*channel
, *next
;
1062 if (!xendev
->name
) {
1066 trace_xen_device_unrealize(type
, xendev
->name
);
1068 if (xendev
->exit
.notify
) {
1069 qemu_remove_exit_notifier(&xendev
->exit
);
1070 xendev
->exit
.notify
= NULL
;
1073 if (xendev_class
->unrealize
) {
1074 xendev_class
->unrealize(xendev
, errp
);
1077 /* Make sure all event channels are cleaned up */
1078 QLIST_FOREACH_SAFE(channel
, &xendev
->event_channels
, list
, next
) {
1079 xen_device_unbind_event_channel(xendev
, channel
, NULL
);
1082 xen_device_frontend_destroy(xendev
);
1083 xen_device_backend_destroy(xendev
);
1086 xengnttab_close(xendev
->xgth
);
1087 xendev
->xgth
= NULL
;
1090 g_free(xendev
->name
);
1091 xendev
->name
= NULL
;
1094 static void xen_device_exit(Notifier
*n
, void *data
)
1096 XenDevice
*xendev
= container_of(n
, XenDevice
, exit
);
1098 xen_device_unrealize(DEVICE(xendev
), &error_abort
);
1101 static void xen_device_realize(DeviceState
*dev
, Error
**errp
)
1103 XenDevice
*xendev
= XEN_DEVICE(dev
);
1104 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1105 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
1106 const char *type
= object_get_typename(OBJECT(xendev
));
1107 Error
*local_err
= NULL
;
1109 if (xendev
->frontend_id
== DOMID_INVALID
) {
1110 xendev
->frontend_id
= xen_domid
;
1113 if (xendev
->frontend_id
>= DOMID_FIRST_RESERVED
) {
1114 error_setg(errp
, "invalid frontend-id");
1118 if (!xendev_class
->get_name
) {
1119 error_setg(errp
, "get_name method not implemented");
1123 xendev
->name
= xendev_class
->get_name(xendev
, &local_err
);
1125 error_propagate_prepend(errp
, local_err
,
1126 "failed to get device name: ");
1130 trace_xen_device_realize(type
, xendev
->name
);
1132 xendev
->xgth
= xengnttab_open(NULL
, 0);
1133 if (!xendev
->xgth
) {
1134 error_setg_errno(errp
, errno
, "failed xengnttab_open");
1138 xendev
->feature_grant_copy
=
1139 (xengnttab_grant_copy(xendev
->xgth
, 0, NULL
) == 0);
1141 xen_device_backend_create(xendev
, &local_err
);
1143 error_propagate(errp
, local_err
);
1147 xen_device_frontend_create(xendev
, &local_err
);
1149 error_propagate(errp
, local_err
);
1153 if (xendev_class
->realize
) {
1154 xendev_class
->realize(xendev
, &local_err
);
1156 error_propagate(errp
, local_err
);
1161 xen_device_backend_printf(xendev
, "frontend", "%s",
1162 xendev
->frontend_path
);
1163 xen_device_backend_printf(xendev
, "frontend-id", "%u",
1164 xendev
->frontend_id
);
1165 xen_device_backend_printf(xendev
, "hotplug-status", "connected");
1167 xen_device_backend_set_online(xendev
, true);
1168 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
1170 xen_device_frontend_printf(xendev
, "backend", "%s",
1171 xendev
->backend_path
);
1172 xen_device_frontend_printf(xendev
, "backend-id", "%u",
1173 xenbus
->backend_id
);
1175 xen_device_frontend_set_state(xendev
, XenbusStateInitialising
, true);
1177 xendev
->exit
.notify
= xen_device_exit
;
1178 qemu_add_exit_notifier(&xendev
->exit
);
1182 xen_device_unrealize(dev
, &error_abort
);
1185 static Property xen_device_props
[] = {
1186 DEFINE_PROP_UINT16("frontend-id", XenDevice
, frontend_id
,
1188 DEFINE_PROP_END_OF_LIST()
1191 static void xen_device_class_init(ObjectClass
*class, void *data
)
1193 DeviceClass
*dev_class
= DEVICE_CLASS(class);
1195 dev_class
->realize
= xen_device_realize
;
1196 dev_class
->unrealize
= xen_device_unrealize
;
1197 dev_class
->props
= xen_device_props
;
1198 dev_class
->bus_type
= TYPE_XEN_BUS
;
1201 static const TypeInfo xen_device_type_info
= {
1202 .name
= TYPE_XEN_DEVICE
,
1203 .parent
= TYPE_DEVICE
,
1204 .instance_size
= sizeof(XenDevice
),
1206 .class_size
= sizeof(XenDeviceClass
),
1207 .class_init
= xen_device_class_init
,
1210 typedef struct XenBridge
{
1211 SysBusDevice busdev
;
1214 #define TYPE_XEN_BRIDGE "xen-bridge"
1216 static const TypeInfo xen_bridge_type_info
= {
1217 .name
= TYPE_XEN_BRIDGE
,
1218 .parent
= TYPE_SYS_BUS_DEVICE
,
1219 .instance_size
= sizeof(XenBridge
),
1222 static void xen_register_types(void)
1224 type_register_static(&xen_bridge_type_info
);
1225 type_register_static(&xen_bus_type_info
);
1226 type_register_static(&xen_device_type_info
);
1229 type_init(xen_register_types
)
1231 void xen_bus_init(void)
1233 DeviceState
*dev
= qdev_create(NULL
, TYPE_XEN_BRIDGE
);
1234 BusState
*bus
= qbus_create(TYPE_XEN_BUS
, dev
, NULL
);
1236 qdev_init_nofail(dev
);
1237 qbus_set_bus_hotplug_handler(bus
, &error_abort
);