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/log.h"
  31#include "qemu/main-loop.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_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev));
 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_create(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