2 * xen backend driver infrastructure
3 * (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; under version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Contributions after 2012-01-13 are licensed under the terms of the
18 * GNU GPL, version 2 or (at your option) any later version.
22 * TODO: add some xenbus / xenstore concepts overview here.
25 #include "qemu/osdep.h"
26 #include <sys/signal.h>
29 #include "hw/sysbus.h"
30 #include "sysemu/char.h"
32 #include "hw/xen/xen_backend.h"
33 #include "hw/xen/xen_pvdev.h"
35 #include <xen/grant_table.h>
37 #define TYPE_XENSYSDEV "xensysdev"
39 DeviceState
*xen_sysdev
;
41 /* ------------------------------------------------------------- */
44 xc_interface
*xen_xc
= NULL
;
45 xenforeignmemory_handle
*xen_fmem
= NULL
;
46 struct xs_handle
*xenstore
= NULL
;
47 const char *xen_protocol
;
52 int xenstore_write_be_str(struct XenDevice
*xendev
, const char *node
, const char *val
)
54 return xenstore_write_str(xendev
->be
, node
, val
);
57 int xenstore_write_be_int(struct XenDevice
*xendev
, const char *node
, int ival
)
59 return xenstore_write_int(xendev
->be
, node
, ival
);
62 int xenstore_write_be_int64(struct XenDevice
*xendev
, const char *node
, int64_t ival
)
64 return xenstore_write_int64(xendev
->be
, node
, ival
);
67 char *xenstore_read_be_str(struct XenDevice
*xendev
, const char *node
)
69 return xenstore_read_str(xendev
->be
, node
);
72 int xenstore_read_be_int(struct XenDevice
*xendev
, const char *node
, int *ival
)
74 return xenstore_read_int(xendev
->be
, node
, ival
);
77 char *xenstore_read_fe_str(struct XenDevice
*xendev
, const char *node
)
79 return xenstore_read_str(xendev
->fe
, node
);
82 int xenstore_read_fe_int(struct XenDevice
*xendev
, const char *node
, int *ival
)
84 return xenstore_read_int(xendev
->fe
, node
, ival
);
87 int xenstore_read_fe_uint64(struct XenDevice
*xendev
, const char *node
,
90 return xenstore_read_uint64(xendev
->fe
, node
, uval
);
93 /* ------------------------------------------------------------- */
95 int xen_be_set_state(struct XenDevice
*xendev
, enum xenbus_state state
)
99 rc
= xenstore_write_be_int(xendev
, "state", state
);
103 xen_be_printf(xendev
, 1, "backend state: %s -> %s\n",
104 xenbus_strstate(xendev
->be_state
), xenbus_strstate(state
));
105 xendev
->be_state
= state
;
110 * get xen backend device, allocate a new one if it doesn't exist.
112 static struct XenDevice
*xen_be_get_xendev(const char *type
, int dom
, int dev
,
113 struct XenDevOps
*ops
)
115 struct XenDevice
*xendev
;
117 xendev
= xen_be_find_xendev(type
, dom
, dev
);
122 /* init new xendev */
123 xendev
= g_malloc0(ops
->size
);
129 snprintf(xendev
->be
, sizeof(xendev
->be
), "backend/%s/%d/%d",
130 xendev
->type
, xendev
->dom
, xendev
->dev
);
131 snprintf(xendev
->name
, sizeof(xendev
->name
), "%s-%d",
132 xendev
->type
, xendev
->dev
);
134 xendev
->debug
= debug
;
135 xendev
->local_port
= -1;
137 xendev
->evtchndev
= xenevtchn_open(NULL
, 0);
138 if (xendev
->evtchndev
== NULL
) {
139 xen_be_printf(NULL
, 0, "can't open evtchn device\n");
143 fcntl(xenevtchn_fd(xendev
->evtchndev
), F_SETFD
, FD_CLOEXEC
);
145 if (ops
->flags
& DEVOPS_FLAG_NEED_GNTDEV
) {
146 xendev
->gnttabdev
= xengnttab_open(NULL
, 0);
147 if (xendev
->gnttabdev
== NULL
) {
148 xen_be_printf(NULL
, 0, "can't open gnttab device\n");
149 xenevtchn_close(xendev
->evtchndev
);
154 xendev
->gnttabdev
= NULL
;
157 xen_pv_insert_xendev(xendev
);
159 if (xendev
->ops
->alloc
) {
160 xendev
->ops
->alloc(xendev
);
168 * Sync internal data structures on xenstore updates.
169 * Node specifies the changed field. node = NULL means
170 * update all fields (used for initialization).
172 static void xen_be_backend_changed(struct XenDevice
*xendev
, const char *node
)
174 if (node
== NULL
|| strcmp(node
, "online") == 0) {
175 if (xenstore_read_be_int(xendev
, "online", &xendev
->online
) == -1) {
181 xen_be_printf(xendev
, 2, "backend update: %s\n", node
);
182 if (xendev
->ops
->backend_changed
) {
183 xendev
->ops
->backend_changed(xendev
, node
);
188 static void xen_be_frontend_changed(struct XenDevice
*xendev
, const char *node
)
192 if (node
== NULL
|| strcmp(node
, "state") == 0) {
193 if (xenstore_read_fe_int(xendev
, "state", &fe_state
) == -1) {
194 fe_state
= XenbusStateUnknown
;
196 if (xendev
->fe_state
!= fe_state
) {
197 xen_be_printf(xendev
, 1, "frontend state: %s -> %s\n",
198 xenbus_strstate(xendev
->fe_state
),
199 xenbus_strstate(fe_state
));
201 xendev
->fe_state
= fe_state
;
203 if (node
== NULL
|| strcmp(node
, "protocol") == 0) {
204 g_free(xendev
->protocol
);
205 xendev
->protocol
= xenstore_read_fe_str(xendev
, "protocol");
206 if (xendev
->protocol
) {
207 xen_be_printf(xendev
, 1, "frontend protocol: %s\n",
213 xen_be_printf(xendev
, 2, "frontend update: %s\n", node
);
214 if (xendev
->ops
->frontend_changed
) {
215 xendev
->ops
->frontend_changed(xendev
, node
);
220 /* ------------------------------------------------------------- */
221 /* Check for possible state transitions and perform them. */
224 * Initial xendev setup. Read frontend path, register watch for it.
225 * Should succeed once xend finished setting up the backend device.
227 * Also sets initial state (-> Initializing) when done. Which
228 * only affects the xendev->be_state variable as xenbus should
229 * already be put into that state by xend.
231 static int xen_be_try_setup(struct XenDevice
*xendev
)
233 char token
[XEN_BUFSIZE
];
236 if (xenstore_read_be_int(xendev
, "state", &be_state
) == -1) {
237 xen_be_printf(xendev
, 0, "reading backend state failed\n");
241 if (be_state
!= XenbusStateInitialising
) {
242 xen_be_printf(xendev
, 0, "initial backend state is wrong (%s)\n",
243 xenbus_strstate(be_state
));
247 xendev
->fe
= xenstore_read_be_str(xendev
, "frontend");
248 if (xendev
->fe
== NULL
) {
249 xen_be_printf(xendev
, 0, "reading frontend path failed\n");
253 /* setup frontend watch */
254 snprintf(token
, sizeof(token
), "fe:%p", xendev
);
255 if (!xs_watch(xenstore
, xendev
->fe
, token
)) {
256 xen_be_printf(xendev
, 0, "watching frontend path (%s) failed\n",
260 xen_be_set_state(xendev
, XenbusStateInitialising
);
262 xen_be_backend_changed(xendev
, NULL
);
263 xen_be_frontend_changed(xendev
, NULL
);
268 * Try initialize xendev. Prepare everything the backend can do
269 * without synchronizing with the frontend. Fakes hotplug-status. No
270 * hotplug involved here because this is about userspace drivers, thus
271 * there are kernel backend devices which could invoke hotplug.
273 * Goes to InitWait on success.
275 static int xen_be_try_init(struct XenDevice
*xendev
)
279 if (!xendev
->online
) {
280 xen_be_printf(xendev
, 1, "not online\n");
284 if (xendev
->ops
->init
) {
285 rc
= xendev
->ops
->init(xendev
);
288 xen_be_printf(xendev
, 1, "init() failed\n");
292 xenstore_write_be_str(xendev
, "hotplug-status", "connected");
293 xen_be_set_state(xendev
, XenbusStateInitWait
);
298 * Try to initialise xendev. Depends on the frontend being ready
299 * for it (shared ring and evtchn info in xenstore, state being
300 * Initialised or Connected).
302 * Goes to Connected on success.
304 static int xen_be_try_initialise(struct XenDevice
*xendev
)
308 if (xendev
->fe_state
!= XenbusStateInitialised
&&
309 xendev
->fe_state
!= XenbusStateConnected
) {
310 if (xendev
->ops
->flags
& DEVOPS_FLAG_IGNORE_STATE
) {
311 xen_be_printf(xendev
, 2, "frontend not ready, ignoring\n");
313 xen_be_printf(xendev
, 2, "frontend not ready (yet)\n");
318 if (xendev
->ops
->initialise
) {
319 rc
= xendev
->ops
->initialise(xendev
);
322 xen_be_printf(xendev
, 0, "initialise() failed\n");
326 xen_be_set_state(xendev
, XenbusStateConnected
);
331 * Try to let xendev know that it is connected. Depends on the
332 * frontend being Connected. Note that this may be called more
333 * than once since the backend state is not modified.
335 static void xen_be_try_connected(struct XenDevice
*xendev
)
337 if (!xendev
->ops
->connected
) {
341 if (xendev
->fe_state
!= XenbusStateConnected
) {
342 if (xendev
->ops
->flags
& DEVOPS_FLAG_IGNORE_STATE
) {
343 xen_be_printf(xendev
, 2, "frontend not ready, ignoring\n");
345 xen_be_printf(xendev
, 2, "frontend not ready (yet)\n");
350 xendev
->ops
->connected(xendev
);
354 * Teardown connection.
356 * Goes to Closed when done.
358 static void xen_be_disconnect(struct XenDevice
*xendev
, enum xenbus_state state
)
360 if (xendev
->be_state
!= XenbusStateClosing
&&
361 xendev
->be_state
!= XenbusStateClosed
&&
362 xendev
->ops
->disconnect
) {
363 xendev
->ops
->disconnect(xendev
);
365 if (xendev
->be_state
!= state
) {
366 xen_be_set_state(xendev
, state
);
371 * Try to reset xendev, for reconnection by another frontend instance.
373 static int xen_be_try_reset(struct XenDevice
*xendev
)
375 if (xendev
->fe_state
!= XenbusStateInitialising
) {
379 xen_be_printf(xendev
, 1, "device reset (for re-connect)\n");
380 xen_be_set_state(xendev
, XenbusStateInitialising
);
385 * state change dispatcher function
387 void xen_be_check_state(struct XenDevice
*xendev
)
391 /* frontend may request shutdown from almost anywhere */
392 if (xendev
->fe_state
== XenbusStateClosing
||
393 xendev
->fe_state
== XenbusStateClosed
) {
394 xen_be_disconnect(xendev
, xendev
->fe_state
);
398 /* check for possible backend state transitions */
400 switch (xendev
->be_state
) {
401 case XenbusStateUnknown
:
402 rc
= xen_be_try_setup(xendev
);
404 case XenbusStateInitialising
:
405 rc
= xen_be_try_init(xendev
);
407 case XenbusStateInitWait
:
408 rc
= xen_be_try_initialise(xendev
);
410 case XenbusStateConnected
:
411 /* xendev->be_state doesn't change */
412 xen_be_try_connected(xendev
);
415 case XenbusStateClosed
:
416 rc
= xen_be_try_reset(xendev
);
427 /* ------------------------------------------------------------- */
429 static int xenstore_scan(const char *type
, int dom
, struct XenDevOps
*ops
)
431 struct XenDevice
*xendev
;
432 char path
[XEN_BUFSIZE
], token
[XEN_BUFSIZE
];
434 unsigned int cdev
, j
;
437 snprintf(token
, sizeof(token
), "be:%p:%d:%p", type
, dom
, ops
);
438 snprintf(path
, sizeof(path
), "backend/%s/%d", type
, dom
);
439 if (!xs_watch(xenstore
, path
, token
)) {
440 xen_be_printf(NULL
, 0, "xen be: watching backend path (%s) failed\n",
445 /* look for backends */
446 dev
= xs_directory(xenstore
, 0, path
, &cdev
);
450 for (j
= 0; j
< cdev
; j
++) {
451 xendev
= xen_be_get_xendev(type
, dom
, atoi(dev
[j
]), ops
);
452 if (xendev
== NULL
) {
455 xen_be_check_state(xendev
);
461 void xenstore_update_be(char *watch
, char *type
, int dom
,
462 struct XenDevOps
*ops
)
464 struct XenDevice
*xendev
;
465 char path
[XEN_BUFSIZE
], *bepath
;
466 unsigned int len
, dev
;
468 len
= snprintf(path
, sizeof(path
), "backend/%s/%d", type
, dom
);
469 if (strncmp(path
, watch
, len
) != 0) {
472 if (sscanf(watch
+len
, "/%u/%255s", &dev
, path
) != 2) {
474 if (sscanf(watch
+len
, "/%u", &dev
) != 1) {
482 xendev
= xen_be_get_xendev(type
, dom
, dev
, ops
);
483 if (xendev
!= NULL
) {
484 bepath
= xs_read(xenstore
, 0, xendev
->be
, &len
);
485 if (bepath
== NULL
) {
486 xen_be_del_xendev(xendev
);
489 xen_be_backend_changed(xendev
, path
);
490 xen_be_check_state(xendev
);
495 void xenstore_update_fe(char *watch
, struct XenDevice
*xendev
)
500 len
= strlen(xendev
->fe
);
501 if (strncmp(xendev
->fe
, watch
, len
) != 0) {
504 if (watch
[len
] != '/') {
507 node
= watch
+ len
+ 1;
509 xen_be_frontend_changed(xendev
, node
);
510 xen_be_check_state(xendev
);
512 /* -------------------------------------------------------------------- */
514 int xen_be_init(void)
516 xenstore
= xs_daemon_open();
518 xen_be_printf(NULL
, 0, "can't connect to xenstored\n");
522 qemu_set_fd_handler(xs_fileno(xenstore
), xenstore_update
, NULL
, NULL
);
524 if (xen_xc
== NULL
|| xen_fmem
== NULL
) {
525 /* Check if xen_init() have been called */
529 xen_sysdev
= qdev_create(NULL
, TYPE_XENSYSDEV
);
530 qdev_init_nofail(xen_sysdev
);
535 qemu_set_fd_handler(xs_fileno(xenstore
), NULL
, NULL
, NULL
);
536 xs_daemon_close(xenstore
);
542 int xen_be_register(const char *type
, struct XenDevOps
*ops
)
547 if (ops
->backend_register
) {
548 rc
= ops
->backend_register();
554 snprintf(path
, sizeof(path
), "device-model/%u/backends/%s", xen_domid
,
556 xenstore_mkdir(path
, XS_PERM_NONE
);
558 return xenstore_scan(type
, xen_domid
, ops
);
561 void xen_be_register_common(void)
563 xen_be_register("console", &xen_console_ops
);
564 xen_be_register("vkbd", &xen_kbdmouse_ops
);
565 xen_be_register("qdisk", &xen_blkdev_ops
);
566 #ifdef CONFIG_USB_LIBUSB
567 xen_be_register("qusb", &xen_usb_ops
);
571 int xen_be_bind_evtchn(struct XenDevice
*xendev
)
573 if (xendev
->local_port
!= -1) {
576 xendev
->local_port
= xenevtchn_bind_interdomain
577 (xendev
->evtchndev
, xendev
->dom
, xendev
->remote_port
);
578 if (xendev
->local_port
== -1) {
579 xen_be_printf(xendev
, 0, "xenevtchn_bind_interdomain failed\n");
582 xen_be_printf(xendev
, 2, "bind evtchn port %d\n", xendev
->local_port
);
583 qemu_set_fd_handler(xenevtchn_fd(xendev
->evtchndev
),
584 xen_be_evtchn_event
, NULL
, xendev
);
589 static int xen_sysdev_init(SysBusDevice
*dev
)
594 static Property xen_sysdev_properties
[] = {
595 {/* end of property list */},
598 static void xen_sysdev_class_init(ObjectClass
*klass
, void *data
)
600 DeviceClass
*dc
= DEVICE_CLASS(klass
);
601 SysBusDeviceClass
*k
= SYS_BUS_DEVICE_CLASS(klass
);
603 k
->init
= xen_sysdev_init
;
604 dc
->props
= xen_sysdev_properties
;
607 static const TypeInfo xensysdev_info
= {
608 .name
= TYPE_XENSYSDEV
,
609 .parent
= TYPE_SYS_BUS_DEVICE
,
610 .instance_size
= sizeof(SysBusDevice
),
611 .class_init
= xen_sysdev_class_init
,
614 static void xenbe_register_types(void)
616 type_register_static(&xensysdev_info
);
619 type_init(xenbe_register_types
);