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 static void xen_device_backend_changed(void *opaque) 520 { 521 XenDevice *xendev = opaque; 522 const char *type = object_get_typename(OBJECT(xendev)); 523 enum xenbus_state state; 524 unsigned int online; 525 526 trace_xen_device_backend_changed(type, xendev->name); 527 528 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) { 529 state = XenbusStateUnknown; 530 } 531 532 xen_device_backend_set_state(xendev, state); 533 534 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) { 535 online = 0; 536 } 537 538 xen_device_backend_set_online(xendev, !!online); 539 540 /* 541 * If the toolstack (or unplug request callback) has set the backend 542 * state to Closing, but there is no active frontend (i.e. the 543 * state is not Connected) then set the backend state to Closed. 544 */ 545 if (xendev->backend_state == XenbusStateClosing && 546 xendev->frontend_state != XenbusStateConnected) { 547 xen_device_backend_set_state(xendev, XenbusStateClosed); 548 } 549 550 /* 551 * If a backend is still 'online' then we should leave it alone but, 552 * if a backend is not 'online', then the device should be destroyed 553 * once the state is Closed. 554 */ 555 if (!xendev->backend_online && 556 (xendev->backend_state == XenbusStateClosed || 557 xendev->backend_state == XenbusStateInitialising || 558 xendev->backend_state == XenbusStateInitWait || 559 xendev->backend_state == XenbusStateUnknown)) { 560 Error *local_err = NULL; 561 562 if (!xen_backend_try_device_destroy(xendev, &local_err)) { 563 object_unparent(OBJECT(xendev)); 564 } 565 566 if (local_err) { 567 error_report_err(local_err); 568 } 569 } 570 } 571 572 static void xen_device_backend_create(XenDevice *xendev, Error **errp) 573 { 574 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 575 struct xs_permissions perms[2]; 576 Error *local_err = NULL; 577 578 xendev->backend_path = xen_device_get_backend_path(xendev); 579 580 perms[0].id = xenbus->backend_id; 581 perms[0].perms = XS_PERM_NONE; 582 perms[1].id = xendev->frontend_id; 583 perms[1].perms = XS_PERM_READ; 584 585 g_assert(xenbus->xsh); 586 587 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, perms, 588 ARRAY_SIZE(perms), &local_err); 589 if (local_err) { 590 error_propagate_prepend(errp, local_err, 591 "failed to create backend: "); 592 return; 593 } 594 595 xendev->backend_state_watch = 596 xen_bus_add_watch(xenbus, xendev->backend_path, 597 "state", xen_device_backend_changed, 598 xendev, &local_err); 599 if (local_err) { 600 error_propagate_prepend(errp, local_err, 601 "failed to watch backend state: "); 602 return; 603 } 604 605 xendev->backend_online_watch = 606 xen_bus_add_watch(xenbus, xendev->backend_path, 607 "online", xen_device_backend_changed, 608 xendev, &local_err); 609 if (local_err) { 610 error_propagate_prepend(errp, local_err, 611 "failed to watch backend online: "); 612 return; 613 } 614 } 615 616 static void xen_device_backend_destroy(XenDevice *xendev) 617 { 618 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 619 Error *local_err = NULL; 620 621 if (xendev->backend_online_watch) { 622 xen_bus_remove_watch(xenbus, xendev->backend_online_watch, NULL); 623 xendev->backend_online_watch = NULL; 624 } 625 626 if (xendev->backend_state_watch) { 627 xen_bus_remove_watch(xenbus, xendev->backend_state_watch, NULL); 628 xendev->backend_state_watch = NULL; 629 } 630 631 if (!xendev->backend_path) { 632 return; 633 } 634 635 g_assert(xenbus->xsh); 636 637 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path, 638 &local_err); 639 g_free(xendev->backend_path); 640 xendev->backend_path = NULL; 641 642 if (local_err) { 643 error_report_err(local_err); 644 } 645 } 646 647 void xen_device_frontend_printf(XenDevice *xendev, const char *key, 648 const char *fmt, ...) 649 { 650 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 651 Error *local_err = NULL; 652 va_list ap; 653 654 g_assert(xenbus->xsh); 655 656 va_start(ap, fmt); 657 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 658 &local_err, fmt, ap); 659 va_end(ap); 660 661 if (local_err) { 662 error_report_err(local_err); 663 } 664 } 665 666 int xen_device_frontend_scanf(XenDevice *xendev, const char *key, 667 const char *fmt, ...) 668 { 669 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 670 va_list ap; 671 int rc; 672 673 g_assert(xenbus->xsh); 674 675 va_start(ap, fmt); 676 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 677 NULL, fmt, ap); 678 va_end(ap); 679 680 return rc; 681 } 682 683 static void xen_device_frontend_set_state(XenDevice *xendev, 684 enum xenbus_state state) 685 { 686 const char *type = object_get_typename(OBJECT(xendev)); 687 688 if (xendev->frontend_state == state) { 689 return; 690 } 691 692 trace_xen_device_frontend_state(type, xendev->name, 693 xs_strstate(state)); 694 695 xendev->frontend_state = state; 696 xen_device_frontend_printf(xendev, "state", "%u", state); 697 } 698 699 static void xen_device_frontend_changed(void *opaque) 700 { 701 XenDevice *xendev = opaque; 702 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 703 const char *type = object_get_typename(OBJECT(xendev)); 704 enum xenbus_state state; 705 706 trace_xen_device_frontend_changed(type, xendev->name); 707 708 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) { 709 state = XenbusStateUnknown; 710 } 711 712 xen_device_frontend_set_state(xendev, state); 713 714 if (state == XenbusStateInitialising && 715 xendev->backend_state == XenbusStateClosed && 716 xendev->backend_online) { 717 /* 718 * The frontend is re-initializing so switch back to 719 * InitWait. 720 */ 721 xen_device_backend_set_state(xendev, XenbusStateInitWait); 722 return; 723 } 724 725 if (xendev_class->frontend_changed) { 726 Error *local_err = NULL; 727 728 xendev_class->frontend_changed(xendev, state, &local_err); 729 730 if (local_err) { 731 error_reportf_err(local_err, "frontend change error: "); 732 } 733 } 734 } 735 736 static void xen_device_frontend_create(XenDevice *xendev, Error **errp) 737 { 738 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 739 struct xs_permissions perms[2]; 740 Error *local_err = NULL; 741 742 xendev->frontend_path = xen_device_get_frontend_path(xendev); 743 744 perms[0].id = xendev->frontend_id; 745 perms[0].perms = XS_PERM_NONE; 746 perms[1].id = xenbus->backend_id; 747 perms[1].perms = XS_PERM_READ | XS_PERM_WRITE; 748 749 g_assert(xenbus->xsh); 750 751 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, perms, 752 ARRAY_SIZE(perms), &local_err); 753 if (local_err) { 754 error_propagate_prepend(errp, local_err, 755 "failed to create frontend: "); 756 return; 757 } 758 759 xendev->frontend_state_watch = 760 xen_bus_add_watch(xenbus, xendev->frontend_path, "state", 761 xen_device_frontend_changed, xendev, &local_err); 762 if (local_err) { 763 error_propagate_prepend(errp, local_err, 764 "failed to watch frontend state: "); 765 } 766 } 767 768 static void xen_device_frontend_destroy(XenDevice *xendev) 769 { 770 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 771 Error *local_err = NULL; 772 773 if (xendev->frontend_state_watch) { 774 xen_bus_remove_watch(xenbus, xendev->frontend_state_watch, NULL); 775 xendev->frontend_state_watch = NULL; 776 } 777 778 if (!xendev->frontend_path) { 779 return; 780 } 781 782 g_assert(xenbus->xsh); 783 784 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path, 785 &local_err); 786 g_free(xendev->frontend_path); 787 xendev->frontend_path = NULL; 788 789 if (local_err) { 790 error_report_err(local_err); 791 } 792 } 793 794 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, 795 Error **errp) 796 { 797 if (xengnttab_set_max_grants(xendev->xgth, nr_refs)) { 798 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed"); 799 } 800 } 801 802 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, 803 unsigned int nr_refs, int prot, 804 Error **errp) 805 { 806 void *map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_refs, 807 xendev->frontend_id, refs, 808 prot); 809 810 if (!map) { 811 error_setg_errno(errp, errno, 812 "xengnttab_map_domain_grant_refs failed"); 813 } 814 815 return map; 816 } 817 818 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, 819 unsigned int nr_refs, Error **errp) 820 { 821 if (xengnttab_unmap(xendev->xgth, map, nr_refs)) { 822 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 823 } 824 } 825 826 static void compat_copy_grant_refs(XenDevice *xendev, bool to_domain, 827 XenDeviceGrantCopySegment segs[], 828 unsigned int nr_segs, Error **errp) 829 { 830 uint32_t *refs = g_new(uint32_t, nr_segs); 831 int prot = to_domain ? PROT_WRITE : PROT_READ; 832 void *map; 833 unsigned int i; 834 835 for (i = 0; i < nr_segs; i++) { 836 XenDeviceGrantCopySegment *seg = &segs[i]; 837 838 refs[i] = to_domain ? seg->dest.foreign.ref : 839 seg->source.foreign.ref; 840 } 841 842 map = xengnttab_map_domain_grant_refs(xendev->xgth, nr_segs, 843 xendev->frontend_id, refs, 844 prot); 845 if (!map) { 846 error_setg_errno(errp, errno, 847 "xengnttab_map_domain_grant_refs failed"); 848 goto done; 849 } 850 851 for (i = 0; i < nr_segs; i++) { 852 XenDeviceGrantCopySegment *seg = &segs[i]; 853 void *page = map + (i * XC_PAGE_SIZE); 854 855 if (to_domain) { 856 memcpy(page + seg->dest.foreign.offset, seg->source.virt, 857 seg->len); 858 } else { 859 memcpy(seg->dest.virt, page + seg->source.foreign.offset, 860 seg->len); 861 } 862 } 863 864 if (xengnttab_unmap(xendev->xgth, map, nr_segs)) { 865 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 866 } 867 868 done: 869 g_free(refs); 870 } 871 872 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain, 873 XenDeviceGrantCopySegment segs[], 874 unsigned int nr_segs, Error **errp) 875 { 876 xengnttab_grant_copy_segment_t *xengnttab_segs; 877 unsigned int i; 878 879 if (!xendev->feature_grant_copy) { 880 compat_copy_grant_refs(xendev, to_domain, segs, nr_segs, errp); 881 return; 882 } 883 884 xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs); 885 886 for (i = 0; i < nr_segs; i++) { 887 XenDeviceGrantCopySegment *seg = &segs[i]; 888 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; 889 890 if (to_domain) { 891 xengnttab_seg->flags = GNTCOPY_dest_gref; 892 xengnttab_seg->dest.foreign.domid = xendev->frontend_id; 893 xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref; 894 xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset; 895 xengnttab_seg->source.virt = seg->source.virt; 896 } else { 897 xengnttab_seg->flags = GNTCOPY_source_gref; 898 xengnttab_seg->source.foreign.domid = xendev->frontend_id; 899 xengnttab_seg->source.foreign.ref = seg->source.foreign.ref; 900 xengnttab_seg->source.foreign.offset = 901 seg->source.foreign.offset; 902 xengnttab_seg->dest.virt = seg->dest.virt; 903 } 904 905 xengnttab_seg->len = seg->len; 906 } 907 908 if (xengnttab_grant_copy(xendev->xgth, nr_segs, xengnttab_segs)) { 909 error_setg_errno(errp, errno, "xengnttab_grant_copy failed"); 910 goto done; 911 } 912 913 for (i = 0; i < nr_segs; i++) { 914 xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; 915 916 if (xengnttab_seg->status != GNTST_okay) { 917 error_setg(errp, "xengnttab_grant_copy seg[%u] failed", i); 918 break; 919 } 920 } 921 922 done: 923 g_free(xengnttab_segs); 924 } 925 926 struct XenEventChannel { 927 QLIST_ENTRY(XenEventChannel) list; 928 AioContext *ctx; 929 xenevtchn_handle *xeh; 930 evtchn_port_t local_port; 931 XenEventHandler handler; 932 void *opaque; 933 }; 934 935 static bool xen_device_poll(void *opaque) 936 { 937 XenEventChannel *channel = opaque; 938 939 return channel->handler(channel->opaque); 940 } 941 942 static void xen_device_event(void *opaque) 943 { 944 XenEventChannel *channel = opaque; 945 unsigned long port = xenevtchn_pending(channel->xeh); 946 947 if (port == channel->local_port) { 948 xen_device_poll(channel); 949 950 xenevtchn_unmask(channel->xeh, port); 951 } 952 } 953 954 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, 955 AioContext *ctx, 956 unsigned int port, 957 XenEventHandler handler, 958 void *opaque, Error **errp) 959 { 960 XenEventChannel *channel = g_new0(XenEventChannel, 1); 961 xenevtchn_port_or_error_t local_port; 962 963 channel->xeh = xenevtchn_open(NULL, 0); 964 if (!channel->xeh) { 965 error_setg_errno(errp, errno, "failed xenevtchn_open"); 966 goto fail; 967 } 968 969 local_port = xenevtchn_bind_interdomain(channel->xeh, 970 xendev->frontend_id, 971 port); 972 if (local_port < 0) { 973 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed"); 974 goto fail; 975 } 976 977 channel->local_port = local_port; 978 channel->handler = handler; 979 channel->opaque = opaque; 980 981 channel->ctx = ctx; 982 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, 983 xen_device_event, NULL, xen_device_poll, channel); 984 985 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list); 986 987 return channel; 988 989 fail: 990 if (channel->xeh) { 991 xenevtchn_close(channel->xeh); 992 } 993 994 g_free(channel); 995 996 return NULL; 997 } 998 999 void xen_device_notify_event_channel(XenDevice *xendev, 1000 XenEventChannel *channel, 1001 Error **errp) 1002 { 1003 if (!channel) { 1004 error_setg(errp, "bad channel"); 1005 return; 1006 } 1007 1008 if (xenevtchn_notify(channel->xeh, channel->local_port) < 0) { 1009 error_setg_errno(errp, errno, "xenevtchn_notify failed"); 1010 } 1011 } 1012 1013 void xen_device_unbind_event_channel(XenDevice *xendev, 1014 XenEventChannel *channel, 1015 Error **errp) 1016 { 1017 if (!channel) { 1018 error_setg(errp, "bad channel"); 1019 return; 1020 } 1021 1022 QLIST_REMOVE(channel, list); 1023 1024 aio_set_fd_handler(channel->ctx, xenevtchn_fd(channel->xeh), true, 1025 NULL, NULL, NULL, NULL); 1026 1027 if (xenevtchn_unbind(channel->xeh, channel->local_port) < 0) { 1028 error_setg_errno(errp, errno, "xenevtchn_unbind failed"); 1029 } 1030 1031 xenevtchn_close(channel->xeh); 1032 g_free(channel); 1033 } 1034 1035 static void xen_device_unrealize(DeviceState *dev, Error **errp) 1036 { 1037 XenDevice *xendev = XEN_DEVICE(dev); 1038 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1039 const char *type = object_get_typename(OBJECT(xendev)); 1040 XenEventChannel *channel, *next; 1041 1042 if (!xendev->name) { 1043 return; 1044 } 1045 1046 trace_xen_device_unrealize(type, xendev->name); 1047 1048 if (xendev->exit.notify) { 1049 qemu_remove_exit_notifier(&xendev->exit); 1050 xendev->exit.notify = NULL; 1051 } 1052 1053 if (xendev_class->unrealize) { 1054 xendev_class->unrealize(xendev, errp); 1055 } 1056 1057 /* Make sure all event channels are cleaned up */ 1058 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) { 1059 xen_device_unbind_event_channel(xendev, channel, NULL); 1060 } 1061 1062 xen_device_frontend_destroy(xendev); 1063 xen_device_backend_destroy(xendev); 1064 1065 if (xendev->xgth) { 1066 xengnttab_close(xendev->xgth); 1067 xendev->xgth = NULL; 1068 } 1069 1070 g_free(xendev->name); 1071 xendev->name = NULL; 1072 } 1073 1074 static void xen_device_exit(Notifier *n, void *data) 1075 { 1076 XenDevice *xendev = container_of(n, XenDevice, exit); 1077 1078 xen_device_unrealize(DEVICE(xendev), &error_abort); 1079 } 1080 1081 static void xen_device_realize(DeviceState *dev, Error **errp) 1082 { 1083 XenDevice *xendev = XEN_DEVICE(dev); 1084 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1085 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 1086 const char *type = object_get_typename(OBJECT(xendev)); 1087 Error *local_err = NULL; 1088 1089 if (xendev->frontend_id == DOMID_INVALID) { 1090 xendev->frontend_id = xen_domid; 1091 } 1092 1093 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) { 1094 error_setg(errp, "invalid frontend-id"); 1095 goto unrealize; 1096 } 1097 1098 if (!xendev_class->get_name) { 1099 error_setg(errp, "get_name method not implemented"); 1100 goto unrealize; 1101 } 1102 1103 xendev->name = xendev_class->get_name(xendev, &local_err); 1104 if (local_err) { 1105 error_propagate_prepend(errp, local_err, 1106 "failed to get device name: "); 1107 goto unrealize; 1108 } 1109 1110 trace_xen_device_realize(type, xendev->name); 1111 1112 xendev->xgth = xengnttab_open(NULL, 0); 1113 if (!xendev->xgth) { 1114 error_setg_errno(errp, errno, "failed xengnttab_open"); 1115 goto unrealize; 1116 } 1117 1118 xendev->feature_grant_copy = 1119 (xengnttab_grant_copy(xendev->xgth, 0, NULL) == 0); 1120 1121 xen_device_backend_create(xendev, &local_err); 1122 if (local_err) { 1123 error_propagate(errp, local_err); 1124 goto unrealize; 1125 } 1126 1127 xen_device_frontend_create(xendev, &local_err); 1128 if (local_err) { 1129 error_propagate(errp, local_err); 1130 goto unrealize; 1131 } 1132 1133 if (xendev_class->realize) { 1134 xendev_class->realize(xendev, &local_err); 1135 if (local_err) { 1136 error_propagate(errp, local_err); 1137 goto unrealize; 1138 } 1139 } 1140 1141 xen_device_backend_printf(xendev, "frontend", "%s", 1142 xendev->frontend_path); 1143 xen_device_backend_printf(xendev, "frontend-id", "%u", 1144 xendev->frontend_id); 1145 xen_device_backend_printf(xendev, "hotplug-status", "connected"); 1146 1147 xen_device_backend_set_online(xendev, true); 1148 xen_device_backend_set_state(xendev, XenbusStateInitWait); 1149 1150 xen_device_frontend_printf(xendev, "backend", "%s", 1151 xendev->backend_path); 1152 xen_device_frontend_printf(xendev, "backend-id", "%u", 1153 xenbus->backend_id); 1154 1155 xen_device_frontend_set_state(xendev, XenbusStateInitialising); 1156 1157 xendev->exit.notify = xen_device_exit; 1158 qemu_add_exit_notifier(&xendev->exit); 1159 return; 1160 1161 unrealize: 1162 xen_device_unrealize(dev, &error_abort); 1163 } 1164 1165 static Property xen_device_props[] = { 1166 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id, 1167 DOMID_INVALID), 1168 DEFINE_PROP_END_OF_LIST() 1169 }; 1170 1171 static void xen_device_class_init(ObjectClass *class, void *data) 1172 { 1173 DeviceClass *dev_class = DEVICE_CLASS(class); 1174 1175 dev_class->realize = xen_device_realize; 1176 dev_class->unrealize = xen_device_unrealize; 1177 dev_class->props = xen_device_props; 1178 dev_class->bus_type = TYPE_XEN_BUS; 1179 } 1180 1181 static const TypeInfo xen_device_type_info = { 1182 .name = TYPE_XEN_DEVICE, 1183 .parent = TYPE_DEVICE, 1184 .instance_size = sizeof(XenDevice), 1185 .abstract = true, 1186 .class_size = sizeof(XenDeviceClass), 1187 .class_init = xen_device_class_init, 1188 }; 1189 1190 typedef struct XenBridge { 1191 SysBusDevice busdev; 1192 } XenBridge; 1193 1194 #define TYPE_XEN_BRIDGE "xen-bridge" 1195 1196 static const TypeInfo xen_bridge_type_info = { 1197 .name = TYPE_XEN_BRIDGE, 1198 .parent = TYPE_SYS_BUS_DEVICE, 1199 .instance_size = sizeof(XenBridge), 1200 }; 1201 1202 static void xen_register_types(void) 1203 { 1204 type_register_static(&xen_bridge_type_info); 1205 type_register_static(&xen_bus_type_info); 1206 type_register_static(&xen_device_type_info); 1207 } 1208 1209 type_init(xen_register_types) 1210 1211 void xen_bus_init(void) 1212 { 1213 DeviceState *dev = qdev_create(NULL, TYPE_XEN_BRIDGE); 1214 BusState *bus = qbus_create(TYPE_XEN_BUS, dev, NULL); 1215 1216 qdev_init_nofail(dev); 1217 qbus_set_bus_hotplug_handler(bus, &error_abort); 1218 } 1219