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