qemu/hw/xen/xen_backend.c
<<
>>
Prefs
   1/*
   2 *  xen backend driver infrastructure
   3 *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com>
   4 *
   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.
   8 *
   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.
  13 *
  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/>.
  16 *
  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.
  19 */
  20
  21/*
  22 * TODO: add some xenbus / xenstore concepts overview here.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include <sys/signal.h>
  27
  28#include "hw/hw.h"
  29#include "hw/sysbus.h"
  30#include "hw/boards.h"
  31#include "sysemu/char.h"
  32#include "qemu/log.h"
  33#include "qapi/error.h"
  34#include "hw/xen/xen_backend.h"
  35#include "hw/xen/xen_pvdev.h"
  36#include "monitor/qdev.h"
  37
  38#include <xen/grant_table.h>
  39
  40DeviceState *xen_sysdev;
  41BusState *xen_sysbus;
  42
  43/* ------------------------------------------------------------- */
  44
  45/* public */
  46xc_interface *xen_xc = NULL;
  47xenforeignmemory_handle *xen_fmem = NULL;
  48struct xs_handle *xenstore = NULL;
  49const char *xen_protocol;
  50
  51/* private */
  52static int debug;
  53
  54int xenstore_write_be_str(struct XenDevice *xendev, const char *node, const char *val)
  55{
  56    return xenstore_write_str(xendev->be, node, val);
  57}
  58
  59int xenstore_write_be_int(struct XenDevice *xendev, const char *node, int ival)
  60{
  61    return xenstore_write_int(xendev->be, node, ival);
  62}
  63
  64int xenstore_write_be_int64(struct XenDevice *xendev, const char *node, int64_t ival)
  65{
  66    return xenstore_write_int64(xendev->be, node, ival);
  67}
  68
  69char *xenstore_read_be_str(struct XenDevice *xendev, const char *node)
  70{
  71    return xenstore_read_str(xendev->be, node);
  72}
  73
  74int xenstore_read_be_int(struct XenDevice *xendev, const char *node, int *ival)
  75{
  76    return xenstore_read_int(xendev->be, node, ival);
  77}
  78
  79char *xenstore_read_fe_str(struct XenDevice *xendev, const char *node)
  80{
  81    return xenstore_read_str(xendev->fe, node);
  82}
  83
  84int xenstore_read_fe_int(struct XenDevice *xendev, const char *node, int *ival)
  85{
  86    return xenstore_read_int(xendev->fe, node, ival);
  87}
  88
  89int xenstore_read_fe_uint64(struct XenDevice *xendev, const char *node,
  90                            uint64_t *uval)
  91{
  92    return xenstore_read_uint64(xendev->fe, node, uval);
  93}
  94
  95/* ------------------------------------------------------------- */
  96
  97int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state)
  98{
  99    int rc;
 100
 101    rc = xenstore_write_be_int(xendev, "state", state);
 102    if (rc < 0) {
 103        return rc;
 104    }
 105    xen_pv_printf(xendev, 1, "backend state: %s -> %s\n",
 106                  xenbus_strstate(xendev->be_state), xenbus_strstate(state));
 107    xendev->be_state = state;
 108    return 0;
 109}
 110
 111/*
 112 * get xen backend device, allocate a new one if it doesn't exist.
 113 */
 114static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
 115                                           struct XenDevOps *ops)
 116{
 117    struct XenDevice *xendev;
 118
 119    xendev = xen_pv_find_xendev(type, dom, dev);
 120    if (xendev) {
 121        return xendev;
 122    }
 123
 124    /* init new xendev */
 125    xendev = g_malloc0(ops->size);
 126    object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND);
 127    qdev_set_parent_bus(&xendev->qdev, xen_sysbus);
 128    qdev_set_id(&xendev->qdev, g_strdup_printf("xen-%s-%d", type, dev));
 129    qdev_init_nofail(&xendev->qdev);
 130    object_unref(OBJECT(&xendev->qdev));
 131
 132    xendev->type  = type;
 133    xendev->dom   = dom;
 134    xendev->dev   = dev;
 135    xendev->ops   = ops;
 136
 137    snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d",
 138             xendev->type, xendev->dom, xendev->dev);
 139    snprintf(xendev->name, sizeof(xendev->name), "%s-%d",
 140             xendev->type, xendev->dev);
 141
 142    xendev->debug      = debug;
 143    xendev->local_port = -1;
 144
 145    xendev->evtchndev = xenevtchn_open(NULL, 0);
 146    if (xendev->evtchndev == NULL) {
 147        xen_pv_printf(NULL, 0, "can't open evtchn device\n");
 148        g_free(xendev);
 149        return NULL;
 150    }
 151    fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
 152
 153    if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
 154        xendev->gnttabdev = xengnttab_open(NULL, 0);
 155        if (xendev->gnttabdev == NULL) {
 156            xen_pv_printf(NULL, 0, "can't open gnttab device\n");
 157            xenevtchn_close(xendev->evtchndev);
 158            g_free(xendev);
 159            return NULL;
 160        }
 161    } else {
 162        xendev->gnttabdev = NULL;
 163    }
 164
 165    xen_pv_insert_xendev(xendev);
 166
 167    if (xendev->ops->alloc) {
 168        xendev->ops->alloc(xendev);
 169    }
 170
 171    return xendev;
 172}
 173
 174
 175/*
 176 * Sync internal data structures on xenstore updates.
 177 * Node specifies the changed field.  node = NULL means
 178 * update all fields (used for initialization).
 179 */
 180static void xen_be_backend_changed(struct XenDevice *xendev, const char *node)
 181{
 182    if (node == NULL  ||  strcmp(node, "online") == 0) {
 183        if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) {
 184            xendev->online = 0;
 185        }
 186    }
 187
 188    if (node) {
 189        xen_pv_printf(xendev, 2, "backend update: %s\n", node);
 190        if (xendev->ops->backend_changed) {
 191            xendev->ops->backend_changed(xendev, node);
 192        }
 193    }
 194}
 195
 196static void xen_be_frontend_changed(struct XenDevice *xendev, const char *node)
 197{
 198    int fe_state;
 199
 200    if (node == NULL  ||  strcmp(node, "state") == 0) {
 201        if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) {
 202            fe_state = XenbusStateUnknown;
 203        }
 204        if (xendev->fe_state != fe_state) {
 205            xen_pv_printf(xendev, 1, "frontend state: %s -> %s\n",
 206                          xenbus_strstate(xendev->fe_state),
 207                          xenbus_strstate(fe_state));
 208        }
 209        xendev->fe_state = fe_state;
 210    }
 211    if (node == NULL  ||  strcmp(node, "protocol") == 0) {
 212        g_free(xendev->protocol);
 213        xendev->protocol = xenstore_read_fe_str(xendev, "protocol");
 214        if (xendev->protocol) {
 215            xen_pv_printf(xendev, 1, "frontend protocol: %s\n",
 216                          xendev->protocol);
 217        }
 218    }
 219
 220    if (node) {
 221        xen_pv_printf(xendev, 2, "frontend update: %s\n", node);
 222        if (xendev->ops->frontend_changed) {
 223            xendev->ops->frontend_changed(xendev, node);
 224        }
 225    }
 226}
 227
 228/* ------------------------------------------------------------- */
 229/* Check for possible state transitions and perform them.        */
 230
 231/*
 232 * Initial xendev setup.  Read frontend path, register watch for it.
 233 * Should succeed once xend finished setting up the backend device.
 234 *
 235 * Also sets initial state (-> Initializing) when done.  Which
 236 * only affects the xendev->be_state variable as xenbus should
 237 * already be put into that state by xend.
 238 */
 239static int xen_be_try_setup(struct XenDevice *xendev)
 240{
 241    char token[XEN_BUFSIZE];
 242    int be_state;
 243
 244    if (xenstore_read_be_int(xendev, "state", &be_state) == -1) {
 245        xen_pv_printf(xendev, 0, "reading backend state failed\n");
 246        return -1;
 247    }
 248
 249    if (be_state != XenbusStateInitialising) {
 250        xen_pv_printf(xendev, 0, "initial backend state is wrong (%s)\n",
 251                      xenbus_strstate(be_state));
 252        return -1;
 253    }
 254
 255    xendev->fe = xenstore_read_be_str(xendev, "frontend");
 256    if (xendev->fe == NULL) {
 257        xen_pv_printf(xendev, 0, "reading frontend path failed\n");
 258        return -1;
 259    }
 260
 261    /* setup frontend watch */
 262    snprintf(token, sizeof(token), "fe:%p", xendev);
 263    if (!xs_watch(xenstore, xendev->fe, token)) {
 264        xen_pv_printf(xendev, 0, "watching frontend path (%s) failed\n",
 265                      xendev->fe);
 266        return -1;
 267    }
 268    xen_be_set_state(xendev, XenbusStateInitialising);
 269
 270    xen_be_backend_changed(xendev, NULL);
 271    xen_be_frontend_changed(xendev, NULL);
 272    return 0;
 273}
 274
 275/*
 276 * Try initialize xendev.  Prepare everything the backend can do
 277 * without synchronizing with the frontend.  Fakes hotplug-status.  No
 278 * hotplug involved here because this is about userspace drivers, thus
 279 * there are kernel backend devices which could invoke hotplug.
 280 *
 281 * Goes to InitWait on success.
 282 */
 283static int xen_be_try_init(struct XenDevice *xendev)
 284{
 285    int rc = 0;
 286
 287    if (!xendev->online) {
 288        xen_pv_printf(xendev, 1, "not online\n");
 289        return -1;
 290    }
 291
 292    if (xendev->ops->init) {
 293        rc = xendev->ops->init(xendev);
 294    }
 295    if (rc != 0) {
 296        xen_pv_printf(xendev, 1, "init() failed\n");
 297        return rc;
 298    }
 299
 300    xenstore_write_be_str(xendev, "hotplug-status", "connected");
 301    xen_be_set_state(xendev, XenbusStateInitWait);
 302    return 0;
 303}
 304
 305/*
 306 * Try to initialise xendev.  Depends on the frontend being ready
 307 * for it (shared ring and evtchn info in xenstore, state being
 308 * Initialised or Connected).
 309 *
 310 * Goes to Connected on success.
 311 */
 312static int xen_be_try_initialise(struct XenDevice *xendev)
 313{
 314    int rc = 0;
 315
 316    if (xendev->fe_state != XenbusStateInitialised  &&
 317        xendev->fe_state != XenbusStateConnected) {
 318        if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
 319            xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n");
 320        } else {
 321            xen_pv_printf(xendev, 2, "frontend not ready (yet)\n");
 322            return -1;
 323        }
 324    }
 325
 326    if (xendev->ops->initialise) {
 327        rc = xendev->ops->initialise(xendev);
 328    }
 329    if (rc != 0) {
 330        xen_pv_printf(xendev, 0, "initialise() failed\n");
 331        return rc;
 332    }
 333
 334    xen_be_set_state(xendev, XenbusStateConnected);
 335    return 0;
 336}
 337
 338/*
 339 * Try to let xendev know that it is connected.  Depends on the
 340 * frontend being Connected.  Note that this may be called more
 341 * than once since the backend state is not modified.
 342 */
 343static void xen_be_try_connected(struct XenDevice *xendev)
 344{
 345    if (!xendev->ops->connected) {
 346        return;
 347    }
 348
 349    if (xendev->fe_state != XenbusStateConnected) {
 350        if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) {
 351            xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n");
 352        } else {
 353            xen_pv_printf(xendev, 2, "frontend not ready (yet)\n");
 354            return;
 355        }
 356    }
 357
 358    xendev->ops->connected(xendev);
 359}
 360
 361/*
 362 * Teardown connection.
 363 *
 364 * Goes to Closed when done.
 365 */
 366static void xen_be_disconnect(struct XenDevice *xendev, enum xenbus_state state)
 367{
 368    if (xendev->be_state != XenbusStateClosing &&
 369        xendev->be_state != XenbusStateClosed  &&
 370        xendev->ops->disconnect) {
 371        xendev->ops->disconnect(xendev);
 372    }
 373    if (xendev->be_state != state) {
 374        xen_be_set_state(xendev, state);
 375    }
 376}
 377
 378/*
 379 * Try to reset xendev, for reconnection by another frontend instance.
 380 */
 381static int xen_be_try_reset(struct XenDevice *xendev)
 382{
 383    if (xendev->fe_state != XenbusStateInitialising) {
 384        return -1;
 385    }
 386
 387    xen_pv_printf(xendev, 1, "device reset (for re-connect)\n");
 388    xen_be_set_state(xendev, XenbusStateInitialising);
 389    return 0;
 390}
 391
 392/*
 393 * state change dispatcher function
 394 */
 395void xen_be_check_state(struct XenDevice *xendev)
 396{
 397    int rc = 0;
 398
 399    /* frontend may request shutdown from almost anywhere */
 400    if (xendev->fe_state == XenbusStateClosing ||
 401        xendev->fe_state == XenbusStateClosed) {
 402        xen_be_disconnect(xendev, xendev->fe_state);
 403        return;
 404    }
 405
 406    /* check for possible backend state transitions */
 407    for (;;) {
 408        switch (xendev->be_state) {
 409        case XenbusStateUnknown:
 410            rc = xen_be_try_setup(xendev);
 411            break;
 412        case XenbusStateInitialising:
 413            rc = xen_be_try_init(xendev);
 414            break;
 415        case XenbusStateInitWait:
 416            rc = xen_be_try_initialise(xendev);
 417            break;
 418        case XenbusStateConnected:
 419            /* xendev->be_state doesn't change */
 420            xen_be_try_connected(xendev);
 421            rc = -1;
 422            break;
 423        case XenbusStateClosed:
 424            rc = xen_be_try_reset(xendev);
 425            break;
 426        default:
 427            rc = -1;
 428        }
 429        if (rc != 0) {
 430            break;
 431        }
 432    }
 433}
 434
 435/* ------------------------------------------------------------- */
 436
 437static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops)
 438{
 439    struct XenDevice *xendev;
 440    char path[XEN_BUFSIZE], token[XEN_BUFSIZE];
 441    char **dev = NULL;
 442    unsigned int cdev, j;
 443
 444    /* setup watch */
 445    snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops);
 446    snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
 447    if (!xs_watch(xenstore, path, token)) {
 448        xen_pv_printf(NULL, 0, "xen be: watching backend path (%s) failed\n",
 449                      path);
 450        return -1;
 451    }
 452
 453    /* look for backends */
 454    dev = xs_directory(xenstore, 0, path, &cdev);
 455    if (!dev) {
 456        return 0;
 457    }
 458    for (j = 0; j < cdev; j++) {
 459        xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops);
 460        if (xendev == NULL) {
 461            continue;
 462        }
 463        xen_be_check_state(xendev);
 464    }
 465    free(dev);
 466    return 0;
 467}
 468
 469void xenstore_update_be(char *watch, char *type, int dom,
 470                        struct XenDevOps *ops)
 471{
 472    struct XenDevice *xendev;
 473    char path[XEN_BUFSIZE], *bepath;
 474    unsigned int len, dev;
 475
 476    len = snprintf(path, sizeof(path), "backend/%s/%d", type, dom);
 477    if (strncmp(path, watch, len) != 0) {
 478        return;
 479    }
 480    if (sscanf(watch+len, "/%u/%255s", &dev, path) != 2) {
 481        strcpy(path, "");
 482        if (sscanf(watch+len, "/%u", &dev) != 1) {
 483            dev = -1;
 484        }
 485    }
 486    if (dev == -1) {
 487        return;
 488    }
 489
 490    xendev = xen_be_get_xendev(type, dom, dev, ops);
 491    if (xendev != NULL) {
 492        bepath = xs_read(xenstore, 0, xendev->be, &len);
 493        if (bepath == NULL) {
 494            xen_pv_del_xendev(xendev);
 495        } else {
 496            free(bepath);
 497            xen_be_backend_changed(xendev, path);
 498            xen_be_check_state(xendev);
 499        }
 500    }
 501}
 502
 503void xenstore_update_fe(char *watch, struct XenDevice *xendev)
 504{
 505    char *node;
 506    unsigned int len;
 507
 508    len = strlen(xendev->fe);
 509    if (strncmp(xendev->fe, watch, len) != 0) {
 510        return;
 511    }
 512    if (watch[len] != '/') {
 513        return;
 514    }
 515    node = watch + len + 1;
 516
 517    xen_be_frontend_changed(xendev, node);
 518    xen_be_check_state(xendev);
 519}
 520/* -------------------------------------------------------------------- */
 521
 522int xen_be_init(void)
 523{
 524    xenstore = xs_daemon_open();
 525    if (!xenstore) {
 526        xen_pv_printf(NULL, 0, "can't connect to xenstored\n");
 527        return -1;
 528    }
 529
 530    qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL);
 531
 532    if (xen_xc == NULL || xen_fmem == NULL) {
 533        /* Check if xen_init() have been called */
 534        goto err;
 535    }
 536
 537    xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
 538    qdev_init_nofail(xen_sysdev);
 539    xen_sysbus = qbus_create(TYPE_XENSYSBUS, DEVICE(xen_sysdev), "xen-sysbus");
 540    qbus_set_bus_hotplug_handler(xen_sysbus, &error_abort);
 541
 542    return 0;
 543
 544err:
 545    qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL);
 546    xs_daemon_close(xenstore);
 547    xenstore = NULL;
 548
 549    return -1;
 550}
 551
 552static void xen_set_dynamic_sysbus(void)
 553{
 554    Object *machine = qdev_get_machine();
 555    ObjectClass *oc = object_get_class(machine);
 556    MachineClass *mc = MACHINE_CLASS(oc);
 557
 558    mc->has_dynamic_sysbus = true;
 559}
 560
 561int xen_be_register(const char *type, struct XenDevOps *ops)
 562{
 563    char path[50];
 564    int rc;
 565
 566    if (ops->backend_register) {
 567        rc = ops->backend_register();
 568        if (rc) {
 569            return rc;
 570        }
 571    }
 572
 573    snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid,
 574             type);
 575    xenstore_mkdir(path, XS_PERM_NONE);
 576
 577    return xenstore_scan(type, xen_domid, ops);
 578}
 579
 580void xen_be_register_common(void)
 581{
 582    xen_set_dynamic_sysbus();
 583
 584    xen_be_register("console", &xen_console_ops);
 585    xen_be_register("vkbd", &xen_kbdmouse_ops);
 586    xen_be_register("qdisk", &xen_blkdev_ops);
 587#ifdef CONFIG_USB_LIBUSB
 588    xen_be_register("qusb", &xen_usb_ops);
 589#endif
 590}
 591
 592int xen_be_bind_evtchn(struct XenDevice *xendev)
 593{
 594    if (xendev->local_port != -1) {
 595        return 0;
 596    }
 597    xendev->local_port = xenevtchn_bind_interdomain
 598        (xendev->evtchndev, xendev->dom, xendev->remote_port);
 599    if (xendev->local_port == -1) {
 600        xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
 601        return -1;
 602    }
 603    xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
 604    qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
 605                        xen_pv_evtchn_event, NULL, xendev);
 606    return 0;
 607}
 608
 609
 610static Property xendev_properties[] = {
 611    DEFINE_PROP_END_OF_LIST(),
 612};
 613
 614static void xendev_class_init(ObjectClass *klass, void *data)
 615{
 616    DeviceClass *dc = DEVICE_CLASS(klass);
 617
 618    dc->props = xendev_properties;
 619    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
 620}
 621
 622static const TypeInfo xendev_type_info = {
 623    .name          = TYPE_XENBACKEND,
 624    .parent        = TYPE_XENSYSDEV,
 625    .class_init    = xendev_class_init,
 626    .instance_size = sizeof(struct XenDevice),
 627};
 628
 629static void xen_sysbus_class_init(ObjectClass *klass, void *data)
 630{
 631    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 632
 633    hc->unplug = qdev_simple_device_unplug_cb;
 634}
 635
 636static const TypeInfo xensysbus_info = {
 637    .name       = TYPE_XENSYSBUS,
 638    .parent     = TYPE_BUS,
 639    .class_init = xen_sysbus_class_init,
 640    .interfaces = (InterfaceInfo[]) {
 641        { TYPE_HOTPLUG_HANDLER },
 642        { }
 643    }
 644};
 645
 646static int xen_sysdev_init(SysBusDevice *dev)
 647{
 648    return 0;
 649}
 650
 651static Property xen_sysdev_properties[] = {
 652    {/* end of property list */},
 653};
 654
 655static void xen_sysdev_class_init(ObjectClass *klass, void *data)
 656{
 657    DeviceClass *dc = DEVICE_CLASS(klass);
 658    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
 659
 660    k->init = xen_sysdev_init;
 661    dc->props = xen_sysdev_properties;
 662    dc->bus_type = TYPE_XENSYSBUS;
 663}
 664
 665static const TypeInfo xensysdev_info = {
 666    .name          = TYPE_XENSYSDEV,
 667    .parent        = TYPE_SYS_BUS_DEVICE,
 668    .instance_size = sizeof(SysBusDevice),
 669    .class_init    = xen_sysdev_class_init,
 670};
 671
 672static void xenbe_register_types(void)
 673{
 674    type_register_static(&xensysbus_info);
 675    type_register_static(&xensysdev_info);
 676    type_register_static(&xendev_type_info);
 677}
 678
 679type_init(xenbe_register_types)
 680