1 /* 2 * Copyright (c) 2018 Citrix Systems Inc. 3 * 4 * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 * See the COPYING file in the top-level directory. 6 */ 7 8 #include "qemu/osdep.h" 9 #include "qemu/main-loop.h" 10 #include "qemu/module.h" 11 #include "qemu/uuid.h" 12 #include "hw/qdev-properties.h" 13 #include "hw/sysbus.h" 14 #include "hw/xen/xen.h" 15 #include "hw/xen/xen-backend.h" 16 #include "hw/xen/xen-bus.h" 17 #include "hw/xen/xen-bus-helper.h" 18 #include "monitor/monitor.h" 19 #include "qapi/error.h" 20 #include "qapi/qmp/qdict.h" 21 #include "sysemu/sysemu.h" 22 #include "trace.h" 23 24 static char *xen_device_get_backend_path(XenDevice *xendev) 25 { 26 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 27 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 28 const char *type = object_get_typename(OBJECT(xendev)); 29 const char *backend = xendev_class->backend; 30 31 if (!backend) { 32 backend = type; 33 } 34 35 return g_strdup_printf("/local/domain/%u/backend/%s/%u/%s", 36 xenbus->backend_id, backend, xendev->frontend_id, 37 xendev->name); 38 } 39 40 static char *xen_device_get_frontend_path(XenDevice *xendev) 41 { 42 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 43 const char *type = object_get_typename(OBJECT(xendev)); 44 const char *device = xendev_class->device; 45 46 if (!device) { 47 device = type; 48 } 49 50 return g_strdup_printf("/local/domain/%u/device/%s/%s", 51 xendev->frontend_id, device, xendev->name); 52 } 53 54 static void xen_device_unplug(XenDevice *xendev, Error **errp) 55 { 56 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 57 const char *type = object_get_typename(OBJECT(xendev)); 58 Error *local_err = NULL; 59 xs_transaction_t tid; 60 61 trace_xen_device_unplug(type, xendev->name); 62 63 /* Mimic the way the Xen toolstack does an unplug */ 64 again: 65 tid = xs_transaction_start(xenbus->xsh); 66 if (tid == XBT_NULL) { 67 error_setg_errno(errp, errno, "failed xs_transaction_start"); 68 return; 69 } 70 71 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "online", 72 &local_err, "%u", 0); 73 if (local_err) { 74 goto abort; 75 } 76 77 xs_node_printf(xenbus->xsh, tid, xendev->backend_path, "state", 78 &local_err, "%u", XenbusStateClosing); 79 if (local_err) { 80 goto abort; 81 } 82 83 if (!xs_transaction_end(xenbus->xsh, tid, false)) { 84 if (errno == EAGAIN) { 85 goto again; 86 } 87 88 error_setg_errno(errp, errno, "failed xs_transaction_end"); 89 } 90 91 return; 92 93 abort: 94 /* 95 * We only abort if there is already a failure so ignore any error 96 * from ending the transaction. 97 */ 98 xs_transaction_end(xenbus->xsh, tid, true); 99 error_propagate(errp, local_err); 100 } 101 102 static void xen_bus_print_dev(Monitor *mon, DeviceState *dev, int indent) 103 { 104 XenDevice *xendev = XEN_DEVICE(dev); 105 106 monitor_printf(mon, "%*sname = '%s' frontend_id = %u\n", 107 indent, "", xendev->name, xendev->frontend_id); 108 } 109 110 static char *xen_bus_get_dev_path(DeviceState *dev) 111 { 112 return xen_device_get_backend_path(XEN_DEVICE(dev)); 113 } 114 115 struct XenWatch { 116 char *node, *key; 117 char *token; 118 XenWatchHandler handler; 119 void *opaque; 120 Notifier notifier; 121 }; 122 123 static void watch_notify(Notifier *n, void *data) 124 { 125 XenWatch *watch = container_of(n, XenWatch, notifier); 126 const char *token = data; 127 128 if (!strcmp(watch->token, token)) { 129 watch->handler(watch->opaque); 130 } 131 } 132 133 static XenWatch *new_watch(const char *node, const char *key, 134 XenWatchHandler handler, void *opaque) 135 { 136 XenWatch *watch = g_new0(XenWatch, 1); 137 QemuUUID uuid; 138 139 qemu_uuid_generate(&uuid); 140 141 watch->token = qemu_uuid_unparse_strdup(&uuid); 142 watch->node = g_strdup(node); 143 watch->key = g_strdup(key); 144 watch->handler = handler; 145 watch->opaque = opaque; 146 watch->notifier.notify = watch_notify; 147 148 return watch; 149 } 150 151 static void free_watch(XenWatch *watch) 152 { 153 g_free(watch->token); 154 g_free(watch->key); 155 g_free(watch->node); 156 157 g_free(watch); 158 } 159 160 struct XenWatchList { 161 struct xs_handle *xsh; 162 NotifierList notifiers; 163 }; 164 165 static void watch_list_event(void *opaque) 166 { 167 XenWatchList *watch_list = opaque; 168 char **v; 169 const char *token; 170 171 v = xs_check_watch(watch_list->xsh); 172 if (!v) { 173 return; 174 } 175 176 token = v[XS_WATCH_TOKEN]; 177 178 notifier_list_notify(&watch_list->notifiers, (void *)token); 179 180 free(v); 181 } 182 183 static XenWatchList *watch_list_create(struct xs_handle *xsh) 184 { 185 XenWatchList *watch_list = g_new0(XenWatchList, 1); 186 187 g_assert(xsh); 188 189 watch_list->xsh = xsh; 190 notifier_list_init(&watch_list->notifiers); 191 qemu_set_fd_handler(xs_fileno(watch_list->xsh), watch_list_event, NULL, 192 watch_list); 193 194 return watch_list; 195 } 196 197 static void watch_list_destroy(XenWatchList *watch_list) 198 { 199 g_assert(notifier_list_empty(&watch_list->notifiers)); 200 qemu_set_fd_handler(xs_fileno(watch_list->xsh), NULL, NULL, NULL); 201 g_free(watch_list); 202 } 203 204 static XenWatch *watch_list_add(XenWatchList *watch_list, const char *node, 205 const char *key, XenWatchHandler handler, 206 void *opaque, Error **errp) 207 { 208 XenWatch *watch = new_watch(node, key, handler, opaque); 209 Error *local_err = NULL; 210 211 notifier_list_add(&watch_list->notifiers, &watch->notifier); 212 213 xs_node_watch(watch_list->xsh, node, key, watch->token, &local_err); 214 if (local_err) { 215 error_propagate(errp, local_err); 216 217 notifier_remove(&watch->notifier); 218 free_watch(watch); 219 220 return NULL; 221 } 222 223 return watch; 224 } 225 226 static void watch_list_remove(XenWatchList *watch_list, XenWatch *watch, 227 Error **errp) 228 { 229 xs_node_unwatch(watch_list->xsh, watch->node, watch->key, watch->token, 230 errp); 231 232 notifier_remove(&watch->notifier); 233 free_watch(watch); 234 } 235 236 static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node, 237 const char *key, XenWatchHandler handler, 238 Error **errp) 239 { 240 trace_xen_bus_add_watch(node, key); 241 242 return watch_list_add(xenbus->watch_list, node, key, handler, xenbus, 243 errp); 244 } 245 246 static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch, 247 Error **errp) 248 { 249 trace_xen_bus_remove_watch(watch->node, watch->key); 250 251 watch_list_remove(xenbus->watch_list, watch, errp); 252 } 253 254 static void xen_bus_backend_create(XenBus *xenbus, const char *type, 255 const char *name, char *path, 256 Error **errp) 257 { 258 xs_transaction_t tid; 259 char **key; 260 QDict *opts; 261 unsigned int i, n; 262 Error *local_err = NULL; 263 264 trace_xen_bus_backend_create(type, path); 265 266 again: 267 tid = xs_transaction_start(xenbus->xsh); 268 if (tid == XBT_NULL) { 269 error_setg(errp, "failed xs_transaction_start"); 270 return; 271 } 272 273 key = xs_directory(xenbus->xsh, tid, path, &n); 274 if (!key) { 275 if (!xs_transaction_end(xenbus->xsh, tid, true)) { 276 error_setg_errno(errp, errno, "failed xs_transaction_end"); 277 } 278 return; 279 } 280 281 opts = qdict_new(); 282 for (i = 0; i < n; i++) { 283 char *val; 284 285 /* 286 * Assume anything found in the xenstore backend area, other than 287 * the keys created for a generic XenDevice, are parameters 288 * to be used to configure the backend. 289 */ 290 if (!strcmp(key[i], "state") || 291 !strcmp(key[i], "online") || 292 !strcmp(key[i], "frontend") || 293 !strcmp(key[i], "frontend-id") || 294 !strcmp(key[i], "hotplug-status")) 295 continue; 296 297 if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms", 298 &val) == 1) { 299 qdict_put_str(opts, key[i], val); 300 free(val); 301 } 302 } 303 304 free(key); 305 306 if (!xs_transaction_end(xenbus->xsh, tid, false)) { 307 qobject_unref(opts); 308 309 if (errno == EAGAIN) { 310 goto again; 311 } 312 313 error_setg_errno(errp, errno, "failed xs_transaction_end"); 314 return; 315 } 316 317 xen_backend_device_create(xenbus, type, name, opts, &local_err); 318 qobject_unref(opts); 319 320 if (local_err) { 321 error_propagate_prepend(errp, local_err, 322 "failed to create '%s' device '%s': ", 323 type, name); 324 } 325 } 326 327 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type) 328 { 329 char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid); 330 char **backend; 331 unsigned int i, n; 332 333 trace_xen_bus_type_enumerate(type); 334 335 backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n); 336 if (!backend) { 337 goto out; 338 } 339 340 for (i = 0; i < n; i++) { 341 char *backend_path = g_strdup_printf("%s/%s", domain_path, 342 backend[i]); 343 enum xenbus_state state; 344 unsigned int online; 345 346 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state", 347 NULL, "%u", &state) != 1) 348 state = XenbusStateUnknown; 349 350 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "online", 351 NULL, "%u", &online) != 1) 352 online = 0; 353 354 if (online && state == XenbusStateInitialising) { 355 Error *local_err = NULL; 356 357 xen_bus_backend_create(xenbus, type, backend[i], backend_path, 358 &local_err); 359 if (local_err) { 360 error_report_err(local_err); 361 } 362 } 363 364 g_free(backend_path); 365 } 366 367 free(backend); 368 369 out: 370 g_free(domain_path); 371 } 372 373 static void xen_bus_enumerate(XenBus *xenbus) 374 { 375 char **type; 376 unsigned int i, n; 377 378 trace_xen_bus_enumerate(); 379 380 type = xs_directory(xenbus->xsh, XBT_NULL, "backend", &n); 381 if (!type) { 382 return; 383 } 384 385 for (i = 0; i < n; i++) { 386 xen_bus_type_enumerate(xenbus, type[i]); 387 } 388 389 free(type); 390 } 391 392 static void xen_bus_device_cleanup(XenDevice *xendev) 393 { 394 const char *type = object_get_typename(OBJECT(xendev)); 395 Error *local_err = NULL; 396 397 trace_xen_bus_device_cleanup(type, xendev->name); 398 399 g_assert(!xendev->backend_online); 400 401 if (!xen_backend_try_device_destroy(xendev, &local_err)) { 402 object_unparent(OBJECT(xendev)); 403 } 404 405 if (local_err) { 406 error_report_err(local_err); 407 } 408 } 409 410 static void xen_bus_cleanup(XenBus *xenbus) 411 { 412 XenDevice *xendev, *next; 413 414 trace_xen_bus_cleanup(); 415 416 QLIST_FOREACH_SAFE(xendev, &xenbus->inactive_devices, list, next) { 417 g_assert(xendev->inactive); 418 QLIST_REMOVE(xendev, list); 419 xen_bus_device_cleanup(xendev); 420 } 421 } 422 423 static void xen_bus_backend_changed(void *opaque) 424 { 425 XenBus *xenbus = opaque; 426 427 xen_bus_enumerate(xenbus); 428 xen_bus_cleanup(xenbus); 429 } 430 431 static void xen_bus_unrealize(BusState *bus, Error **errp) 432 { 433 XenBus *xenbus = XEN_BUS(bus); 434 435 trace_xen_bus_unrealize(); 436 437 if (xenbus->backend_watch) { 438 xen_bus_remove_watch(xenbus, xenbus->backend_watch, NULL); 439 xenbus->backend_watch = NULL; 440 } 441 442 if (xenbus->watch_list) { 443 watch_list_destroy(xenbus->watch_list); 444 xenbus->watch_list = NULL; 445 } 446 447 if (xenbus->xsh) { 448 xs_close(xenbus->xsh); 449 } 450 } 451 452 static void xen_bus_realize(BusState *bus, Error **errp) 453 { 454 XenBus *xenbus = XEN_BUS(bus); 455 unsigned int domid; 456 Error *local_err = NULL; 457 458 trace_xen_bus_realize(); 459 460 xenbus->xsh = xs_open(0); 461 if (!xenbus->xsh) { 462 error_setg_errno(errp, errno, "failed xs_open"); 463 goto fail; 464 } 465 466 if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */ 467 "domid", NULL, "%u", &domid) == 1) { 468 xenbus->backend_id = domid; 469 } else { 470 xenbus->backend_id = 0; /* Assume lack of node means dom0 */ 471 } 472 473 xenbus->watch_list = watch_list_create(xenbus->xsh); 474 475 module_call_init(MODULE_INIT_XEN_BACKEND); 476 477 xenbus->backend_watch = 478 xen_bus_add_watch(xenbus, "", /* domain root node */ 479 "backend", xen_bus_backend_changed, &local_err); 480 if (local_err) { 481 /* This need not be treated as a hard error so don't propagate */ 482 error_reportf_err(local_err, 483 "failed to set up enumeration watch: "); 484 } 485 486 return; 487 488 fail: 489 xen_bus_unrealize(bus, &error_abort); 490 } 491 492 static void xen_bus_unplug_request(HotplugHandler *hotplug, 493 DeviceState *dev, 494 Error **errp) 495 { 496 XenDevice *xendev = XEN_DEVICE(dev); 497 498 xen_device_unplug(xendev, errp); 499 } 500 501 static void xen_bus_class_init(ObjectClass *class, void *data) 502 { 503 BusClass *bus_class = BUS_CLASS(class); 504 HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class); 505 506 bus_class->print_dev = xen_bus_print_dev; 507 bus_class->get_dev_path = xen_bus_get_dev_path; 508 bus_class->realize = xen_bus_realize; 509 bus_class->unrealize = xen_bus_unrealize; 510 511 hotplug_class->unplug_request = xen_bus_unplug_request; 512 } 513 514 static const TypeInfo xen_bus_type_info = { 515 .name = TYPE_XEN_BUS, 516 .parent = TYPE_BUS, 517 .instance_size = sizeof(XenBus), 518 .class_size = sizeof(XenBusClass), 519 .class_init = xen_bus_class_init, 520 .interfaces = (InterfaceInfo[]) { 521 { TYPE_HOTPLUG_HANDLER }, 522 { } 523 }, 524 }; 525 526 void xen_device_backend_printf(XenDevice *xendev, const char *key, 527 const char *fmt, ...) 528 { 529 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 530 Error *local_err = NULL; 531 va_list ap; 532 533 g_assert(xenbus->xsh); 534 535 va_start(ap, fmt); 536 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, 537 &local_err, fmt, ap); 538 va_end(ap); 539 540 if (local_err) { 541 error_report_err(local_err); 542 } 543 } 544 545 static int xen_device_backend_scanf(XenDevice *xendev, const char *key, 546 const char *fmt, ...) 547 { 548 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 549 va_list ap; 550 int rc; 551 552 g_assert(xenbus->xsh); 553 554 va_start(ap, fmt); 555 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, 556 NULL, fmt, ap); 557 va_end(ap); 558 559 return rc; 560 } 561 562 void xen_device_backend_set_state(XenDevice *xendev, 563 enum xenbus_state state) 564 { 565 const char *type = object_get_typename(OBJECT(xendev)); 566 567 if (xendev->backend_state == state) { 568 return; 569 } 570 571 trace_xen_device_backend_state(type, xendev->name, 572 xs_strstate(state)); 573 574 xendev->backend_state = state; 575 xen_device_backend_printf(xendev, "state", "%u", state); 576 } 577 578 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev) 579 { 580 return xendev->backend_state; 581 } 582 583 static void xen_device_backend_set_online(XenDevice *xendev, bool online) 584 { 585 const char *type = object_get_typename(OBJECT(xendev)); 586 587 if (xendev->backend_online == online) { 588 return; 589 } 590 591 trace_xen_device_backend_online(type, xendev->name, online); 592 593 xendev->backend_online = online; 594 xen_device_backend_printf(xendev, "online", "%u", online); 595 } 596 597 /* 598 * Tell from the state whether the frontend is likely alive, 599 * i.e. it will react to a change of state of the backend. 600 */ 601 static bool xen_device_frontend_is_active(XenDevice *xendev) 602 { 603 switch (xendev->frontend_state) { 604 case XenbusStateInitWait: 605 case XenbusStateInitialised: 606 case XenbusStateConnected: 607 case XenbusStateClosing: 608 return true; 609 default: 610 return false; 611 } 612 } 613 614 static void xen_device_backend_changed(void *opaque) 615 { 616 XenDevice *xendev = opaque; 617 const char *type = object_get_typename(OBJECT(xendev)); 618 enum xenbus_state state; 619 unsigned int online; 620 621 trace_xen_device_backend_changed(type, xendev->name); 622 623 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) { 624 state = XenbusStateUnknown; 625 } 626 627 xen_device_backend_set_state(xendev, state); 628 629 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) { 630 online = 0; 631 } 632 633 xen_device_backend_set_online(xendev, !!online); 634 635 /* 636 * If the toolstack (or unplug request callback) has set the backend 637 * state to Closing, but there is no active frontend then set the 638 * backend state to Closed. 639 */ 640 if (state == XenbusStateClosing && 641 !xen_device_frontend_is_active(xendev)) { 642 xen_device_backend_set_state(xendev, XenbusStateClosed); 643 } 644 645 /* 646 * If a backend is still 'online' then we should leave it alone but, 647 * if a backend is not 'online', then the device is a candidate 648 * for destruction. Hence add it to the 'inactive' list to be cleaned 649 * by xen_bus_cleanup(). 650 */ 651 if (!online && 652 (state == XenbusStateClosed || state == XenbusStateInitialising || 653 state == XenbusStateInitWait || state == XenbusStateUnknown) && 654 !xendev->inactive) { 655 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 656 657 xendev->inactive = true; 658 QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list); 659 660 /* 661 * Re-write the state to cause a XenBus backend_watch notification, 662 * resulting in a call to xen_bus_cleanup(). 663 */ 664 xen_device_backend_printf(xendev, "state", "%u", state); 665 } 666 } 667 668 static XenWatch *xen_device_add_watch(XenDevice *xendev, const char *node, 669 const char *key, 670 XenWatchHandler handler, 671 Error **errp) 672 { 673 const char *type = object_get_typename(OBJECT(xendev)); 674 675 trace_xen_device_add_watch(type, xendev->name, node, key); 676 677 return watch_list_add(xendev->watch_list, node, key, handler, xendev, 678 errp); 679 } 680 681 static void xen_device_remove_watch(XenDevice *xendev, XenWatch *watch, 682 Error **errp) 683 { 684 const char *type = object_get_typename(OBJECT(xendev)); 685 686 trace_xen_device_remove_watch(type, xendev->name, watch->node, 687 watch->key); 688 689 watch_list_remove(xendev->watch_list, watch, errp); 690 } 691 692 693 static void xen_device_backend_create(XenDevice *xendev, Error **errp) 694 { 695 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 696 struct xs_permissions perms[2]; 697 Error *local_err = NULL; 698 699 xendev->backend_path = xen_device_get_backend_path(xendev); 700 701 perms[0].id = xenbus->backend_id; 702 perms[0].perms = XS_PERM_NONE; 703 perms[1].id = xendev->frontend_id; 704 perms[1].perms = XS_PERM_READ; 705 706 g_assert(xenbus->xsh); 707 708 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, perms, 709 ARRAY_SIZE(perms), &local_err); 710 if (local_err) { 711 error_propagate_prepend(errp, local_err, 712 "failed to create backend: "); 713 return; 714 } 715 716 xendev->backend_state_watch = 717 xen_device_add_watch(xendev, xendev->backend_path, 718 "state", xen_device_backend_changed, 719 &local_err); 720 if (local_err) { 721 error_propagate_prepend(errp, local_err, 722 "failed to watch backend state: "); 723 return; 724 } 725 726 xendev->backend_online_watch = 727 xen_device_add_watch(xendev, xendev->backend_path, 728 "online", xen_device_backend_changed, 729 &local_err); 730 if (local_err) { 731 error_propagate_prepend(errp, local_err, 732 "failed to watch backend online: "); 733 return; 734 } 735 } 736 737 static void xen_device_backend_destroy(XenDevice *xendev) 738 { 739 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 740 Error *local_err = NULL; 741 742 if (xendev->backend_online_watch) { 743 xen_device_remove_watch(xendev, xendev->backend_online_watch, NULL); 744 xendev->backend_online_watch = NULL; 745 } 746 747 if (xendev->backend_state_watch) { 748 xen_device_remove_watch(xendev, xendev->backend_state_watch, NULL); 749 xendev->backend_state_watch = NULL; 750 } 751 752 if (!xendev->backend_path) { 753 return; 754 } 755 756 g_assert(xenbus->xsh); 757 758 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path, 759 &local_err); 760 g_free(xendev->backend_path); 761 xendev->backend_path = NULL; 762 763 if (local_err) { 764 error_report_err(local_err); 765 } 766 } 767 768 void xen_device_frontend_printf(XenDevice *xendev, const char *key, 769 const char *fmt, ...) 770 { 771 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 772 Error *local_err = NULL; 773 va_list ap; 774 775 g_assert(xenbus->xsh); 776 777 va_start(ap, fmt); 778 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 779 &local_err, fmt, ap); 780 va_end(ap); 781 782 if (local_err) { 783 error_report_err(local_err); 784 } 785 } 786 787 int xen_device_frontend_scanf(XenDevice *xendev, const char *key, 788 const char *fmt, ...) 789 { 790 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 791 va_list ap; 792 int rc; 793 794 g_assert(xenbus->xsh); 795 796 va_start(ap, fmt); 797 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 798 NULL, fmt, ap); 799 va_end(ap); 800 801 return rc; 802 } 803 804 static void xen_device_frontend_set_state(XenDevice *xendev, 805 enum xenbus_state state, 806 bool publish) 807 { 808 const char *type = object_get_typename(OBJECT(xendev)); 809 810 if (xendev->frontend_state == state) { 811 return; 812 } 813 814 trace_xen_device_frontend_state(type, xendev->name, 815 xs_strstate(state)); 816 817 xendev->frontend_state = state; 818 if (publish) { 819 xen_device_frontend_printf(xendev, "state", "%u", state); 820 } 821 } 822 823 static void xen_device_frontend_changed(void *opaque) 824 { 825 XenDevice *xendev = opaque; 826 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 827 const char *type = object_get_typename(OBJECT(xendev)); 828 enum xenbus_state state; 829 830 trace_xen_device_frontend_changed(type, xendev->name); 831 832 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) { 833 state = XenbusStateUnknown; 834 } 835 836 xen_device_frontend_set_state(xendev, state, false); 837 838 if (state == XenbusStateInitialising && 839 xendev->backend_state == XenbusStateClosed && 840 xendev->backend_online) { 841 /* 842 * The frontend is re-initializing so switch back to 843 * InitWait. 844 */ 845 xen_device_backend_set_state(xendev, XenbusStateInitWait); 846 return; 847 } 848 849 if (xendev_class->frontend_changed) { 850 Error *local_err = NULL; 851 852 xendev_class->frontend_changed(xendev, state, &local_err); 853 854 if (local_err) { 855 error_reportf_err(local_err, "frontend change error: "); 856 } 857 } 858 } 859 860 static bool xen_device_frontend_exists(XenDevice *xendev) 861 { 862 enum xenbus_state state; 863 864 return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1); 865 } 866 867 static void xen_device_frontend_create(XenDevice *xendev, Error **errp) 868 { 869 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 870 struct xs_permissions perms[2]; 871 Error *local_err = NULL; 872 873 xendev->frontend_path = xen_device_get_frontend_path(xendev); 874 875 /* 876 * The frontend area may have already been created by a legacy 877 * toolstack. 878 */ 879 if (!xen_device_frontend_exists(xendev)) { 880 perms[0].id = xendev->frontend_id; 881 perms[0].perms = XS_PERM_NONE; 882 perms[1].id = xenbus->backend_id; 883 perms[1].perms = XS_PERM_READ | XS_PERM_WRITE; 884 885 g_assert(xenbus->xsh); 886 887 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms, 888 ARRAY_SIZE(perms), &local_err); 889 if (local_err) { 890 error_propagate_prepend(errp, local_err, 891 "failed to create frontend: "); 892 return; 893 } 894 } 895 896 xendev->frontend_state_watch = 897 xen_device_add_watch(xendev, xendev->frontend_path, "state", 898 xen_device_frontend_changed, &local_err); 899 if (local_err) { 900 error_propagate_prepend(errp, local_err, 901 "failed to watch frontend state: "); 902 } 903 } 904 905 static void xen_device_frontend_destroy(XenDevice *xendev) 906 { 907 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 908 Error *local_err = NULL; 909 910 if (xendev->frontend_state_watch) { 911 xen_device_remove_watch(xendev, xendev->frontend_state_watch, 912 NULL); 913 xendev->frontend_state_watch = NULL; 914 } 915 916 if (!xendev->frontend_path) { 917 return; 918 } 919 920 g_assert(xenbus->xsh); 921 922 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path, 923 &local_err); 924 g_free(xendev->frontend_path); 925 xendev->frontend_path = NULL; 926 927 if (local_err) { 928 error_report_err(local_err); 929 } 930 } 931 932 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, 933 Error **errp) 934 { 935 if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) { 936 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed"); 937 } 938 } 939 940 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, 941 unsigned int nr_refs, int prot, 942 Error **errp) 943 { 944 void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs, 945 xendev->frontend_id, refs, 946 prot); 947 948 if (!map) { 949 error_setg_errno(errp, errno, 950 "xengnttab_map_domain_grant_refs failed"); 951 } 952 953 return map; 954 } 955 956 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, 957 unsigned int nr_refs, Error **errp) 958 { 959 if (xengnttab_unmap(xendev->xgth, map, nr_refs)) { 960 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 961 } 962 } 963 964 static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain, 965 XenDeviceGrantCopySegment segs[], 966 unsigned int nr_segs, Error **errp) 967 { 968 uint32_t *refs = g_new(uint32_t, nr_segs); 969 int prot = to_domain ? PROT_WRITE : PROT_READ; 970 void *map; 971 unsigned int i; 972 973 for (i = 0; i < nr_segs; i++) { 974 XenDeviceGrantCopySegment *seg = &segs[i]; 975 976 refs[i] = to_domain ? seg->dest.foreign.ref : 977 seg->source.foreign.ref; 978 } 979 980 map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs, 981 xendev->frontend_id, refs, 982 prot); 983 if (!map) { 984 error_setg_errno(errp, errno, 985 "xengnttab_map_domain_grant_refs failed"); 986 goto done; 987 } 988 989 for (i = 0; i < nr_segs; i++) { 990 XenDeviceGrantCopySegment *seg = &segs[i]; 991 void *page = map + (i * XC_PAGE_SIZE); 992 993 if (to_domain) { 994 memcpy(page + seg->dest.foreign.offset, seg->source.virt, 995 seg->len); 996 } else { 997 memcpy(seg->dest.virt, page + seg->source.foreign.offset, 998 seg->len); 999 } 1000 } 1001 1002 if (xengnttab_unmap(xendev->xgth, map, nr_segs)) { 1003 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 1004 } 1005 1006 done: 1007 g_free(refs); 1008 } 1009 1010 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain, 1011 XenDeviceGrantCopySegment segs[], 1012 unsigned int nr_segs, Error **errp) 1013 { 1014 xengnttab_grant_copy_segment_t *xengnttab_segs; 1015 unsigned int i; 1016 1017 if (!xendev->feature_grant_copy) { 1018 compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp); 1019 return; 1020 } 1021 1022 xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs); 1023 1024 for (i = 0; i < nr_segs; i++) { 1025 XenDeviceGrantCopySegment *seg = &segs[i]; 1026 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; 1027 1028 if (to_domain) { 1029 xengnttab_seg->flags = GNTCOPY_dest_gref; 1030 xengnttab_seg->dest.foreign.domid = xendev->frontend_id; 1031 xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref; 1032 xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset; 1033 xengnttab_seg->source.virt = seg->source.virt; 1034 } else { 1035 xengnttab_seg->flags = GNTCOPY_source_gref; 1036 xengnttab_seg->source.foreign.domid = xendev->frontend_id; 1037 xengnttab_seg->source.foreign.ref = seg->source.foreign.ref; 1038 xengnttab_seg->source.foreign.offset = 1039 seg->source.foreign.offset; 1040 xengnttab_seg->dest.virt = seg->dest.virt; 1041 } 1042 1043 xengnttab_seg->len = seg->len; 1044 } 1045 1046 if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) { 1047 error_setg_errno(errp, errno, "xengnttab_grant_copy failed"); 1048 goto done; 1049 } 1050 1051 for (i = 0; i < nr_segs; i++) { 1052 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; 1053 1054 if (xengnttab_seg->status != GNTST_okay) { 1055 error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i); 1056 break; 1057 } 1058 } 1059 1060 done: 1061 g_free(xengnttab_segs); 1062 } 1063 1064 struct XenEventChannel { 1065 QLIST_ENTRY(XenEventChannel) list; 1066 AioContext *ctx; 1067 xenevtchn_handle *xeh; 1068 evtchn_port_t local_port; 1069 XenEventHandler handler; 1070 void *opaque; 1071 }; 1072 1073 static bool xen_device_poll(void *opaque) 1074 { 1075 XenEventChannel *channel = opaque; 1076 1077 return channel->handler(channel->opaque); 1078 } 1079 1080 static void xen_device_event(void *opaque) 1081 { 1082 XenEventChannel *channel = opaque; 1083 unsigned long port = xenevtchn_pending(channel->xeh); 1084 1085 if (port == channel->local_port) { 1086 xen_device_poll(channel); 1087 1088 xenevtchn_unmask(channel->xeh, port); 1089 } 1090 } 1091 1092 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, 1093 AioContext *ctx, 1094 unsigned int port, 1095 XenEventHandler handler, 1096 void *opaque, Error **errp) 1097 { 1098 XenEventChannel *channel = g_new0(XenEventChannel, 1); 1099 xenevtchn_port_or_error_t local_port; 1100 1101 channel->xeh = xenevtchn_open(NULL, 0); 1102 if (!channel->xeh) { 1103 error_setg_errno(errp, errno, "failed xenevtchn_open"); 1104 goto fail; 1105 } 1106 1107 local_port = xenevtchn_bind_interdomain(channel->xeh, 1108 xendev->frontend_id, 1109 port); 1110 if (local_port < 0) { 1111 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed"); 1112 goto fail; 1113 } 1114 1115 channel->local_port = local_port; 1116 channel->handler = handler; 1117 channel->opaque = opaque; 1118 1119 channel->ctx = ctx; 1120 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, 1121 xen_device_event, NULL, xen_device_poll, channel); 1122 1123 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list); 1124 1125 return channel; 1126 1127 fail: 1128 if (channel->xeh) { 1129 xenevtchn_close(channel->xeh); 1130 } 1131 1132 g_free(channel); 1133 1134 return NULL; 1135 } 1136 1137 void xen_device_notify_event_channel(XenDevice *xendev, 1138 XenEventChannel *channel, 1139 Error **errp) 1140 { 1141 if (!channel) { 1142 error_setg(errp, "bad channel"); 1143 return; 1144 } 1145 1146 if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) { 1147 error_setg_errno(errp, errno, "xenevtchn_notify failed"); 1148 } 1149 } 1150 1151 void xen_device_unbind_event_channel(XenDevice *xendev, 1152 XenEventChannel *channel, 1153 Error **errp) 1154 { 1155 if (!channel) { 1156 error_setg(errp, "bad channel"); 1157 return; 1158 } 1159 1160 QLIST_REMOVE(channel, list); 1161 1162 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, 1163 NULL, NULL, NULL, NULL); 1164 1165 if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) { 1166 error_setg_errno(errp, errno, "xenevtchn_unbind failed"); 1167 } 1168 1169 xenevtchn_close(channel->xeh); 1170 g_free(channel); 1171 } 1172 1173 static void xen_device_unrealize(DeviceState *dev, Error **errp) 1174 { 1175 XenDevice *xendev = XEN_DEVICE(dev); 1176 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1177 const char *type = object_get_typename(OBJECT(xendev)); 1178 XenEventChannel *channel, *next; 1179 1180 if (!xendev->name) { 1181 return; 1182 } 1183 1184 trace_xen_device_unrealize(type, xendev->name); 1185 1186 if (xendev->exit.notify) { 1187 qemu_remove_exit_notifier(&xendev->exit); 1188 xendev->exit.notify = NULL; 1189 } 1190 1191 if (xendev_class->unrealize) { 1192 xendev_class->unrealize(xendev, errp); 1193 } 1194 1195 /* Make sure all event channels are cleaned up */ 1196 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) { 1197 xen_device_unbind_event_channel(xendev, channel, NULL); 1198 } 1199 1200 xen_device_frontend_destroy(xendev); 1201 xen_device_backend_destroy(xendev); 1202 1203 if (xendev->xgth) { 1204 xengnttab_close(xendev->xgth); 1205 xendev->xgth = NULL; 1206 } 1207 1208 if (xendev->watch_list) { 1209 watch_list_destroy(xendev->watch_list); 1210 xendev->watch_list = NULL; 1211 } 1212 1213 if (xendev->xsh) { 1214 xs_close(xendev->xsh); 1215 xendev->xsh = NULL; 1216 } 1217 1218 g_free(xendev->name); 1219 xendev->name = NULL; 1220 } 1221 1222 static void xen_device_exit(Notifier *n, void *data) 1223 { 1224 XenDevice *xendev = container_of(n, XenDevice, exit); 1225 1226 xen_device_unrealize(DEVICE(xendev), &error_abort); 1227 } 1228 1229 static void xen_device_realize(DeviceState *dev, Error **errp) 1230 { 1231 XenDevice *xendev = XEN_DEVICE(dev); 1232 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1233 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 1234 const char *type = object_get_typename(OBJECT(xendev)); 1235 Error *local_err = NULL; 1236 1237 if (xendev->frontend_id == DOMID_INVALID) { 1238 xendev->frontend_id = xen_domid; 1239 } 1240 1241 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) { 1242 error_setg(errp, "invalid frontend-id"); 1243 goto unrealize; 1244 } 1245 1246 if (!xendev_class->get_name) { 1247 error_setg(errp, "get_name method not implemented"); 1248 goto unrealize; 1249 } 1250 1251 xendev->name = xendev_class->get_name(xendev, &local_err); 1252 if (local_err) { 1253 error_propagate_prepend(errp, local_err, 1254 "failed to get device name: "); 1255 goto unrealize; 1256 } 1257 1258 trace_xen_device_realize(type, xendev->name); 1259 1260 xendev->xsh = xs_open(0); 1261 if (!xendev->xsh) { 1262 error_setg_errno(errp, errno, "failed xs_open"); 1263 goto unrealize; 1264 } 1265 1266 xendev->watch_list = watch_list_create(xendev->xsh); 1267 1268 xendev->xgth = xengnttab_open(NULL, 0); 1269 if (!xendev->xgth) { 1270 error_setg_errno(errp, errno, "failed xengnttab_open"); 1271 goto unrealize; 1272 } 1273 1274 xendev->feature_grant_copy = 1275 (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0); 1276 1277 xen_device_backend_create(xendev, &local_err); 1278 if (local_err) { 1279 error_propagate(errp, local_err); 1280 goto unrealize; 1281 } 1282 1283 xen_device_frontend_create(xendev, &local_err); 1284 if (local_err) { 1285 error_propagate(errp, local_err); 1286 goto unrealize; 1287 } 1288 1289 if (xendev_class->realize) { 1290 xendev_class->realize(xendev, &local_err); 1291 if (local_err) { 1292 error_propagate(errp, local_err); 1293 goto unrealize; 1294 } 1295 } 1296 1297 xen_device_backend_printf(xendev, "frontend", "%s", 1298 xendev->frontend_path); 1299 xen_device_backend_printf(xendev, "frontend-id", "%u", 1300 xendev->frontend_id); 1301 xen_device_backend_printf(xendev, "hotplug-status", "connected"); 1302 1303 xen_device_backend_set_online(xendev, true); 1304 xen_device_backend_set_state(xendev, XenbusStateInitWait); 1305 1306 if (!xen_device_frontend_exists(xendev)) { 1307 xen_device_frontend_printf(xendev, "backend", "%s", 1308 xendev->backend_path); 1309 xen_device_frontend_printf(xendev, "backend-id", "%u", 1310 xenbus->backend_id); 1311 1312 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true); 1313 } 1314 1315 xendev->exit.notify = xen_device_exit; 1316 qemu_add_exit_notifier(&xendev->exit); 1317 return; 1318 1319 unrealize: 1320 xen_device_unrealize(dev, &error_abort); 1321 } 1322 1323 static Property xen_device_props[] = { 1324 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id, 1325 DOMID_INVALID), 1326 DEFINE_PROP_END_OF_LIST() 1327 }; 1328 1329 static void xen_device_class_init(ObjectClass *class, void *data) 1330 { 1331 DeviceClass *dev_class = DEVICE_CLASS(class); 1332 1333 dev_class->realize = xen_device_realize; 1334 dev_class->unrealize = xen_device_unrealize; 1335 dev_class->props = xen_device_props; 1336 dev_class->bus_type = TYPE_XEN_BUS; 1337 } 1338 1339 static const TypeInfo xen_device_type_info = { 1340 .name = TYPE_XEN_DEVICE, 1341 .parent = TYPE_DEVICE, 1342 .instance_size = sizeof(XenDevice), 1343 .abstract = true, 1344 .class_size = sizeof(XenDeviceClass), 1345 .class_init = xen_device_class_init, 1346 }; 1347 1348 typedef struct XenBridge { 1349 SysBusDevice busdev; 1350 } XenBridge; 1351 1352 #define TYPE_XEN_BRIDGE "xen-bridge" 1353 1354 static const TypeInfo xen_bridge_type_info = { 1355 .name = TYPE_XEN_BRIDGE, 1356 .parent = TYPE_SYS_BUS_DEVICE, 1357 .instance_size = sizeof(XenBridge), 1358 }; 1359 1360 static void xen_register_types(void) 1361 { 1362 type_register_static(&xen_bridge_type_info); 1363 type_register_static(&xen_bus_type_info); 1364 type_register_static(&xen_device_type_info); 1365 } 1366 1367 type_init(xen_register_types) 1368 1369 void xen_bus_init(void) 1370 { 1371 DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE); 1372 BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL); 1373 1374 qdev_init_nofail(dev); 1375 qbus_set_bus_hotplug_handler(bus, &error_abort); 1376 } 1377