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 static XenWatch *xen_bus_add_watch(XenBus *xenbus, const char *node, 161 const char *key, XenWatchHandler handler, 162 void *opaque, Error **errp) 163 { 164 XenWatch *watch = new_watch(node, key, handler, opaque); 165 Error *local_err = NULL; 166 167 trace_xen_bus_add_watch(watch->node, watch->key, watch->token); 168 169 notifier_list_add(&xenbus->watch_notifiers, &watch->notifier); 170 171 xs_node_watch(xenbus->xsh, node, key, watch->token, &local_err); 172 if (local_err) { 173 error_propagate(errp, local_err); 174 175 notifier_remove(&watch->notifier); 176 free_watch(watch); 177 178 return NULL; 179 } 180 181 return watch; 182 } 183 184 static void xen_bus_remove_watch(XenBus *xenbus, XenWatch *watch, 185 Error **errp) 186 { 187 trace_xen_bus_remove_watch(watch->node, watch->key, watch->token); 188 189 xs_node_unwatch(xenbus->xsh, watch->node, watch->key, watch->token, 190 errp); 191 192 notifier_remove(&watch->notifier); 193 free_watch(watch); 194 } 195 196 static void xen_bus_backend_create(XenBus *xenbus, const char *type, 197 const char *name, char *path, 198 Error **errp) 199 { 200 xs_transaction_t tid; 201 char **key; 202 QDict *opts; 203 unsigned int i, n; 204 Error *local_err = NULL; 205 206 trace_xen_bus_backend_create(type, path); 207 208 again: 209 tid = xs_transaction_start(xenbus->xsh); 210 if (tid == XBT_NULL) { 211 error_setg(errp, "failed xs_transaction_start"); 212 return; 213 } 214 215 key = xs_directory(xenbus->xsh, tid, path, &n); 216 if (!key) { 217 if (!xs_transaction_end(xenbus->xsh, tid, true)) { 218 error_setg_errno(errp, errno, "failed xs_transaction_end"); 219 } 220 return; 221 } 222 223 opts = qdict_new(); 224 for (i = 0; i < n; i++) { 225 char *val; 226 227 /* 228 * Assume anything found in the xenstore backend area, other than 229 * the keys created for a generic XenDevice, are parameters 230 * to be used to configure the backend. 231 */ 232 if (!strcmp(key[i], "state") || 233 !strcmp(key[i], "online") || 234 !strcmp(key[i], "frontend") || 235 !strcmp(key[i], "frontend-id") || 236 !strcmp(key[i], "hotplug-status")) 237 continue; 238 239 if (xs_node_scanf(xenbus->xsh, tid, path, key[i], NULL, "%ms", 240 &val) == 1) { 241 qdict_put_str(opts, key[i], val); 242 free(val); 243 } 244 } 245 246 free(key); 247 248 if (!xs_transaction_end(xenbus->xsh, tid, false)) { 249 qobject_unref(opts); 250 251 if (errno == EAGAIN) { 252 goto again; 253 } 254 255 error_setg_errno(errp, errno, "failed xs_transaction_end"); 256 return; 257 } 258 259 xen_backend_device_create(xenbus, type, name, opts, &local_err); 260 qobject_unref(opts); 261 262 if (local_err) { 263 error_propagate_prepend(errp, local_err, 264 "failed to create '%s' device '%s': ", 265 type, name); 266 } 267 } 268 269 static void xen_bus_type_enumerate(XenBus *xenbus, const char *type) 270 { 271 char *domain_path = g_strdup_printf("backend/%s/%u", type, xen_domid); 272 char **backend; 273 unsigned int i, n; 274 275 trace_xen_bus_type_enumerate(type); 276 277 backend = xs_directory(xenbus->xsh, XBT_NULL, domain_path, &n); 278 if (!backend) { 279 goto out; 280 } 281 282 for (i = 0; i < n; i++) { 283 char *backend_path = g_strdup_printf("%s/%s", domain_path, 284 backend[i]); 285 enum xenbus_state backend_state; 286 287 if (xs_node_scanf(xenbus->xsh, XBT_NULL, backend_path, "state", 288 NULL, "%u", &backend_state) != 1) 289 backend_state = XenbusStateUnknown; 290 291 if (backend_state == XenbusStateInitialising) { 292 Error *local_err = NULL; 293 294 xen_bus_backend_create(xenbus, type, backend[i], backend_path, 295 &local_err); 296 if (local_err) { 297 error_report_err(local_err); 298 } 299 } 300 301 g_free(backend_path); 302 } 303 304 free(backend); 305 306 out: 307 g_free(domain_path); 308 } 309 310 static void xen_bus_enumerate(void *opaque) 311 { 312 XenBus *xenbus = opaque; 313 char **type; 314 unsigned int i, n; 315 316 trace_xen_bus_enumerate(); 317 318 type = xs_directory(xenbus->xsh, XBT_NULL, "backend", &n); 319 if (!type) { 320 return; 321 } 322 323 for (i = 0; i < n; i++) { 324 xen_bus_type_enumerate(xenbus, type[i]); 325 } 326 327 free(type); 328 } 329 330 static void xen_bus_unrealize(BusState *bus, Error **errp) 331 { 332 XenBus *xenbus = XEN_BUS(bus); 333 334 trace_xen_bus_unrealize(); 335 336 if (xenbus->backend_watch) { 337 xen_bus_remove_watch(xenbus, xenbus->backend_watch, NULL); 338 xenbus->backend_watch = NULL; 339 } 340 341 if (!xenbus->xsh) { 342 return; 343 } 344 345 qemu_set_fd_handler(xs_fileno(xenbus->xsh), NULL, NULL, NULL); 346 347 xs_close(xenbus->xsh); 348 } 349 350 static void xen_bus_watch(void *opaque) 351 { 352 XenBus *xenbus = opaque; 353 char **v; 354 const char *token; 355 356 g_assert(xenbus->xsh); 357 358 v = xs_check_watch(xenbus->xsh); 359 if (!v) { 360 return; 361 } 362 363 token = v[XS_WATCH_TOKEN]; 364 365 trace_xen_bus_watch(token); 366 367 notifier_list_notify(&xenbus->watch_notifiers, (void *)token); 368 369 free(v); 370 } 371 372 static void xen_bus_realize(BusState *bus, Error **errp) 373 { 374 XenBus *xenbus = XEN_BUS(bus); 375 unsigned int domid; 376 Error *local_err = NULL; 377 378 trace_xen_bus_realize(); 379 380 xenbus->xsh = xs_open(0); 381 if (!xenbus->xsh) { 382 error_setg_errno(errp, errno, "failed xs_open"); 383 goto fail; 384 } 385 386 if (xs_node_scanf(xenbus->xsh, XBT_NULL, "", /* domain root node */ 387 "domid", NULL, "%u", &domid) == 1) { 388 xenbus->backend_id = domid; 389 } else { 390 xenbus->backend_id = 0; /* Assume lack of node means dom0 */ 391 } 392 393 notifier_list_init(&xenbus->watch_notifiers); 394 qemu_set_fd_handler(xs_fileno(xenbus->xsh), xen_bus_watch, NULL, 395 xenbus); 396 397 module_call_init(MODULE_INIT_XEN_BACKEND); 398 399 xenbus->backend_watch = 400 xen_bus_add_watch(xenbus, "", /* domain root node */ 401 "backend", xen_bus_enumerate, xenbus, &local_err); 402 if (local_err) { 403 /* This need not be treated as a hard error so don't propagate */ 404 error_reportf_err(local_err, 405 "failed to set up enumeration watch: "); 406 } 407 408 return; 409 410 fail: 411 xen_bus_unrealize(bus, &error_abort); 412 } 413 414 static void xen_bus_unplug_request(HotplugHandler *hotplug, 415 DeviceState *dev, 416 Error **errp) 417 { 418 XenDevice *xendev = XEN_DEVICE(dev); 419 420 xen_device_unplug(xendev, errp); 421 } 422 423 static void xen_bus_class_init(ObjectClass *class, void *data) 424 { 425 BusClass *bus_class = BUS_CLASS(class); 426 HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class); 427 428 bus_class->print_dev = xen_bus_print_dev; 429 bus_class->get_dev_path = xen_bus_get_dev_path; 430 bus_class->realize = xen_bus_realize; 431 bus_class->unrealize = xen_bus_unrealize; 432 433 hotplug_class->unplug_request = xen_bus_unplug_request; 434 } 435 436 static const TypeInfo xen_bus_type_info = { 437 .name = TYPE_XEN_BUS, 438 .parent = TYPE_BUS, 439 .instance_size = sizeof(XenBus), 440 .class_size = sizeof(XenBusClass), 441 .class_init = xen_bus_class_init, 442 .interfaces = (InterfaceInfo[]) { 443 { TYPE_HOTPLUG_HANDLER }, 444 { } 445 }, 446 }; 447 448 void xen_device_backend_printf(XenDevice *xendev, const char *key, 449 const char *fmt, ...) 450 { 451 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 452 Error *local_err = NULL; 453 va_list ap; 454 455 g_assert(xenbus->xsh); 456 457 va_start(ap, fmt); 458 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, 459 &local_err, fmt, ap); 460 va_end(ap); 461 462 if (local_err) { 463 error_report_err(local_err); 464 } 465 } 466 467 static int xen_device_backend_scanf(XenDevice *xendev, const char *key, 468 const char *fmt, ...) 469 { 470 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 471 va_list ap; 472 int rc; 473 474 g_assert(xenbus->xsh); 475 476 va_start(ap, fmt); 477 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, 478 NULL, fmt, ap); 479 va_end(ap); 480 481 return rc; 482 } 483 484 void xen_device_backend_set_state(XenDevice *xendev, 485 enum xenbus_state state) 486 { 487 const char *type = object_get_typename(OBJECT(xendev)); 488 489 if (xendev->backend_state == state) { 490 return; 491 } 492 493 trace_xen_device_backend_state(type, xendev->name, 494 xs_strstate(state)); 495 496 xendev->backend_state = state; 497 xen_device_backend_printf(xendev, "state", "%u", state); 498 } 499 500 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev) 501 { 502 return xendev->backend_state; 503 } 504 505 static void xen_device_backend_set_online(XenDevice *xendev, bool online) 506 { 507 const char *type = object_get_typename(OBJECT(xendev)); 508 509 if (xendev->backend_online == online) { 510 return; 511 } 512 513 trace_xen_device_backend_online(type, xendev->name, online); 514 515 xendev->backend_online = online; 516 xen_device_backend_printf(xendev, "online", "%u", online); 517 } 518 519 /* 520 * Tell from the state whether the frontend is likely alive, 521 * i.e. it will react to a change of state of the backend. 522 */ 523 static bool xen_device_state_is_active(enum xenbus_state state) 524 { 525 switch (state) { 526 case XenbusStateInitWait: 527 case XenbusStateInitialised: 528 case XenbusStateConnected: 529 case XenbusStateClosing: 530 return true; 531 default: 532 return false; 533 } 534 } 535 536 static void xen_device_backend_changed(void *opaque) 537 { 538 XenDevice *xendev = opaque; 539 const char *type = object_get_typename(OBJECT(xendev)); 540 enum xenbus_state state; 541 unsigned int online; 542 543 trace_xen_device_backend_changed(type, xendev->name); 544 545 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) { 546 state = XenbusStateUnknown; 547 } 548 549 xen_device_backend_set_state(xendev, state); 550 551 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) { 552 online = 0; 553 } 554 555 xen_device_backend_set_online(xendev, !!online); 556 557 /* 558 * If the toolstack (or unplug request callback) has set the backend 559 * state to Closing, but there is no active frontend then set the 560 * backend state to Closed. 561 */ 562 if (xendev->backend_state == XenbusStateClosing && 563 !xen_device_state_is_active(state)) { 564 xen_device_backend_set_state(xendev, XenbusStateClosed); 565 } 566 567 /* 568 * If a backend is still 'online' then we should leave it alone but, 569 * if a backend is not 'online', then the device should be destroyed 570 * once the state is Closed. 571 */ 572 if (!xendev->backend_online && 573 (xendev->backend_state == XenbusStateClosed || 574 xendev->backend_state == XenbusStateInitialising || 575 xendev->backend_state == XenbusStateInitWait || 576 xendev->backend_state == XenbusStateUnknown)) { 577 Error *local_err = NULL; 578 579 if (!xen_backend_try_device_destroy(xendev, &local_err)) { 580 object_unparent(OBJECT(xendev)); 581 } 582 583 if (local_err) { 584 error_report_err(local_err); 585 } 586 } 587 } 588 589 static void xen_device_backend_create(XenDevice *xendev, Error **errp) 590 { 591 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 592 struct xs_permissions perms[2]; 593 Error *local_err = NULL; 594 595 xendev->backend_path = xen_device_get_backend_path(xendev); 596 597 perms[0].id = xenbus->backend_id; 598 perms[0].perms = XS_PERM_NONE; 599 perms[1].id = xendev->frontend_id; 600 perms[1].perms = XS_PERM_READ; 601 602 g_assert(xenbus->xsh); 603 604 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, perms, 605 ARRAY_SIZE(perms), &local_err); 606 if (local_err) { 607 error_propagate_prepend(errp, local_err, 608 "failed to create backend: "); 609 return; 610 } 611 612 xendev->backend_state_watch = 613 xen_bus_add_watch(xenbus, xendev->backend_path, 614 "state", xen_device_backend_changed, 615 xendev, &local_err); 616 if (local_err) { 617 error_propagate_prepend(errp, local_err, 618 "failed to watch backend state: "); 619 return; 620 } 621 622 xendev->backend_online_watch = 623 xen_bus_add_watch(xenbus, xendev->backend_path, 624 "online", xen_device_backend_changed, 625 xendev, &local_err); 626 if (local_err) { 627 error_propagate_prepend(errp, local_err, 628 "failed to watch backend online: "); 629 return; 630 } 631 } 632 633 static void xen_device_backend_destroy(XenDevice *xendev) 634 { 635 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 636 Error *local_err = NULL; 637 638 if (xendev->backend_online_watch) { 639 xen_bus_remove_watch(xenbus, xendev->backend_online_watch, NULL); 640 xendev->backend_online_watch = NULL; 641 } 642 643 if (xendev->backend_state_watch) { 644 xen_bus_remove_watch(xenbus, xendev->backend_state_watch, NULL); 645 xendev->backend_state_watch = NULL; 646 } 647 648 if (!xendev->backend_path) { 649 return; 650 } 651 652 g_assert(xenbus->xsh); 653 654 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path, 655 &local_err); 656 g_free(xendev->backend_path); 657 xendev->backend_path = NULL; 658 659 if (local_err) { 660 error_report_err(local_err); 661 } 662 } 663 664 void xen_device_frontend_printf(XenDevice *xendev, const char *key, 665 const char *fmt, ...) 666 { 667 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 668 Error *local_err = NULL; 669 va_list ap; 670 671 g_assert(xenbus->xsh); 672 673 va_start(ap, fmt); 674 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 675 &local_err, fmt, ap); 676 va_end(ap); 677 678 if (local_err) { 679 error_report_err(local_err); 680 } 681 } 682 683 int xen_device_frontend_scanf(XenDevice *xendev, const char *key, 684 const char *fmt, ...) 685 { 686 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 687 va_list ap; 688 int rc; 689 690 g_assert(xenbus->xsh); 691 692 va_start(ap, fmt); 693 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 694 NULL, fmt, ap); 695 va_end(ap); 696 697 return rc; 698 } 699 700 static void xen_device_frontend_set_state(XenDevice *xendev, 701 enum xenbus_state state, 702 bool publish) 703 { 704 const char *type = object_get_typename(OBJECT(xendev)); 705 706 if (xendev->frontend_state == state) { 707 return; 708 } 709 710 trace_xen_device_frontend_state(type, xendev->name, 711 xs_strstate(state)); 712 713 xendev->frontend_state = state; 714 if (publish) { 715 xen_device_frontend_printf(xendev, "state", "%u", state); 716 } 717 } 718 719 static void xen_device_frontend_changed(void *opaque) 720 { 721 XenDevice *xendev = opaque; 722 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 723 const char *type = object_get_typename(OBJECT(xendev)); 724 enum xenbus_state state; 725 726 trace_xen_device_frontend_changed(type, xendev->name); 727 728 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) { 729 state = XenbusStateUnknown; 730 } 731 732 xen_device_frontend_set_state(xendev, state, false); 733 734 if (state == XenbusStateInitialising && 735 xendev->backend_state == XenbusStateClosed && 736 xendev->backend_online) { 737 /* 738 * The frontend is re-initializing so switch back to 739 * InitWait. 740 */ 741 xen_device_backend_set_state(xendev, XenbusStateInitWait); 742 return; 743 } 744 745 if (xendev_class->frontend_changed) { 746 Error *local_err = NULL; 747 748 xendev_class->frontend_changed(xendev, state, &local_err); 749 750 if (local_err) { 751 error_reportf_err(local_err, "frontend change error: "); 752 } 753 } 754 } 755 756 static void xen_device_frontend_create(XenDevice *xendev, Error **errp) 757 { 758 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 759 struct xs_permissions perms[2]; 760 Error *local_err = NULL; 761 762 xendev->frontend_path = xen_device_get_frontend_path(xendev); 763 764 perms[0].id = xendev->frontend_id; 765 perms[0].perms = XS_PERM_NONE; 766 perms[1].id = xenbus->backend_id; 767 perms[1].perms = XS_PERM_READ | XS_PERM_WRITE; 768 769 g_assert(xenbus->xsh); 770 771 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms, 772 ARRAY_SIZE(perms), &local_err); 773 if (local_err) { 774 error_propagate_prepend(errp, local_err, 775 "failed to create frontend: "); 776 return; 777 } 778 779 xendev->frontend_state_watch = 780 xen_bus_add_watch(xenbus, xendev->frontend_path, "state", 781 xen_device_frontend_changed, xendev, &local_err); 782 if (local_err) { 783 error_propagate_prepend(errp, local_err, 784 "failed to watch frontend state: "); 785 } 786 } 787 788 static void xen_device_frontend_destroy(XenDevice *xendev) 789 { 790 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 791 Error *local_err = NULL; 792 793 if (xendev->frontend_state_watch) { 794 xen_bus_remove_watch(xenbus, xendev->frontend_state_watch, NULL); 795 xendev->frontend_state_watch = NULL; 796 } 797 798 if (!xendev->frontend_path) { 799 return; 800 } 801 802 g_assert(xenbus->xsh); 803 804 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path, 805 &local_err); 806 g_free(xendev->frontend_path); 807 xendev->frontend_path = NULL; 808 809 if (local_err) { 810 error_report_err(local_err); 811 } 812 } 813 814 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, 815 Error **errp) 816 { 817 if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) { 818 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed"); 819 } 820 } 821 822 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, 823 unsigned int nr_refs, int prot, 824 Error **errp) 825 { 826 void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs, 827 xendev->frontend_id, refs, 828 prot); 829 830 if (!map) { 831 error_setg_errno(errp, errno, 832 "xengnttab_map_domain_grant_refs failed"); 833 } 834 835 return map; 836 } 837 838 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, 839 unsigned int nr_refs, Error **errp) 840 { 841 if (xengnttab_unmap(xendev->xgth, map, nr_refs)) { 842 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 843 } 844 } 845 846 static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain, 847 XenDeviceGrantCopySegment segs[], 848 unsigned int nr_segs, Error **errp) 849 { 850 uint32_t *refs = g_new(uint32_t, nr_segs); 851 int prot = to_domain ? PROT_WRITE : PROT_READ; 852 void *map; 853 unsigned int i; 854 855 for (i = 0; i < nr_segs; i++) { 856 XenDeviceGrantCopySegment *seg = &segs[i]; 857 858 refs[i] = to_domain ? seg->dest.foreign.ref : 859 seg->source.foreign.ref; 860 } 861 862 map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs, 863 xendev->frontend_id, refs, 864 prot); 865 if (!map) { 866 error_setg_errno(errp, errno, 867 "xengnttab_map_domain_grant_refs failed"); 868 goto done; 869 } 870 871 for (i = 0; i < nr_segs; i++) { 872 XenDeviceGrantCopySegment *seg = &segs[i]; 873 void *page = map + (i * XC_PAGE_SIZE); 874 875 if (to_domain) { 876 memcpy(page + seg->dest.foreign.offset, seg->source.virt, 877 seg->len); 878 } else { 879 memcpy(seg->dest.virt, page + seg->source.foreign.offset, 880 seg->len); 881 } 882 } 883 884 if (xengnttab_unmap(xendev->xgth, map, nr_segs)) { 885 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 886 } 887 888 done: 889 g_free(refs); 890 } 891 892 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain, 893 XenDeviceGrantCopySegment segs[], 894 unsigned int nr_segs, Error **errp) 895 { 896 xengnttab_grant_copy_segment_t *xengnttab_segs; 897 unsigned int i; 898 899 if (!xendev->feature_grant_copy) { 900 compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp); 901 return; 902 } 903 904 xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs); 905 906 for (i = 0; i < nr_segs; i++) { 907 XenDeviceGrantCopySegment *seg = &segs[i]; 908 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; 909 910 if (to_domain) { 911 xengnttab_seg->flags = GNTCOPY_dest_gref; 912 xengnttab_seg->dest.foreign.domid = xendev->frontend_id; 913 xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref; 914 xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset; 915 xengnttab_seg->source.virt = seg->source.virt; 916 } else { 917 xengnttab_seg->flags = GNTCOPY_source_gref; 918 xengnttab_seg->source.foreign.domid = xendev->frontend_id; 919 xengnttab_seg->source.foreign.ref = seg->source.foreign.ref; 920 xengnttab_seg->source.foreign.offset = 921 seg->source.foreign.offset; 922 xengnttab_seg->dest.virt = seg->dest.virt; 923 } 924 925 xengnttab_seg->len = seg->len; 926 } 927 928 if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) { 929 error_setg_errno(errp, errno, "xengnttab_grant_copy failed"); 930 goto done; 931 } 932 933 for (i = 0; i < nr_segs; i++) { 934 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; 935 936 if (xengnttab_seg->status != GNTST_okay) { 937 error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i); 938 break; 939 } 940 } 941 942 done: 943 g_free(xengnttab_segs); 944 } 945 946 struct XenEventChannel { 947 QLIST_ENTRY(XenEventChannel) list; 948 AioContext *ctx; 949 xenevtchn_handle *xeh; 950 evtchn_port_t local_port; 951 XenEventHandler handler; 952 void *opaque; 953 }; 954 955 static bool xen_device_poll(void *opaque) 956 { 957 XenEventChannel *channel = opaque; 958 959 return channel->handler(channel->opaque); 960 } 961 962 static void xen_device_event(void *opaque) 963 { 964 XenEventChannel *channel = opaque; 965 unsigned long port = xenevtchn_pending(channel->xeh); 966 967 if (port == channel->local_port) { 968 xen_device_poll(channel); 969 970 xenevtchn_unmask(channel->xeh, port); 971 } 972 } 973 974 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, 975 AioContext *ctx, 976 unsigned int port, 977 XenEventHandler handler, 978 void *opaque, Error **errp) 979 { 980 XenEventChannel *channel = g_new0(XenEventChannel, 1); 981 xenevtchn_port_or_error_t local_port; 982 983 channel->xeh = xenevtchn_open(NULL, 0); 984 if (!channel->xeh) { 985 error_setg_errno(errp, errno, "failed xenevtchn_open"); 986 goto fail; 987 } 988 989 local_port = xenevtchn_bind_interdomain(channel->xeh, 990 xendev->frontend_id, 991 port); 992 if (local_port < 0) { 993 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed"); 994 goto fail; 995 } 996 997 channel->local_port = local_port; 998 channel->handler = handler; 999 channel->opaque = opaque; 1000 1001 channel->ctx = ctx; 1002 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, 1003 xen_device_event, NULL, xen_device_poll, channel); 1004 1005 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list); 1006 1007 return channel; 1008 1009 fail: 1010 if (channel->xeh) { 1011 xenevtchn_close(channel->xeh); 1012 } 1013 1014 g_free(channel); 1015 1016 return NULL; 1017 } 1018 1019 void xen_device_notify_event_channel(XenDevice *xendev, 1020 XenEventChannel *channel, 1021 Error **errp) 1022 { 1023 if (!channel) { 1024 error_setg(errp, "bad channel"); 1025 return; 1026 } 1027 1028 if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) { 1029 error_setg_errno(errp, errno, "xenevtchn_notify failed"); 1030 } 1031 } 1032 1033 void xen_device_unbind_event_channel(XenDevice *xendev, 1034 XenEventChannel *channel, 1035 Error **errp) 1036 { 1037 if (!channel) { 1038 error_setg(errp, "bad channel"); 1039 return; 1040 } 1041 1042 QLIST_REMOVE(channel, list); 1043 1044 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, 1045 NULL, NULL, NULL, NULL); 1046 1047 if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) { 1048 error_setg_errno(errp, errno, "xenevtchn_unbind failed"); 1049 } 1050 1051 xenevtchn_close(channel->xeh); 1052 g_free(channel); 1053 } 1054 1055 static void xen_device_unrealize(DeviceState *dev, Error **errp) 1056 { 1057 XenDevice *xendev = XEN_DEVICE(dev); 1058 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1059 const char *type = object_get_typename(OBJECT(xendev)); 1060 XenEventChannel *channel, *next; 1061 1062 if (!xendev->name) { 1063 return; 1064 } 1065 1066 trace_xen_device_unrealize(type, xendev->name); 1067 1068 if (xendev->exit.notify) { 1069 qemu_remove_exit_notifier(&xendev->exit); 1070 xendev->exit.notify = NULL; 1071 } 1072 1073 if (xendev_class->unrealize) { 1074 xendev_class->unrealize(xendev, errp); 1075 } 1076 1077 /* Make sure all event channels are cleaned up */ 1078 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) { 1079 xen_device_unbind_event_channel(xendev, channel, NULL); 1080 } 1081 1082 xen_device_frontend_destroy(xendev); 1083 xen_device_backend_destroy(xendev); 1084 1085 if (xendev->xgth) { 1086 xengnttab_close(xendev->xgth); 1087 xendev->xgth = NULL; 1088 } 1089 1090 g_free(xendev->name); 1091 xendev->name = NULL; 1092 } 1093 1094 static void xen_device_exit(Notifier *n, void *data) 1095 { 1096 XenDevice *xendev = container_of(n, XenDevice, exit); 1097 1098 xen_device_unrealize(DEVICE(xendev), &error_abort); 1099 } 1100 1101 static void xen_device_realize(DeviceState *dev, Error **errp) 1102 { 1103 XenDevice *xendev = XEN_DEVICE(dev); 1104 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1105 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 1106 const char *type = object_get_typename(OBJECT(xendev)); 1107 Error *local_err = NULL; 1108 1109 if (xendev->frontend_id == DOMID_INVALID) { 1110 xendev->frontend_id = xen_domid; 1111 } 1112 1113 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) { 1114 error_setg(errp, "invalid frontend-id"); 1115 goto unrealize; 1116 } 1117 1118 if (!xendev_class->get_name) { 1119 error_setg(errp, "get_name method not implemented"); 1120 goto unrealize; 1121 } 1122 1123 xendev->name = xendev_class->get_name(xendev, &local_err); 1124 if (local_err) { 1125 error_propagate_prepend(errp, local_err, 1126 "failed to get device name: "); 1127 goto unrealize; 1128 } 1129 1130 trace_xen_device_realize(type, xendev->name); 1131 1132 xendev->xgth = xengnttab_open(NULL, 0); 1133 if (!xendev->xgth) { 1134 error_setg_errno(errp, errno, "failed xengnttab_open"); 1135 goto unrealize; 1136 } 1137 1138 xendev->feature_grant_copy = 1139 (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0); 1140 1141 xen_device_backend_create(xendev, &local_err); 1142 if (local_err) { 1143 error_propagate(errp, local_err); 1144 goto unrealize; 1145 } 1146 1147 xen_device_frontend_create(xendev, &local_err); 1148 if (local_err) { 1149 error_propagate(errp, local_err); 1150 goto unrealize; 1151 } 1152 1153 if (xendev_class->realize) { 1154 xendev_class->realize(xendev, &local_err); 1155 if (local_err) { 1156 error_propagate(errp, local_err); 1157 goto unrealize; 1158 } 1159 } 1160 1161 xen_device_backend_printf(xendev, "frontend", "%s", 1162 xendev->frontend_path); 1163 xen_device_backend_printf(xendev, "frontend-id", "%u", 1164 xendev->frontend_id); 1165 xen_device_backend_printf(xendev, "hotplug-status", "connected"); 1166 1167 xen_device_backend_set_online(xendev, true); 1168 xen_device_backend_set_state(xendev, XenbusStateInitWait); 1169 1170 xen_device_frontend_printf(xendev, "backend", "%s", 1171 xendev->backend_path); 1172 xen_device_frontend_printf(xendev, "backend-id", "%u", 1173 xenbus->backend_id); 1174 1175 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true); 1176 1177 xendev->exit.notify = xen_device_exit; 1178 qemu_add_exit_notifier(&xendev->exit); 1179 return; 1180 1181 unrealize: 1182 xen_device_unrealize(dev, &error_abort); 1183 } 1184 1185 static Property xen_device_props[] = { 1186 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id, 1187 DOMID_INVALID), 1188 DEFINE_PROP_END_OF_LIST() 1189 }; 1190 1191 static void xen_device_class_init(ObjectClass *class, void *data) 1192 { 1193 DeviceClass *dev_class = DEVICE_CLASS(class); 1194 1195 dev_class->realize = xen_device_realize; 1196 dev_class->unrealize = xen_device_unrealize; 1197 dev_class->props = xen_device_props; 1198 dev_class->bus_type = TYPE_XEN_BUS; 1199 } 1200 1201 static const TypeInfo xen_device_type_info = { 1202 .name = TYPE_XEN_DEVICE, 1203 .parent = TYPE_DEVICE, 1204 .instance_size = sizeof(XenDevice), 1205 .abstract = true, 1206 .class_size = sizeof(XenDeviceClass), 1207 .class_init = xen_device_class_init, 1208 }; 1209 1210 typedef struct XenBridge { 1211 SysBusDevice busdev; 1212 } XenBridge; 1213 1214 #define TYPE_XEN_BRIDGE "xen-bridge" 1215 1216 static const TypeInfo xen_bridge_type_info = { 1217 .name = TYPE_XEN_BRIDGE, 1218 .parent = TYPE_SYS_BUS_DEVICE, 1219 .instance_size = sizeof(XenBridge), 1220 }; 1221 1222 static void xen_register_types(void) 1223 { 1224 type_register_static(&xen_bridge_type_info); 1225 type_register_static(&xen_bus_type_info); 1226 type_register_static(&xen_device_type_info); 1227 } 1228 1229 type_init(xen_register_types) 1230 1231 void xen_bus_init(void) 1232 { 1233 DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE); 1234 BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL); 1235 1236 qdev_init_nofail(dev); 1237 qbus_set_bus_hotplug_handler(bus, &error_abort); 1238 } 1239