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 qemu_xs_handle *xenstore; 43 const char *xen_protocol; 44 45 /* private */ 46 static int debug; 47 48 int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node, 49 const char *val) 50 { 51 return xenstore_write_str(xendev->be, node, val); 52 } 53 54 int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node, 55 int ival) 56 { 57 return xenstore_write_int(xendev->be, node, ival); 58 } 59 60 int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *node, 61 int64_t ival) 62 { 63 return xenstore_write_int64(xendev->be, node, ival); 64 } 65 66 char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node) 67 { 68 return xenstore_read_str(xendev->be, node); 69 } 70 71 int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node, 72 int *ival) 73 { 74 return xenstore_read_int(xendev->be, node, ival); 75 } 76 77 char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node) 78 { 79 return xenstore_read_str(xendev->fe, node); 80 } 81 82 int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node, 83 int *ival) 84 { 85 return xenstore_read_int(xendev->fe, node, ival); 86 } 87 88 int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node, 89 uint64_t *uval) 90 { 91 return xenstore_read_uint64(xendev->fe, node, uval); 92 } 93 94 /* ------------------------------------------------------------- */ 95 96 int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state) 97 { 98 int rc; 99 100 rc = xenstore_write_be_int(xendev, "state", state); 101 if (rc < 0) { 102 return rc; 103 } 104 xen_pv_printf(xendev, 1, "backend state: %s -> %s\n", 105 xenbus_strstate(xendev->be_state), xenbus_strstate(state)); 106 xendev->be_state = state; 107 return 0; 108 } 109 110 void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev, 111 unsigned int nr_refs) 112 { 113 assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); 114 115 if (qemu_xen_gnttab_set_max_grants(xendev->gnttabdev, nr_refs)) { 116 xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n", 117 strerror(errno)); 118 } 119 } 120 121 void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs, 122 unsigned int nr_refs, int prot) 123 { 124 void *ptr; 125 126 assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); 127 128 ptr = qemu_xen_gnttab_map_refs(xendev->gnttabdev, nr_refs, xen_domid, refs, 129 prot); 130 if (!ptr) { 131 xen_pv_printf(xendev, 0, 132 "xengnttab_map_domain_grant_refs failed: %s\n", 133 strerror(errno)); 134 } 135 136 return ptr; 137 } 138 139 void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr, 140 uint32_t *refs, unsigned int nr_refs) 141 { 142 assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); 143 144 if (qemu_xen_gnttab_unmap(xendev->gnttabdev, ptr, refs, nr_refs)) { 145 xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n", 146 strerror(errno)); 147 } 148 } 149 150 /* 151 * get xen backend device, allocate a new one if it doesn't exist. 152 */ 153 static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom, 154 int dev, 155 const struct XenDevOps *ops) 156 { 157 struct XenLegacyDevice *xendev; 158 159 xendev = xen_pv_find_xendev(type, dom, dev); 160 if (xendev) { 161 return xendev; 162 } 163 164 /* init new xendev */ 165 xendev = g_malloc0(ops->size); 166 object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND); 167 OBJECT(xendev)->free = g_free; 168 qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev), 169 &error_fatal); 170 qdev_realize(DEVICE(xendev), xen_sysbus, &error_fatal); 171 object_unref(OBJECT(xendev)); 172 173 xendev->type = type; 174 xendev->dom = dom; 175 xendev->dev = dev; 176 xendev->ops = ops; 177 178 snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d", 179 xendev->type, xendev->dom, xendev->dev); 180 snprintf(xendev->name, sizeof(xendev->name), "%s-%d", 181 xendev->type, xendev->dev); 182 183 xendev->debug = debug; 184 xendev->local_port = -1; 185 186 xendev->evtchndev = qemu_xen_evtchn_open(); 187 if (xendev->evtchndev == NULL) { 188 xen_pv_printf(NULL, 0, "can't open evtchn device\n"); 189 qdev_unplug(DEVICE(xendev), NULL); 190 return NULL; 191 } 192 qemu_set_cloexec(qemu_xen_evtchn_fd(xendev->evtchndev)); 193 194 xen_pv_insert_xendev(xendev); 195 196 if (xendev->ops->alloc) { 197 xendev->ops->alloc(xendev); 198 } 199 200 return xendev; 201 } 202 203 204 /* 205 * Sync internal data structures on xenstore updates. 206 * Node specifies the changed field. node = NULL means 207 * update all fields (used for initialization). 208 */ 209 static void xen_be_backend_changed(struct XenLegacyDevice *xendev, 210 const char *node) 211 { 212 if (node == NULL || strcmp(node, "online") == 0) { 213 if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) { 214 xendev->online = 0; 215 } 216 } 217 218 if (node) { 219 xen_pv_printf(xendev, 2, "backend update: %s\n", node); 220 if (xendev->ops->backend_changed) { 221 xendev->ops->backend_changed(xendev, node); 222 } 223 } 224 } 225 226 static void xen_be_frontend_changed(struct XenLegacyDevice *xendev, 227 const char *node) 228 { 229 int fe_state; 230 231 if (node == NULL || strcmp(node, "state") == 0) { 232 if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) { 233 fe_state = XenbusStateUnknown; 234 } 235 if (xendev->fe_state != fe_state) { 236 xen_pv_printf(xendev, 1, "frontend state: %s -> %s\n", 237 xenbus_strstate(xendev->fe_state), 238 xenbus_strstate(fe_state)); 239 } 240 xendev->fe_state = fe_state; 241 } 242 if (node == NULL || strcmp(node, "protocol") == 0) { 243 g_free(xendev->protocol); 244 xendev->protocol = xenstore_read_fe_str(xendev, "protocol"); 245 if (xendev->protocol) { 246 xen_pv_printf(xendev, 1, "frontend protocol: %s\n", 247 xendev->protocol); 248 } 249 } 250 251 if (node) { 252 xen_pv_printf(xendev, 2, "frontend update: %s\n", node); 253 if (xendev->ops->frontend_changed) { 254 xendev->ops->frontend_changed(xendev, node); 255 } 256 } 257 } 258 259 static void xenstore_update_fe(void *opaque, const char *watch) 260 { 261 struct XenLegacyDevice *xendev = opaque; 262 const char *node; 263 unsigned int len; 264 265 len = strlen(xendev->fe); 266 if (strncmp(xendev->fe, watch, len) != 0) { 267 return; 268 } 269 if (watch[len] != '/') { 270 return; 271 } 272 node = watch + len + 1; 273 274 xen_be_frontend_changed(xendev, node); 275 xen_be_check_state(xendev); 276 } 277 278 /* ------------------------------------------------------------- */ 279 /* Check for possible state transitions and perform them. */ 280 281 /* 282 * Initial xendev setup. Read frontend path, register watch for it. 283 * Should succeed once xend finished setting up the backend device. 284 * 285 * Also sets initial state (-> Initializing) when done. Which 286 * only affects the xendev->be_state variable as xenbus should 287 * already be put into that state by xend. 288 */ 289 static int xen_be_try_setup(struct XenLegacyDevice *xendev) 290 { 291 int be_state; 292 293 if (xenstore_read_be_int(xendev, "state", &be_state) == -1) { 294 xen_pv_printf(xendev, 0, "reading backend state failed\n"); 295 return -1; 296 } 297 298 if (be_state != XenbusStateInitialising) { 299 xen_pv_printf(xendev, 0, "initial backend state is wrong (%s)\n", 300 xenbus_strstate(be_state)); 301 return -1; 302 } 303 304 xendev->fe = xenstore_read_be_str(xendev, "frontend"); 305 if (xendev->fe == NULL) { 306 xen_pv_printf(xendev, 0, "reading frontend path failed\n"); 307 return -1; 308 } 309 310 /* setup frontend watch */ 311 xendev->watch = qemu_xen_xs_watch(xenstore, xendev->fe, xenstore_update_fe, 312 xendev); 313 if (!xendev->watch) { 314 xen_pv_printf(xendev, 0, "watching frontend path (%s) failed\n", 315 xendev->fe); 316 return -1; 317 } 318 xen_be_set_state(xendev, XenbusStateInitialising); 319 320 xen_be_backend_changed(xendev, NULL); 321 xen_be_frontend_changed(xendev, NULL); 322 return 0; 323 } 324 325 /* 326 * Try initialize xendev. Prepare everything the backend can do 327 * without synchronizing with the frontend. Fakes hotplug-status. No 328 * hotplug involved here because this is about userspace drivers, thus 329 * there are kernel backend devices which could invoke hotplug. 330 * 331 * Goes to InitWait on success. 332 */ 333 static int xen_be_try_init(struct XenLegacyDevice *xendev) 334 { 335 int rc = 0; 336 337 if (!xendev->online) { 338 xen_pv_printf(xendev, 1, "not online\n"); 339 return -1; 340 } 341 342 if (xendev->ops->init) { 343 rc = xendev->ops->init(xendev); 344 } 345 if (rc != 0) { 346 xen_pv_printf(xendev, 1, "init() failed\n"); 347 return rc; 348 } 349 350 xenstore_write_be_str(xendev, "hotplug-status", "connected"); 351 xen_be_set_state(xendev, XenbusStateInitWait); 352 return 0; 353 } 354 355 /* 356 * Try to initialise xendev. Depends on the frontend being ready 357 * for it (shared ring and evtchn info in xenstore, state being 358 * Initialised or Connected). 359 * 360 * Goes to Connected on success. 361 */ 362 static int xen_be_try_initialise(struct XenLegacyDevice *xendev) 363 { 364 int rc = 0; 365 366 if (xendev->fe_state != XenbusStateInitialised && 367 xendev->fe_state != XenbusStateConnected) { 368 if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { 369 xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n"); 370 } else { 371 xen_pv_printf(xendev, 2, "frontend not ready (yet)\n"); 372 return -1; 373 } 374 } 375 376 if (xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV) { 377 xendev->gnttabdev = qemu_xen_gnttab_open(); 378 if (xendev->gnttabdev == NULL) { 379 xen_pv_printf(NULL, 0, "can't open gnttab device\n"); 380 return -1; 381 } 382 } else { 383 xendev->gnttabdev = NULL; 384 } 385 386 if (xendev->ops->initialise) { 387 rc = xendev->ops->initialise(xendev); 388 } 389 if (rc != 0) { 390 xen_pv_printf(xendev, 0, "initialise() failed\n"); 391 return rc; 392 } 393 394 xen_be_set_state(xendev, XenbusStateConnected); 395 return 0; 396 } 397 398 /* 399 * Try to let xendev know that it is connected. Depends on the 400 * frontend being Connected. Note that this may be called more 401 * than once since the backend state is not modified. 402 */ 403 static void xen_be_try_connected(struct XenLegacyDevice *xendev) 404 { 405 if (!xendev->ops->connected) { 406 return; 407 } 408 409 if (xendev->fe_state != XenbusStateConnected) { 410 if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { 411 xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n"); 412 } else { 413 xen_pv_printf(xendev, 2, "frontend not ready (yet)\n"); 414 return; 415 } 416 } 417 418 xendev->ops->connected(xendev); 419 } 420 421 /* 422 * Teardown connection. 423 * 424 * Goes to Closed when done. 425 */ 426 static void xen_be_disconnect(struct XenLegacyDevice *xendev, 427 enum xenbus_state state) 428 { 429 if (xendev->be_state != XenbusStateClosing && 430 xendev->be_state != XenbusStateClosed && 431 xendev->ops->disconnect) { 432 xendev->ops->disconnect(xendev); 433 } 434 if (xendev->gnttabdev) { 435 qemu_xen_gnttab_close(xendev->gnttabdev); 436 xendev->gnttabdev = NULL; 437 } 438 if (xendev->be_state != state) { 439 xen_be_set_state(xendev, state); 440 } 441 } 442 443 /* 444 * Try to reset xendev, for reconnection by another frontend instance. 445 */ 446 static int xen_be_try_reset(struct XenLegacyDevice *xendev) 447 { 448 if (xendev->fe_state != XenbusStateInitialising) { 449 return -1; 450 } 451 452 xen_pv_printf(xendev, 1, "device reset (for re-connect)\n"); 453 xen_be_set_state(xendev, XenbusStateInitialising); 454 return 0; 455 } 456 457 /* 458 * state change dispatcher function 459 */ 460 void xen_be_check_state(struct XenLegacyDevice *xendev) 461 { 462 int rc = 0; 463 464 /* frontend may request shutdown from almost anywhere */ 465 if (xendev->fe_state == XenbusStateClosing || 466 xendev->fe_state == XenbusStateClosed) { 467 xen_be_disconnect(xendev, xendev->fe_state); 468 return; 469 } 470 471 /* check for possible backend state transitions */ 472 for (;;) { 473 switch (xendev->be_state) { 474 case XenbusStateUnknown: 475 rc = xen_be_try_setup(xendev); 476 break; 477 case XenbusStateInitialising: 478 rc = xen_be_try_init(xendev); 479 break; 480 case XenbusStateInitWait: 481 rc = xen_be_try_initialise(xendev); 482 break; 483 case XenbusStateConnected: 484 /* xendev->be_state doesn't change */ 485 xen_be_try_connected(xendev); 486 rc = -1; 487 break; 488 case XenbusStateClosed: 489 rc = xen_be_try_reset(xendev); 490 break; 491 default: 492 rc = -1; 493 } 494 if (rc != 0) { 495 break; 496 } 497 } 498 } 499 500 /* ------------------------------------------------------------- */ 501 502 struct xenstore_be { 503 const char *type; 504 int dom; 505 const struct XenDevOps *ops; 506 }; 507 508 static void xenstore_update_be(void *opaque, const char *watch) 509 { 510 struct xenstore_be *be = opaque; 511 struct XenLegacyDevice *xendev; 512 char path[XEN_BUFSIZE], *bepath; 513 unsigned int len, dev; 514 515 len = snprintf(path, sizeof(path), "backend/%s/%d", be->type, be->dom); 516 if (strncmp(path, watch, len) != 0) { 517 return; 518 } 519 if (sscanf(watch + len, "/%u/%255s", &dev, path) != 2) { 520 strcpy(path, ""); 521 if (sscanf(watch + len, "/%u", &dev) != 1) { 522 dev = -1; 523 } 524 } 525 if (dev == -1) { 526 return; 527 } 528 529 xendev = xen_be_get_xendev(be->type, be->dom, dev, be->ops); 530 if (xendev != NULL) { 531 bepath = qemu_xen_xs_read(xenstore, 0, xendev->be, &len); 532 if (bepath == NULL) { 533 xen_pv_del_xendev(xendev); 534 } else { 535 free(bepath); 536 xen_be_backend_changed(xendev, path); 537 xen_be_check_state(xendev); 538 } 539 } 540 } 541 542 static int xenstore_scan(const char *type, int dom, const struct XenDevOps *ops) 543 { 544 struct XenLegacyDevice *xendev; 545 char path[XEN_BUFSIZE]; 546 struct xenstore_be *be = g_new0(struct xenstore_be, 1); 547 char **dev = NULL; 548 unsigned int cdev, j; 549 550 /* setup watch */ 551 be->type = type; 552 be->dom = dom; 553 be->ops = ops; 554 snprintf(path, sizeof(path), "backend/%s/%d", type, dom); 555 if (!qemu_xen_xs_watch(xenstore, path, xenstore_update_be, be)) { 556 xen_pv_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", 557 path); 558 return -1; 559 } 560 561 /* look for backends */ 562 dev = qemu_xen_xs_directory(xenstore, 0, path, &cdev); 563 if (!dev) { 564 return 0; 565 } 566 for (j = 0; j < cdev; j++) { 567 xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops); 568 if (xendev == NULL) { 569 continue; 570 } 571 xen_be_check_state(xendev); 572 } 573 free(dev); 574 return 0; 575 } 576 577 /* -------------------------------------------------------------------- */ 578 579 static void xen_set_dynamic_sysbus(void) 580 { 581 Object *machine = qdev_get_machine(); 582 ObjectClass *oc = object_get_class(machine); 583 MachineClass *mc = MACHINE_CLASS(oc); 584 585 machine_class_allow_dynamic_sysbus_dev(mc, TYPE_XENSYSDEV); 586 } 587 588 void xen_be_init(void) 589 { 590 xenstore = qemu_xen_xs_open(); 591 if (!xenstore) { 592 xen_pv_printf(NULL, 0, "can't connect to xenstored\n"); 593 exit(1); 594 } 595 596 if (xen_evtchn_ops == NULL || xen_gnttab_ops == NULL) { 597 xen_pv_printf(NULL, 0, "Xen operations not set up\n"); 598 exit(1); 599 } 600 601 xen_sysdev = qdev_new(TYPE_XENSYSDEV); 602 sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal); 603 xen_sysbus = qbus_new(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus"); 604 qbus_set_bus_hotplug_handler(xen_sysbus); 605 606 xen_set_dynamic_sysbus(); 607 } 608 609 int xen_be_register(const char *type, const struct XenDevOps *ops) 610 { 611 char path[50]; 612 613 snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid, 614 type); 615 xenstore_mkdir(path, XS_PERM_NONE); 616 617 return xenstore_scan(type, xen_domid, ops); 618 } 619 620 int xen_be_bind_evtchn(struct XenLegacyDevice *xendev) 621 { 622 if (xendev->local_port != -1) { 623 return 0; 624 } 625 xendev->local_port = qemu_xen_evtchn_bind_interdomain 626 (xendev->evtchndev, xendev->dom, xendev->remote_port); 627 if (xendev->local_port == -1) { 628 xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n"); 629 return -1; 630 } 631 xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); 632 qemu_set_fd_handler(qemu_xen_evtchn_fd(xendev->evtchndev), 633 xen_pv_evtchn_event, NULL, xendev); 634 return 0; 635 } 636 637 638 static Property xendev_properties[] = { 639 DEFINE_PROP_END_OF_LIST(), 640 }; 641 642 static void xendev_class_init(ObjectClass *klass, void *data) 643 { 644 DeviceClass *dc = DEVICE_CLASS(klass); 645 646 device_class_set_props(dc, xendev_properties); 647 set_bit(DEVICE_CATEGORY_MISC, dc->categories); 648 /* xen-backend devices can be plugged/unplugged dynamically */ 649 dc->user_creatable = true; 650 dc->bus_type = TYPE_XENSYSBUS; 651 } 652 653 static const TypeInfo xendev_type_info = { 654 .name = TYPE_XENBACKEND, 655 .parent = TYPE_DEVICE, 656 .class_init = xendev_class_init, 657 .instance_size = sizeof(struct XenLegacyDevice), 658 }; 659 660 static void xen_sysbus_class_init(ObjectClass *klass, void *data) 661 { 662 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); 663 664 hc->unplug = qdev_simple_device_unplug_cb; 665 } 666 667 static const TypeInfo xensysbus_info = { 668 .name = TYPE_XENSYSBUS, 669 .parent = TYPE_BUS, 670 .class_init = xen_sysbus_class_init, 671 .interfaces = (InterfaceInfo[]) { 672 { TYPE_HOTPLUG_HANDLER }, 673 { } 674 } 675 }; 676 677 static Property xen_sysdev_properties[] = { 678 {/* end of property list */}, 679 }; 680 681 static void xen_sysdev_class_init(ObjectClass *klass, void *data) 682 { 683 DeviceClass *dc = DEVICE_CLASS(klass); 684 685 device_class_set_props(dc, xen_sysdev_properties); 686 } 687 688 static const TypeInfo xensysdev_info = { 689 .name = TYPE_XENSYSDEV, 690 .parent = TYPE_SYS_BUS_DEVICE, 691 .instance_size = sizeof(SysBusDevice), 692 .class_init = xen_sysdev_class_init, 693 }; 694 695 static void xenbe_register_types(void) 696 { 697 type_register_static(&xensysbus_info); 698 type_register_static(&xensysdev_info); 699 type_register_static(&xendev_type_info); 700 } 701 702 type_init(xenbe_register_types) 703