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