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/uuid.h"
12 #include "hw/sysbus.h"
13 #include "hw/xen/xen.h"
14 #include "hw/xen/xen-backend.h"
15 #include "hw/xen/xen-bus.h"
16 #include "hw/xen/xen-bus-helper.h"
17 #include "monitor/monitor.h"
18 #include "qapi/error.h"
19 #include "qapi/qmp/qdict.h"
20 #include "sysemu/sysemu.h"
23 static char *xen_device_get_backend_path(XenDevice
*xendev
)
25 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
26 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
27 const char *type
= object_get_typename(OBJECT(xendev
));
28 const char *backend
= xendev_class
->backend
;
34 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s",
35 xenbus
->backend_id
, backend
, xendev
->frontend_id
,
39 static char *xen_device_get_frontend_path(XenDevice
*xendev
)
41 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
42 const char *type
= object_get_typename(OBJECT(xendev
));
43 const char *device
= xendev_class
->device
;
49 return g_strdup_printf("/local/domain/%u/device/%s/%s",
50 xendev
->frontend_id
, device
, xendev
->name
);
53 static void xen_device_unplug(XenDevice
*xendev
, Error
**errp
)
55 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
56 const char *type
= object_get_typename(OBJECT(xendev
));
57 Error
*local_err
= NULL
;
60 trace_xen_device_unplug(type
, xendev
->name
);
62 /* Mimic the way the Xen toolstack does an unplug */
64 tid
= xs_transaction_start(xenbus
->xsh
);
65 if (tid
== XBT_NULL
) {
66 error_setg_errno(errp
, errno
, "failed xs_transaction_start");
70 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "online",
76 xs_node_printf(xenbus
->xsh
, tid
, xendev
->backend_path
, "state",
77 &local_err
, "%u", XenbusStateClosing
);
82 if (!xs_transaction_end(xenbus
->xsh
, tid
, false)) {
83 if (errno
== EAGAIN
) {
87 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
94 * We only abort if there is already a failure so ignore any error
95 * from ending the transaction.
97 xs_transaction_end(xenbus
->xsh
, tid
, true);
98 error_propagate(errp
, local_err
);
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 static XenWatch
*xen_bus_add_watch(XenBus
*xenbus
, const char *node
,
160 const char *key
, XenWatchHandler handler
,
161 void *opaque
, Error
**errp
)
163 XenWatch
*watch
= new_watch(node
, key
, handler
, opaque
);
164 Error
*local_err
= NULL
;
166 trace_xen_bus_add_watch(watch
->node
, watch
->key
, watch
->token
);
168 notifier_list_add(&xenbus
->watch_notifiers
, &watch
->notifier
);
170 xs_node_watch(xenbus
->xsh
, node
, key
, watch
->token
, &local_err
);
172 error_propagate(errp
, local_err
);
174 notifier_remove(&watch
->notifier
);
183 static void xen_bus_remove_watch(XenBus
*xenbus
, XenWatch
*watch
,
186 trace_xen_bus_remove_watch(watch
->node
, watch
->key
, watch
->token
);
188 xs_node_unwatch(xenbus
->xsh
, watch
->node
, watch
->key
, watch
->token
,
191 notifier_remove(&watch
->notifier
);
195 static void xen_bus_backend_create(XenBus
*xenbus
, const char *type
,
196 const char *name
, char *path
,
199 xs_transaction_t tid
;
203 Error
*local_err
= NULL
;
205 trace_xen_bus_backend_create(type
, path
);
208 tid
= xs_transaction_start(xenbus
->xsh
);
209 if (tid
== XBT_NULL
) {
210 error_setg(errp
, "failed xs_transaction_start");
214 key
= xs_directory(xenbus
->xsh
, tid
, path
, &n
);
216 if (!xs_transaction_end(xenbus
->xsh
, tid
, true)) {
217 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
223 for (i
= 0; i
< n
; i
++) {
227 * Assume anything found in the xenstore backend area, other than
228 * the keys created for a generic XenDevice, are parameters
229 * to be used to configure the backend.
231 if (!strcmp(key
[i
], "state") ||
232 !strcmp(key
[i
], "online") ||
233 !strcmp(key
[i
], "frontend") ||
234 !strcmp(key
[i
], "frontend-id") ||
235 !strcmp(key
[i
], "hotplug-status"))
238 if (xs_node_scanf(xenbus
->xsh
, tid
, path
, key
[i
], NULL
, "%ms",
240 qdict_put_str(opts
, key
[i
], val
);
247 if (!xs_transaction_end(xenbus
->xsh
, tid
, false)) {
250 if (errno
== EAGAIN
) {
254 error_setg_errno(errp
, errno
, "failed xs_transaction_end");
258 xen_backend_device_create(xenbus
, type
, name
, opts
, &local_err
);
262 error_propagate_prepend(errp
, local_err
,
263 "failed to create '%s' device '%s': ",
268 static void xen_bus_type_enumerate(XenBus
*xenbus
, const char *type
)
270 char *domain_path
= g_strdup_printf("backend/%s/%u", type
, xen_domid
);
274 trace_xen_bus_type_enumerate(type
);
276 backend
= xs_directory(xenbus
->xsh
, XBT_NULL
, domain_path
, &n
);
281 for (i
= 0; i
< n
; i
++) {
282 char *backend_path
= g_strdup_printf("%s/%s", domain_path
,
284 enum xenbus_state backend_state
;
286 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, backend_path
, "state",
287 NULL
, "%u", &backend_state
) != 1)
288 backend_state
= XenbusStateUnknown
;
290 if (backend_state
== XenbusStateInitialising
) {
291 Error
*local_err
= NULL
;
293 xen_bus_backend_create(xenbus
, type
, backend
[i
], backend_path
,
296 error_report_err(local_err
);
300 g_free(backend_path
);
309 static void xen_bus_enumerate(void *opaque
)
311 XenBus
*xenbus
= opaque
;
315 trace_xen_bus_enumerate();
317 type
= xs_directory(xenbus
->xsh
, XBT_NULL
, "backend", &n
);
322 for (i
= 0; i
< n
; i
++) {
323 xen_bus_type_enumerate(xenbus
, type
[i
]);
329 static void xen_bus_unrealize(BusState
*bus
, Error
**errp
)
331 XenBus
*xenbus
= XEN_BUS(bus
);
333 trace_xen_bus_unrealize();
335 if (xenbus
->backend_watch
) {
336 xen_bus_remove_watch(xenbus
, xenbus
->backend_watch
, NULL
);
337 xenbus
->backend_watch
= NULL
;
344 qemu_set_fd_handler(xs_fileno(xenbus
->xsh
), NULL
, NULL
, NULL
);
346 xs_close(xenbus
->xsh
);
349 static void xen_bus_watch(void *opaque
)
351 XenBus
*xenbus
= opaque
;
355 g_assert(xenbus
->xsh
);
357 v
= xs_check_watch(xenbus
->xsh
);
362 token
= v
[XS_WATCH_TOKEN
];
364 trace_xen_bus_watch(token
);
366 notifier_list_notify(&xenbus
->watch_notifiers
, (void *)token
);
371 static void xen_bus_realize(BusState
*bus
, Error
**errp
)
373 XenBus
*xenbus
= XEN_BUS(bus
);
375 Error
*local_err
= NULL
;
377 trace_xen_bus_realize();
379 xenbus
->xsh
= xs_open(0);
381 error_setg_errno(errp
, errno
, "failed xs_open");
385 if (xs_node_scanf(xenbus
->xsh
, XBT_NULL
, "", /* domain root node */
386 "domid", NULL
, "%u", &domid
) == 1) {
387 xenbus
->backend_id
= domid
;
389 xenbus
->backend_id
= 0; /* Assume lack of node means dom0 */
392 notifier_list_init(&xenbus
->watch_notifiers
);
393 qemu_set_fd_handler(xs_fileno(xenbus
->xsh
), xen_bus_watch
, NULL
,
396 module_call_init(MODULE_INIT_XEN_BACKEND
);
398 xenbus
->backend_watch
=
399 xen_bus_add_watch(xenbus
, "", /* domain root node */
400 "backend", xen_bus_enumerate
, xenbus
, &local_err
);
402 /* This need not be treated as a hard error so don't propagate */
403 error_reportf_err(local_err
,
404 "failed to set up enumeration watch: ");
410 xen_bus_unrealize(bus
, &error_abort
);
413 static void xen_bus_unplug_request(HotplugHandler
*hotplug
,
417 XenDevice
*xendev
= XEN_DEVICE(dev
);
419 xen_device_unplug(xendev
, errp
);
422 static void xen_bus_class_init(ObjectClass
*class, void *data
)
424 BusClass
*bus_class
= BUS_CLASS(class);
425 HotplugHandlerClass
*hotplug_class
= HOTPLUG_HANDLER_CLASS(class);
427 bus_class
->print_dev
= xen_bus_print_dev
;
428 bus_class
->get_dev_path
= xen_bus_get_dev_path
;
429 bus_class
->realize
= xen_bus_realize
;
430 bus_class
->unrealize
= xen_bus_unrealize
;
432 hotplug_class
->unplug_request
= xen_bus_unplug_request
;
435 static const TypeInfo xen_bus_type_info
= {
436 .name
= TYPE_XEN_BUS
,
438 .instance_size
= sizeof(XenBus
),
439 .class_size
= sizeof(XenBusClass
),
440 .class_init
= xen_bus_class_init
,
441 .interfaces
= (InterfaceInfo
[]) {
442 { TYPE_HOTPLUG_HANDLER
},
447 void xen_device_backend_printf(XenDevice
*xendev
, const char *key
,
448 const char *fmt
, ...)
450 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
451 Error
*local_err
= NULL
;
454 g_assert(xenbus
->xsh
);
457 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
458 &local_err
, fmt
, ap
);
462 error_report_err(local_err
);
466 static int xen_device_backend_scanf(XenDevice
*xendev
, const char *key
,
467 const char *fmt
, ...)
469 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
473 g_assert(xenbus
->xsh
);
476 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, key
,
483 void xen_device_backend_set_state(XenDevice
*xendev
,
484 enum xenbus_state state
)
486 const char *type
= object_get_typename(OBJECT(xendev
));
488 if (xendev
->backend_state
== state
) {
492 trace_xen_device_backend_state(type
, xendev
->name
,
495 xendev
->backend_state
= state
;
496 xen_device_backend_printf(xendev
, "state", "%u", state
);
499 enum xenbus_state
xen_device_backend_get_state(XenDevice
*xendev
)
501 return xendev
->backend_state
;
504 static void xen_device_backend_set_online(XenDevice
*xendev
, bool online
)
506 const char *type
= object_get_typename(OBJECT(xendev
));
508 if (xendev
->backend_online
== online
) {
512 trace_xen_device_backend_online(type
, xendev
->name
, online
);
514 xendev
->backend_online
= online
;
515 xen_device_backend_printf(xendev
, "online", "%u", online
);
518 static void xen_device_backend_changed(void *opaque
)
520 XenDevice
*xendev
= opaque
;
521 const char *type
= object_get_typename(OBJECT(xendev
));
522 enum xenbus_state state
;
525 trace_xen_device_backend_changed(type
, xendev
->name
);
527 if (xen_device_backend_scanf(xendev
, "state", "%u", &state
) != 1) {
528 state
= XenbusStateUnknown
;
531 xen_device_backend_set_state(xendev
, state
);
533 if (xen_device_backend_scanf(xendev
, "online", "%u", &online
) != 1) {
537 xen_device_backend_set_online(xendev
, !!online
);
540 * If the toolstack (or unplug request callback) has set the backend
541 * state to Closing, but there is no active frontend (i.e. the
542 * state is not Connected) then set the backend state to Closed.
544 if (xendev
->backend_state
== XenbusStateClosing
&&
545 xendev
->frontend_state
!= XenbusStateConnected
) {
546 xen_device_backend_set_state(xendev
, XenbusStateClosed
);
550 * If a backend is still 'online' then its state should be cycled
551 * back round to InitWait in order for a new frontend instance to
552 * connect. This may happen when, for example, a frontend driver is
553 * re-installed or updated.
554 * If a backend is not 'online' then the device should be destroyed.
556 if (xendev
->backend_online
&&
557 xendev
->backend_state
== XenbusStateClosed
) {
558 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
559 } else if (!xendev
->backend_online
&&
560 (xendev
->backend_state
== XenbusStateClosed
||
561 xendev
->backend_state
== XenbusStateInitialising
||
562 xendev
->backend_state
== XenbusStateInitWait
||
563 xendev
->backend_state
== XenbusStateUnknown
)) {
564 Error
*local_err
= NULL
;
566 if (!xen_backend_try_device_destroy(xendev
, &local_err
)) {
567 object_unparent(OBJECT(xendev
));
571 error_report_err(local_err
);
576 static void xen_device_backend_create(XenDevice
*xendev
, Error
**errp
)
578 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
579 struct xs_permissions perms
[2];
580 Error
*local_err
= NULL
;
582 xendev
->backend_path
= xen_device_get_backend_path(xendev
);
584 perms
[0].id
= xenbus
->backend_id
;
585 perms
[0].perms
= XS_PERM_NONE
;
586 perms
[1].id
= xendev
->frontend_id
;
587 perms
[1].perms
= XS_PERM_READ
;
589 g_assert(xenbus
->xsh
);
591 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
, perms
,
592 ARRAY_SIZE(perms
), &local_err
);
594 error_propagate_prepend(errp
, local_err
,
595 "failed to create backend: ");
599 xendev
->backend_state_watch
=
600 xen_bus_add_watch(xenbus
, xendev
->backend_path
,
601 "state", xen_device_backend_changed
,
604 error_propagate_prepend(errp
, local_err
,
605 "failed to watch backend state: ");
609 xendev
->backend_online_watch
=
610 xen_bus_add_watch(xenbus
, xendev
->backend_path
,
611 "online", xen_device_backend_changed
,
614 error_propagate_prepend(errp
, local_err
,
615 "failed to watch backend online: ");
620 static void xen_device_backend_destroy(XenDevice
*xendev
)
622 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
623 Error
*local_err
= NULL
;
625 if (xendev
->backend_online_watch
) {
626 xen_bus_remove_watch(xenbus
, xendev
->backend_online_watch
, NULL
);
627 xendev
->backend_online_watch
= NULL
;
630 if (xendev
->backend_state_watch
) {
631 xen_bus_remove_watch(xenbus
, xendev
->backend_state_watch
, NULL
);
632 xendev
->backend_state_watch
= NULL
;
635 if (!xendev
->backend_path
) {
639 g_assert(xenbus
->xsh
);
641 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->backend_path
,
643 g_free(xendev
->backend_path
);
644 xendev
->backend_path
= NULL
;
647 error_report_err(local_err
);
651 void xen_device_frontend_printf(XenDevice
*xendev
, const char *key
,
652 const char *fmt
, ...)
654 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
655 Error
*local_err
= NULL
;
658 g_assert(xenbus
->xsh
);
661 xs_node_vprintf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
662 &local_err
, fmt
, ap
);
666 error_report_err(local_err
);
670 int xen_device_frontend_scanf(XenDevice
*xendev
, const char *key
,
671 const char *fmt
, ...)
673 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
677 g_assert(xenbus
->xsh
);
680 rc
= xs_node_vscanf(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, key
,
687 static void xen_device_frontend_set_state(XenDevice
*xendev
,
688 enum xenbus_state state
)
690 const char *type
= object_get_typename(OBJECT(xendev
));
692 if (xendev
->frontend_state
== state
) {
696 trace_xen_device_frontend_state(type
, xendev
->name
,
699 xendev
->frontend_state
= state
;
700 xen_device_frontend_printf(xendev
, "state", "%u", state
);
703 static void xen_device_frontend_changed(void *opaque
)
705 XenDevice
*xendev
= opaque
;
706 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
707 const char *type
= object_get_typename(OBJECT(xendev
));
708 enum xenbus_state state
;
710 trace_xen_device_frontend_changed(type
, xendev
->name
);
712 if (xen_device_frontend_scanf(xendev
, "state", "%u", &state
) != 1) {
713 state
= XenbusStateUnknown
;
716 xen_device_frontend_set_state(xendev
, state
);
718 if (xendev_class
->frontend_changed
) {
719 Error
*local_err
= NULL
;
721 xendev_class
->frontend_changed(xendev
, state
, &local_err
);
724 error_reportf_err(local_err
, "frontend change error: ");
729 static void xen_device_frontend_create(XenDevice
*xendev
, Error
**errp
)
731 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
732 struct xs_permissions perms
[2];
733 Error
*local_err
= NULL
;
735 xendev
->frontend_path
= xen_device_get_frontend_path(xendev
);
737 perms
[0].id
= xendev
->frontend_id
;
738 perms
[0].perms
= XS_PERM_NONE
;
739 perms
[1].id
= xenbus
->backend_id
;
740 perms
[1].perms
= XS_PERM_READ
| XS_PERM_WRITE
;
742 g_assert(xenbus
->xsh
);
744 xs_node_create(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
, perms
,
745 ARRAY_SIZE(perms
), &local_err
);
747 error_propagate_prepend(errp
, local_err
,
748 "failed to create frontend: ");
752 xendev
->frontend_state_watch
=
753 xen_bus_add_watch(xenbus
, xendev
->frontend_path
, "state",
754 xen_device_frontend_changed
, xendev
, &local_err
);
756 error_propagate_prepend(errp
, local_err
,
757 "failed to watch frontend state: ");
761 static void xen_device_frontend_destroy(XenDevice
*xendev
)
763 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
764 Error
*local_err
= NULL
;
766 if (xendev
->frontend_state_watch
) {
767 xen_bus_remove_watch(xenbus
, xendev
->frontend_state_watch
, NULL
);
768 xendev
->frontend_state_watch
= NULL
;
771 if (!xendev
->frontend_path
) {
775 g_assert(xenbus
->xsh
);
777 xs_node_destroy(xenbus
->xsh
, XBT_NULL
, xendev
->frontend_path
,
779 g_free(xendev
->frontend_path
);
780 xendev
->frontend_path
= NULL
;
783 error_report_err(local_err
);
787 void xen_device_set_max_grant_refs(XenDevice
*xendev
, unsigned int nr_refs
,
790 if (xengnttab_set_max_grants(xendev
->xgth
, nr_refs
)) {
791 error_setg_errno(errp
, errno
, "xengnttab_set_max_grants failed");
795 void *xen_device_map_grant_refs(XenDevice
*xendev
, uint32_t *refs
,
796 unsigned int nr_refs
, int prot
,
799 void *map
= xengnttab_map_domain_grant_refs(xendev
->xgth
, nr_refs
,
800 xendev
->frontend_id
, refs
,
804 error_setg_errno(errp
, errno
,
805 "xengnttab_map_domain_grant_refs failed");
811 void xen_device_unmap_grant_refs(XenDevice
*xendev
, void *map
,
812 unsigned int nr_refs
, Error
**errp
)
814 if (xengnttab_unmap(xendev
->xgth
, map
, nr_refs
)) {
815 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
819 static void compat_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
820 XenDeviceGrantCopySegment segs
[],
821 unsigned int nr_segs
, Error
**errp
)
823 uint32_t *refs
= g_new(uint32_t, nr_segs
);
824 int prot
= to_domain
? PROT_WRITE
: PROT_READ
;
828 for (i
= 0; i
< nr_segs
; i
++) {
829 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
831 refs
[i
] = to_domain
? seg
->dest
.foreign
.ref
:
832 seg
->source
.foreign
.ref
;
835 map
= xengnttab_map_domain_grant_refs(xendev
->xgth
, nr_segs
,
836 xendev
->frontend_id
, refs
,
839 error_setg_errno(errp
, errno
,
840 "xengnttab_map_domain_grant_refs failed");
844 for (i
= 0; i
< nr_segs
; i
++) {
845 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
846 void *page
= map
+ (i
* XC_PAGE_SIZE
);
849 memcpy(page
+ seg
->dest
.foreign
.offset
, seg
->source
.virt
,
852 memcpy(seg
->dest
.virt
, page
+ seg
->source
.foreign
.offset
,
857 if (xengnttab_unmap(xendev
->xgth
, map
, nr_segs
)) {
858 error_setg_errno(errp
, errno
, "xengnttab_unmap failed");
865 void xen_device_copy_grant_refs(XenDevice
*xendev
, bool to_domain
,
866 XenDeviceGrantCopySegment segs
[],
867 unsigned int nr_segs
, Error
**errp
)
869 xengnttab_grant_copy_segment_t
*xengnttab_segs
;
872 if (!xendev
->feature_grant_copy
) {
873 compat_copy_grant_refs(xendev
, to_domain
, segs
, nr_segs
, errp
);
877 xengnttab_segs
= g_new0(xengnttab_grant_copy_segment_t
, nr_segs
);
879 for (i
= 0; i
< nr_segs
; i
++) {
880 XenDeviceGrantCopySegment
*seg
= &segs
[i
];
881 xengnttab_grant_copy_segment_t
*xengnttab_seg
= &xengnttab_segs
[i
];
884 xengnttab_seg
->flags
= GNTCOPY_dest_gref
;
885 xengnttab_seg
->dest
.foreign
.domid
= xendev
->frontend_id
;
886 xengnttab_seg
->dest
.foreign
.ref
= seg
->dest
.foreign
.ref
;
887 xengnttab_seg
->dest
.foreign
.offset
= seg
->dest
.foreign
.offset
;
888 xengnttab_seg
->source
.virt
= seg
->source
.virt
;
890 xengnttab_seg
->flags
= GNTCOPY_source_gref
;
891 xengnttab_seg
->source
.foreign
.domid
= xendev
->frontend_id
;
892 xengnttab_seg
->source
.foreign
.ref
= seg
->source
.foreign
.ref
;
893 xengnttab_seg
->source
.foreign
.offset
=
894 seg
->source
.foreign
.offset
;
895 xengnttab_seg
->dest
.virt
= seg
->dest
.virt
;
898 xengnttab_seg
->len
= seg
->len
;
901 if (xengnttab_grant_copy(xendev
->xgth
, nr_segs
, xengnttab_segs
)) {
902 error_setg_errno(errp
, errno
, "xengnttab_grant_copy failed");
906 for (i
= 0; i
< nr_segs
; i
++) {
907 xengnttab_grant_copy_segment_t
*xengnttab_seg
= &xengnttab_segs
[i
];
909 if (xengnttab_seg
->status
!= GNTST_okay
) {
910 error_setg(errp
, "xengnttab_grant_copy seg[%u] failed", i
);
916 g_free(xengnttab_segs
);
919 struct XenEventChannel
{
920 evtchn_port_t local_port
;
921 XenEventHandler handler
;
926 static void event_notify(Notifier
*n
, void *data
)
928 XenEventChannel
*channel
= container_of(n
, XenEventChannel
, notifier
);
929 unsigned long port
= (unsigned long)data
;
931 if (port
== channel
->local_port
) {
932 channel
->handler(channel
->opaque
);
936 XenEventChannel
*xen_device_bind_event_channel(XenDevice
*xendev
,
938 XenEventHandler handler
,
939 void *opaque
, Error
**errp
)
941 XenEventChannel
*channel
= g_new0(XenEventChannel
, 1);
942 xenevtchn_port_or_error_t local_port
;
944 local_port
= xenevtchn_bind_interdomain(xendev
->xeh
,
947 if (local_port
< 0) {
948 error_setg_errno(errp
, errno
, "xenevtchn_bind_interdomain failed");
954 channel
->local_port
= local_port
;
955 channel
->handler
= handler
;
956 channel
->opaque
= opaque
;
957 channel
->notifier
.notify
= event_notify
;
959 notifier_list_add(&xendev
->event_notifiers
, &channel
->notifier
);
964 void xen_device_notify_event_channel(XenDevice
*xendev
,
965 XenEventChannel
*channel
,
969 error_setg(errp
, "bad channel");
973 if (xenevtchn_notify(xendev
->xeh
, channel
->local_port
) < 0) {
974 error_setg_errno(errp
, errno
, "xenevtchn_notify failed");
978 void xen_device_unbind_event_channel(XenDevice
*xendev
,
979 XenEventChannel
*channel
,
983 error_setg(errp
, "bad channel");
987 notifier_remove(&channel
->notifier
);
989 if (xenevtchn_unbind(xendev
->xeh
, channel
->local_port
) < 0) {
990 error_setg_errno(errp
, errno
, "xenevtchn_unbind failed");
996 static void xen_device_unrealize(DeviceState
*dev
, Error
**errp
)
998 XenDevice
*xendev
= XEN_DEVICE(dev
);
999 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1000 const char *type
= object_get_typename(OBJECT(xendev
));
1002 if (!xendev
->name
) {
1006 trace_xen_device_unrealize(type
, xendev
->name
);
1008 if (xendev
->exit
.notify
) {
1009 qemu_remove_exit_notifier(&xendev
->exit
);
1010 xendev
->exit
.notify
= NULL
;
1013 if (xendev_class
->unrealize
) {
1014 xendev_class
->unrealize(xendev
, errp
);
1017 xen_device_frontend_destroy(xendev
);
1018 xen_device_backend_destroy(xendev
);
1021 qemu_set_fd_handler(xenevtchn_fd(xendev
->xeh
), NULL
, NULL
, NULL
);
1022 xenevtchn_close(xendev
->xeh
);
1027 xengnttab_close(xendev
->xgth
);
1028 xendev
->xgth
= NULL
;
1031 g_free(xendev
->name
);
1032 xendev
->name
= NULL
;
1035 static void xen_device_exit(Notifier
*n
, void *data
)
1037 XenDevice
*xendev
= container_of(n
, XenDevice
, exit
);
1039 xen_device_unrealize(DEVICE(xendev
), &error_abort
);
1042 static void xen_device_event(void *opaque
)
1044 XenDevice
*xendev
= opaque
;
1045 unsigned long port
= xenevtchn_pending(xendev
->xeh
);
1047 notifier_list_notify(&xendev
->event_notifiers
, (void *)port
);
1049 xenevtchn_unmask(xendev
->xeh
, port
);
1052 static void xen_device_realize(DeviceState
*dev
, Error
**errp
)
1054 XenDevice
*xendev
= XEN_DEVICE(dev
);
1055 XenDeviceClass
*xendev_class
= XEN_DEVICE_GET_CLASS(xendev
);
1056 XenBus
*xenbus
= XEN_BUS(qdev_get_parent_bus(DEVICE(xendev
)));
1057 const char *type
= object_get_typename(OBJECT(xendev
));
1058 Error
*local_err
= NULL
;
1060 if (xendev
->frontend_id
== DOMID_INVALID
) {
1061 xendev
->frontend_id
= xen_domid
;
1064 if (xendev
->frontend_id
>= DOMID_FIRST_RESERVED
) {
1065 error_setg(errp
, "invalid frontend-id");
1069 if (!xendev_class
->get_name
) {
1070 error_setg(errp
, "get_name method not implemented");
1074 xendev
->name
= xendev_class
->get_name(xendev
, &local_err
);
1076 error_propagate_prepend(errp
, local_err
,
1077 "failed to get device name: ");
1081 trace_xen_device_realize(type
, xendev
->name
);
1083 xendev
->xgth
= xengnttab_open(NULL
, 0);
1084 if (!xendev
->xgth
) {
1085 error_setg_errno(errp
, errno
, "failed xengnttab_open");
1089 xendev
->feature_grant_copy
=
1090 (xengnttab_grant_copy(xendev
->xgth
, 0, NULL
) == 0);
1092 xendev
->xeh
= xenevtchn_open(NULL
, 0);
1094 error_setg_errno(errp
, errno
, "failed xenevtchn_open");
1098 notifier_list_init(&xendev
->event_notifiers
);
1099 qemu_set_fd_handler(xenevtchn_fd(xendev
->xeh
), xen_device_event
, NULL
,
1102 xen_device_backend_create(xendev
, &local_err
);
1104 error_propagate(errp
, local_err
);
1108 xen_device_frontend_create(xendev
, &local_err
);
1110 error_propagate(errp
, local_err
);
1114 if (xendev_class
->realize
) {
1115 xendev_class
->realize(xendev
, &local_err
);
1117 error_propagate(errp
, local_err
);
1122 xen_device_backend_printf(xendev
, "frontend", "%s",
1123 xendev
->frontend_path
);
1124 xen_device_backend_printf(xendev
, "frontend-id", "%u",
1125 xendev
->frontend_id
);
1126 xen_device_backend_printf(xendev
, "hotplug-status", "connected");
1128 xen_device_backend_set_online(xendev
, true);
1129 xen_device_backend_set_state(xendev
, XenbusStateInitWait
);
1131 xen_device_frontend_printf(xendev
, "backend", "%s",
1132 xendev
->backend_path
);
1133 xen_device_frontend_printf(xendev
, "backend-id", "%u",
1134 xenbus
->backend_id
);
1136 xen_device_frontend_set_state(xendev
, XenbusStateInitialising
);
1138 xendev
->exit
.notify
= xen_device_exit
;
1139 qemu_add_exit_notifier(&xendev
->exit
);
1143 xen_device_unrealize(dev
, &error_abort
);
1146 static Property xen_device_props
[] = {
1147 DEFINE_PROP_UINT16("frontend-id", XenDevice
, frontend_id
,
1149 DEFINE_PROP_END_OF_LIST()
1152 static void xen_device_class_init(ObjectClass
*class, void *data
)
1154 DeviceClass
*dev_class
= DEVICE_CLASS(class);
1156 dev_class
->realize
= xen_device_realize
;
1157 dev_class
->unrealize
= xen_device_unrealize
;
1158 dev_class
->props
= xen_device_props
;
1159 dev_class
->bus_type
= TYPE_XEN_BUS
;
1162 static const TypeInfo xen_device_type_info
= {
1163 .name
= TYPE_XEN_DEVICE
,
1164 .parent
= TYPE_DEVICE
,
1165 .instance_size
= sizeof(XenDevice
),
1167 .class_size
= sizeof(XenDeviceClass
),
1168 .class_init
= xen_device_class_init
,
1171 typedef struct XenBridge
{
1172 SysBusDevice busdev
;
1175 #define TYPE_XEN_BRIDGE "xen-bridge"
1177 static const TypeInfo xen_bridge_type_info
= {
1178 .name
= TYPE_XEN_BRIDGE
,
1179 .parent
= TYPE_SYS_BUS_DEVICE
,
1180 .instance_size
= sizeof(XenBridge
),
1183 static void xen_register_types(void)
1185 type_register_static(&xen_bridge_type_info
);
1186 type_register_static(&xen_bus_type_info
);
1187 type_register_static(&xen_device_type_info
);
1190 type_init(xen_register_types
)
1192 void xen_bus_init(void)
1194 DeviceState
*dev
= qdev_create(NULL
, TYPE_XEN_BRIDGE
);
1195 BusState
*bus
= qbus_create(TYPE_XEN_BUS
, dev
, NULL
);
1197 qdev_init_nofail(dev
);
1198 qbus_set_bus_hotplug_handler(bus
, &error_abort
);