qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

xen-legacy-backend.c (24172B)


      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 
     36 DeviceState *xen_sysdev;
     37 BusState *xen_sysbus;
     38 
     39 /* ------------------------------------------------------------- */
     40 
     41 /* public */
     42 struct xs_handle *xenstore;
     43 const char *xen_protocol;
     44 
     45 /* private */
     46 static bool xen_feature_grant_copy;
     47 static int debug;
     48 
     49 int 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 
     55 int 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 
     61 int 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 
     67 char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node)
     68 {
     69     return xenstore_read_str(xendev->be, node);
     70 }
     71 
     72 int 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 
     78 char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node)
     79 {
     80     return xenstore_read_str(xendev->fe, node);
     81 }
     82 
     83 int 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 
     89 int 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 
     97 int 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 
    111 void 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 
    122 void *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 
    140 void 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 
    151 static 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 
    200 int 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  */
    264 static 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  */
    320 static 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 
    337 static 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  */
    381 static 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  */
    425 static 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  */
    454 static 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  */
    495 static 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  */
    518 static 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  */
    538 static 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  */
    552 void 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 
    594 static 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 
    626 void 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 
    660 void 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 
    679 int 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 
    711 err:
    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 
    719 static 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 
    728 int 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 
    747 void 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 
    761 int 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 
    779 static Property xendev_properties[] = {
    780     DEFINE_PROP_END_OF_LIST(),
    781 };
    782 
    783 static 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 
    794 static 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 
    801 static 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 
    808 static 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 
    818 static Property xen_sysdev_properties[] = {
    819     {/* end of property list */},
    820 };
    821 
    822 static 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 
    829 static 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 
    836 static 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 
    843 type_init(xenbe_register_types)