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