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