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