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