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