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