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