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 local_err = NULL; 361 } 362 363 g_free(node); 364 } 365 366 g_free(type); 367 g_free(key); 368 return; 369 370 fail: 371 xen_bus_unrealize(bus); 372 g_free(key); 373 } 374 375 static void xen_bus_unplug_request(HotplugHandler *hotplug, 376 DeviceState *dev, 377 Error **errp) 378 { 379 XenDevice *xendev = XEN_DEVICE(dev); 380 381 xen_device_unplug(xendev, errp); 382 } 383 384 static void xen_bus_class_init(ObjectClass *class, void *data) 385 { 386 BusClass *bus_class = BUS_CLASS(class); 387 HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class); 388 389 bus_class->print_dev = xen_bus_print_dev; 390 bus_class->get_dev_path = xen_bus_get_dev_path; 391 bus_class->realize = xen_bus_realize; 392 bus_class->unrealize = xen_bus_unrealize; 393 394 hotplug_class->unplug_request = xen_bus_unplug_request; 395 } 396 397 static const TypeInfo xen_bus_type_info = { 398 .name = TYPE_XEN_BUS, 399 .parent = TYPE_BUS, 400 .instance_size = sizeof(XenBus), 401 .class_size = sizeof(XenBusClass), 402 .class_init = xen_bus_class_init, 403 .interfaces = (InterfaceInfo[]) { 404 { TYPE_HOTPLUG_HANDLER }, 405 { } 406 }, 407 }; 408 409 void xen_device_backend_printf(XenDevice *xendev, const char *key, 410 const char *fmt, ...) 411 { 412 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 413 Error *local_err = NULL; 414 va_list ap; 415 416 g_assert(xenbus->xsh); 417 418 va_start(ap, fmt); 419 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, 420 &local_err, fmt, ap); 421 va_end(ap); 422 423 if (local_err) { 424 error_report_err(local_err); 425 } 426 } 427 428 G_GNUC_SCANF(3, 4) 429 static int xen_device_backend_scanf(XenDevice *xendev, const char *key, 430 const char *fmt, ...) 431 { 432 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 433 va_list ap; 434 int rc; 435 436 g_assert(xenbus->xsh); 437 438 va_start(ap, fmt); 439 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->backend_path, key, 440 NULL, fmt, ap); 441 va_end(ap); 442 443 return rc; 444 } 445 446 void xen_device_backend_set_state(XenDevice *xendev, 447 enum xenbus_state state) 448 { 449 const char *type = object_get_typename(OBJECT(xendev)); 450 451 if (xendev->backend_state == state) { 452 return; 453 } 454 455 trace_xen_device_backend_state(type, xendev->name, 456 xs_strstate(state)); 457 458 xendev->backend_state = state; 459 xen_device_backend_printf(xendev, "state", "%u", state); 460 } 461 462 enum xenbus_state xen_device_backend_get_state(XenDevice *xendev) 463 { 464 return xendev->backend_state; 465 } 466 467 static void xen_device_backend_set_online(XenDevice *xendev, bool online) 468 { 469 const char *type = object_get_typename(OBJECT(xendev)); 470 471 if (xendev->backend_online == online) { 472 return; 473 } 474 475 trace_xen_device_backend_online(type, xendev->name, online); 476 477 xendev->backend_online = online; 478 xen_device_backend_printf(xendev, "online", "%u", online); 479 } 480 481 /* 482 * Tell from the state whether the frontend is likely alive, 483 * i.e. it will react to a change of state of the backend. 484 */ 485 static bool xen_device_frontend_is_active(XenDevice *xendev) 486 { 487 switch (xendev->frontend_state) { 488 case XenbusStateInitWait: 489 case XenbusStateInitialised: 490 case XenbusStateConnected: 491 case XenbusStateClosing: 492 return true; 493 default: 494 return false; 495 } 496 } 497 498 static void xen_device_backend_changed(void *opaque, const char *path) 499 { 500 XenDevice *xendev = opaque; 501 const char *type = object_get_typename(OBJECT(xendev)); 502 enum xenbus_state state; 503 unsigned int online; 504 505 trace_xen_device_backend_changed(type, xendev->name); 506 507 if (xen_device_backend_scanf(xendev, "state", "%u", &state) != 1) { 508 state = XenbusStateUnknown; 509 } 510 511 xen_device_backend_set_state(xendev, state); 512 513 if (xen_device_backend_scanf(xendev, "online", "%u", &online) != 1) { 514 online = 0; 515 } 516 517 xen_device_backend_set_online(xendev, !!online); 518 519 /* 520 * If the toolstack (or unplug request callback) has set the backend 521 * state to Closing, but there is no active frontend then set the 522 * backend state to Closed. 523 */ 524 if (state == XenbusStateClosing && 525 !xen_device_frontend_is_active(xendev)) { 526 xen_device_backend_set_state(xendev, XenbusStateClosed); 527 } 528 529 /* 530 * If a backend is still 'online' then we should leave it alone but, 531 * if a backend is not 'online', then the device is a candidate 532 * for destruction. Hence add it to the 'inactive' list to be cleaned 533 * by xen_bus_cleanup(). 534 */ 535 if (!online && 536 (state == XenbusStateClosed || state == XenbusStateInitialising || 537 state == XenbusStateInitWait || state == XenbusStateUnknown) && 538 !xendev->inactive) { 539 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 540 541 xendev->inactive = true; 542 QLIST_INSERT_HEAD(&xenbus->inactive_devices, xendev, list); 543 544 /* 545 * Re-write the state to cause a XenBus backend_watch notification, 546 * resulting in a call to xen_bus_cleanup(). 547 */ 548 xen_device_backend_printf(xendev, "state", "%u", state); 549 } 550 } 551 552 static void xen_device_backend_create(XenDevice *xendev, Error **errp) 553 { 554 ERRP_GUARD(); 555 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 556 557 xendev->backend_path = xen_device_get_backend_path(xendev); 558 559 g_assert(xenbus->xsh); 560 561 xs_node_create(xenbus->xsh, XBT_NULL, xendev->backend_path, 562 xenbus->backend_id, xendev->frontend_id, XS_PERM_READ, errp); 563 if (*errp) { 564 error_prepend(errp, "failed to create backend: "); 565 return; 566 } 567 568 xendev->backend_state_watch = 569 xs_node_watch(xendev->xsh, xendev->backend_path, 570 "state", xen_device_backend_changed, xendev, 571 errp); 572 if (*errp) { 573 error_prepend(errp, "failed to watch backend state: "); 574 return; 575 } 576 577 xendev->backend_online_watch = 578 xs_node_watch(xendev->xsh, xendev->backend_path, 579 "online", xen_device_backend_changed, xendev, 580 errp); 581 if (*errp) { 582 error_prepend(errp, "failed to watch backend online: "); 583 return; 584 } 585 } 586 587 static void xen_device_backend_destroy(XenDevice *xendev) 588 { 589 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 590 Error *local_err = NULL; 591 592 if (xendev->backend_online_watch) { 593 xs_node_unwatch(xendev->xsh, xendev->backend_online_watch); 594 xendev->backend_online_watch = NULL; 595 } 596 597 if (xendev->backend_state_watch) { 598 xs_node_unwatch(xendev->xsh, xendev->backend_state_watch); 599 xendev->backend_state_watch = NULL; 600 } 601 602 if (!xendev->backend_path) { 603 return; 604 } 605 606 g_assert(xenbus->xsh); 607 608 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->backend_path, 609 &local_err); 610 g_free(xendev->backend_path); 611 xendev->backend_path = NULL; 612 613 if (local_err) { 614 error_report_err(local_err); 615 } 616 } 617 618 void xen_device_frontend_printf(XenDevice *xendev, const char *key, 619 const char *fmt, ...) 620 { 621 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 622 Error *local_err = NULL; 623 va_list ap; 624 625 g_assert(xenbus->xsh); 626 627 va_start(ap, fmt); 628 xs_node_vprintf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 629 &local_err, fmt, ap); 630 va_end(ap); 631 632 if (local_err) { 633 error_report_err(local_err); 634 } 635 } 636 637 int xen_device_frontend_scanf(XenDevice *xendev, const char *key, 638 const char *fmt, ...) 639 { 640 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 641 va_list ap; 642 int rc; 643 644 g_assert(xenbus->xsh); 645 646 va_start(ap, fmt); 647 rc = xs_node_vscanf(xenbus->xsh, XBT_NULL, xendev->frontend_path, key, 648 NULL, fmt, ap); 649 va_end(ap); 650 651 return rc; 652 } 653 654 char *xen_device_frontend_read(XenDevice *xendev, const char *key) 655 { 656 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 657 658 g_assert(xenbus->xsh); 659 660 return xs_node_read(xenbus->xsh, XBT_NULL, NULL, NULL, "%s/%s", 661 xendev->frontend_path, key); 662 } 663 664 static void xen_device_frontend_set_state(XenDevice *xendev, 665 enum xenbus_state state, 666 bool publish) 667 { 668 const char *type = object_get_typename(OBJECT(xendev)); 669 670 if (xendev->frontend_state == state) { 671 return; 672 } 673 674 trace_xen_device_frontend_state(type, xendev->name, 675 xs_strstate(state)); 676 677 xendev->frontend_state = state; 678 if (publish) { 679 xen_device_frontend_printf(xendev, "state", "%u", state); 680 } 681 } 682 683 static void xen_device_frontend_changed(void *opaque, const char *path) 684 { 685 XenDevice *xendev = opaque; 686 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 687 const char *type = object_get_typename(OBJECT(xendev)); 688 enum xenbus_state state; 689 690 trace_xen_device_frontend_changed(type, xendev->name); 691 692 if (xen_device_frontend_scanf(xendev, "state", "%u", &state) != 1) { 693 state = XenbusStateUnknown; 694 } 695 696 xen_device_frontend_set_state(xendev, state, false); 697 698 if (state == XenbusStateInitialising && 699 xendev->backend_state == XenbusStateClosed && 700 xendev->backend_online) { 701 /* 702 * The frontend is re-initializing so switch back to 703 * InitWait. 704 */ 705 xen_device_backend_set_state(xendev, XenbusStateInitWait); 706 return; 707 } 708 709 if (xendev_class->frontend_changed) { 710 Error *local_err = NULL; 711 712 xendev_class->frontend_changed(xendev, state, &local_err); 713 714 if (local_err) { 715 error_reportf_err(local_err, "frontend change error: "); 716 } 717 } 718 } 719 720 static bool xen_device_frontend_exists(XenDevice *xendev) 721 { 722 enum xenbus_state state; 723 724 return (xen_device_frontend_scanf(xendev, "state", "%u", &state) == 1); 725 } 726 727 static void xen_device_frontend_create(XenDevice *xendev, Error **errp) 728 { 729 ERRP_GUARD(); 730 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 731 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 732 733 if (xendev_class->get_frontend_path) { 734 xendev->frontend_path = xendev_class->get_frontend_path(xendev, errp); 735 if (!xendev->frontend_path) { 736 error_prepend(errp, "failed to create frontend: "); 737 return; 738 } 739 } else { 740 xendev->frontend_path = xen_device_get_frontend_path(xendev); 741 } 742 743 /* 744 * The frontend area may have already been created by a legacy 745 * toolstack. 746 */ 747 if (!xen_device_frontend_exists(xendev)) { 748 g_assert(xenbus->xsh); 749 750 xs_node_create(xenbus->xsh, XBT_NULL, xendev->frontend_path, 751 xendev->frontend_id, xenbus->backend_id, 752 XS_PERM_READ | XS_PERM_WRITE, errp); 753 if (*errp) { 754 error_prepend(errp, "failed to create frontend: "); 755 return; 756 } 757 } 758 759 xendev->frontend_state_watch = 760 xs_node_watch(xendev->xsh, xendev->frontend_path, "state", 761 xen_device_frontend_changed, xendev, errp); 762 if (*errp) { 763 error_prepend(errp, "failed to watch frontend state: "); 764 } 765 } 766 767 static void xen_device_frontend_destroy(XenDevice *xendev) 768 { 769 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 770 Error *local_err = NULL; 771 772 if (xendev->frontend_state_watch) { 773 xs_node_unwatch(xendev->xsh, xendev->frontend_state_watch); 774 xendev->frontend_state_watch = NULL; 775 } 776 777 if (!xendev->frontend_path) { 778 return; 779 } 780 781 g_assert(xenbus->xsh); 782 783 xs_node_destroy(xenbus->xsh, XBT_NULL, xendev->frontend_path, 784 &local_err); 785 g_free(xendev->frontend_path); 786 xendev->frontend_path = NULL; 787 788 if (local_err) { 789 error_report_err(local_err); 790 } 791 } 792 793 void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs, 794 Error **errp) 795 { 796 if (qemu_xen_gnttab_set_max_grants(xendev->xgth, nr_refs)) { 797 error_setg_errno(errp, errno, "xengnttab_set_max_grants failed"); 798 } 799 } 800 801 void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs, 802 unsigned int nr_refs, int prot, 803 Error **errp) 804 { 805 void *map = qemu_xen_gnttab_map_refs(xendev->xgth, nr_refs, 806 xendev->frontend_id, refs, prot); 807 808 if (!map) { 809 error_setg_errno(errp, errno, 810 "xengnttab_map_domain_grant_refs failed"); 811 } 812 813 return map; 814 } 815 816 void xen_device_unmap_grant_refs(XenDevice *xendev, void *map, uint32_t *refs, 817 unsigned int nr_refs, Error **errp) 818 { 819 if (qemu_xen_gnttab_unmap(xendev->xgth, map, refs, nr_refs)) { 820 error_setg_errno(errp, errno, "xengnttab_unmap failed"); 821 } 822 } 823 824 void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain, 825 XenDeviceGrantCopySegment segs[], 826 unsigned int nr_segs, Error **errp) 827 { 828 qemu_xen_gnttab_grant_copy(xendev->xgth, to_domain, xendev->frontend_id, 829 (XenGrantCopySegment *)segs, nr_segs, errp); 830 } 831 832 struct XenEventChannel { 833 QLIST_ENTRY(XenEventChannel) list; 834 AioContext *ctx; 835 xenevtchn_handle *xeh; 836 evtchn_port_t local_port; 837 XenEventHandler handler; 838 void *opaque; 839 }; 840 841 static bool xen_device_poll(void *opaque) 842 { 843 XenEventChannel *channel = opaque; 844 845 return channel->handler(channel->opaque); 846 } 847 848 static void xen_device_event(void *opaque) 849 { 850 XenEventChannel *channel = opaque; 851 unsigned long port = qemu_xen_evtchn_pending(channel->xeh); 852 853 if (port == channel->local_port) { 854 xen_device_poll(channel); 855 856 qemu_xen_evtchn_unmask(channel->xeh, port); 857 } 858 } 859 860 void xen_device_set_event_channel_context(XenDevice *xendev, 861 XenEventChannel *channel, 862 AioContext *ctx, 863 Error **errp) 864 { 865 if (!channel) { 866 error_setg(errp, "bad channel"); 867 return; 868 } 869 870 if (channel->ctx) 871 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), 872 NULL, NULL, NULL, NULL, NULL); 873 874 channel->ctx = ctx; 875 if (ctx) { 876 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), 877 xen_device_event, NULL, xen_device_poll, NULL, 878 channel); 879 } 880 } 881 882 XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev, 883 unsigned int port, 884 XenEventHandler handler, 885 void *opaque, Error **errp) 886 { 887 XenEventChannel *channel = g_new0(XenEventChannel, 1); 888 xenevtchn_port_or_error_t local_port; 889 890 channel->xeh = qemu_xen_evtchn_open(); 891 if (!channel->xeh) { 892 error_setg_errno(errp, errno, "failed xenevtchn_open"); 893 goto fail; 894 } 895 896 local_port = qemu_xen_evtchn_bind_interdomain(channel->xeh, 897 xendev->frontend_id, 898 port); 899 if (local_port < 0) { 900 error_setg_errno(errp, errno, "xenevtchn_bind_interdomain failed"); 901 goto fail; 902 } 903 904 channel->local_port = local_port; 905 channel->handler = handler; 906 channel->opaque = opaque; 907 908 /* Only reason for failure is a NULL channel */ 909 xen_device_set_event_channel_context(xendev, channel, 910 qemu_get_aio_context(), 911 &error_abort); 912 913 QLIST_INSERT_HEAD(&xendev->event_channels, channel, list); 914 915 return channel; 916 917 fail: 918 if (channel->xeh) { 919 qemu_xen_evtchn_close(channel->xeh); 920 } 921 922 g_free(channel); 923 924 return NULL; 925 } 926 927 void xen_device_notify_event_channel(XenDevice *xendev, 928 XenEventChannel *channel, 929 Error **errp) 930 { 931 if (!channel) { 932 error_setg(errp, "bad channel"); 933 return; 934 } 935 936 if (qemu_xen_evtchn_notify(channel->xeh, channel->local_port) < 0) { 937 error_setg_errno(errp, errno, "xenevtchn_notify failed"); 938 } 939 } 940 941 unsigned int xen_event_channel_get_local_port(XenEventChannel *channel) 942 { 943 return channel->local_port; 944 } 945 946 void xen_device_unbind_event_channel(XenDevice *xendev, 947 XenEventChannel *channel, 948 Error **errp) 949 { 950 if (!channel) { 951 error_setg(errp, "bad channel"); 952 return; 953 } 954 955 QLIST_REMOVE(channel, list); 956 957 if (channel->ctx) { 958 aio_set_fd_handler(channel->ctx, qemu_xen_evtchn_fd(channel->xeh), 959 NULL, NULL, NULL, NULL, NULL); 960 } 961 962 if (qemu_xen_evtchn_unbind(channel->xeh, channel->local_port) < 0) { 963 error_setg_errno(errp, errno, "xenevtchn_unbind failed"); 964 } 965 966 qemu_xen_evtchn_close(channel->xeh); 967 g_free(channel); 968 } 969 970 static void xen_device_unrealize(DeviceState *dev) 971 { 972 XenDevice *xendev = XEN_DEVICE(dev); 973 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 974 const char *type = object_get_typename(OBJECT(xendev)); 975 XenEventChannel *channel, *next; 976 977 if (!xendev->name) { 978 return; 979 } 980 981 trace_xen_device_unrealize(type, xendev->name); 982 983 if (xendev->exit.notify) { 984 qemu_remove_exit_notifier(&xendev->exit); 985 xendev->exit.notify = NULL; 986 } 987 988 if (xendev_class->unrealize) { 989 xendev_class->unrealize(xendev); 990 } 991 992 /* Make sure all event channels are cleaned up */ 993 QLIST_FOREACH_SAFE(channel, &xendev->event_channels, list, next) { 994 xen_device_unbind_event_channel(xendev, channel, NULL); 995 } 996 997 xen_device_frontend_destroy(xendev); 998 xen_device_backend_destroy(xendev); 999 1000 if (xendev->xgth) { 1001 qemu_xen_gnttab_close(xendev->xgth); 1002 xendev->xgth = NULL; 1003 } 1004 1005 if (xendev->xsh) { 1006 qemu_xen_xs_close(xendev->xsh); 1007 xendev->xsh = NULL; 1008 } 1009 1010 g_free(xendev->name); 1011 xendev->name = NULL; 1012 } 1013 1014 static void xen_device_exit(Notifier *n, void *data) 1015 { 1016 XenDevice *xendev = container_of(n, XenDevice, exit); 1017 1018 xen_device_unrealize(DEVICE(xendev)); 1019 } 1020 1021 static void xen_device_realize(DeviceState *dev, Error **errp) 1022 { 1023 ERRP_GUARD(); 1024 XenDevice *xendev = XEN_DEVICE(dev); 1025 XenDeviceClass *xendev_class = XEN_DEVICE_GET_CLASS(xendev); 1026 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 1027 const char *type = object_get_typename(OBJECT(xendev)); 1028 1029 if (xendev->frontend_id == DOMID_INVALID) { 1030 xendev->frontend_id = xen_domid; 1031 } 1032 1033 if (xendev->frontend_id >= DOMID_FIRST_RESERVED) { 1034 error_setg(errp, "invalid frontend-id"); 1035 goto unrealize; 1036 } 1037 1038 if (!xendev_class->get_name) { 1039 error_setg(errp, "get_name method not implemented"); 1040 goto unrealize; 1041 } 1042 1043 xendev->name = xendev_class->get_name(xendev, errp); 1044 if (*errp) { 1045 error_prepend(errp, "failed to get device name: "); 1046 goto unrealize; 1047 } 1048 1049 trace_xen_device_realize(type, xendev->name); 1050 1051 xendev->xsh = qemu_xen_xs_open(); 1052 if (!xendev->xsh) { 1053 error_setg_errno(errp, errno, "failed xs_open"); 1054 goto unrealize; 1055 } 1056 1057 xendev->xgth = qemu_xen_gnttab_open(); 1058 if (!xendev->xgth) { 1059 error_setg_errno(errp, errno, "failed xengnttab_open"); 1060 goto unrealize; 1061 } 1062 1063 xen_device_backend_create(xendev, errp); 1064 if (*errp) { 1065 goto unrealize; 1066 } 1067 1068 xen_device_frontend_create(xendev, errp); 1069 if (*errp) { 1070 goto unrealize; 1071 } 1072 1073 xen_device_backend_printf(xendev, "frontend", "%s", 1074 xendev->frontend_path); 1075 xen_device_backend_printf(xendev, "frontend-id", "%u", 1076 xendev->frontend_id); 1077 xen_device_backend_printf(xendev, "hotplug-status", "connected"); 1078 1079 xen_device_backend_set_online(xendev, true); 1080 xen_device_backend_set_state(xendev, XenbusStateInitWait); 1081 1082 if (!xen_device_frontend_exists(xendev)) { 1083 xen_device_frontend_printf(xendev, "backend", "%s", 1084 xendev->backend_path); 1085 xen_device_frontend_printf(xendev, "backend-id", "%u", 1086 xenbus->backend_id); 1087 1088 xen_device_frontend_set_state(xendev, XenbusStateInitialising, true); 1089 } 1090 1091 if (xendev_class->realize) { 1092 xendev_class->realize(xendev, errp); 1093 if (*errp) { 1094 goto unrealize; 1095 } 1096 } 1097 1098 xendev->exit.notify = xen_device_exit; 1099 qemu_add_exit_notifier(&xendev->exit); 1100 return; 1101 1102 unrealize: 1103 xen_device_unrealize(dev); 1104 } 1105 1106 static const Property xen_device_props[] = { 1107 DEFINE_PROP_UINT16("frontend-id", XenDevice, frontend_id, 1108 DOMID_INVALID), 1109 }; 1110 1111 static void xen_device_class_init(ObjectClass *class, void *data) 1112 { 1113 DeviceClass *dev_class = DEVICE_CLASS(class); 1114 1115 dev_class->realize = xen_device_realize; 1116 dev_class->unrealize = xen_device_unrealize; 1117 device_class_set_props(dev_class, xen_device_props); 1118 dev_class->bus_type = TYPE_XEN_BUS; 1119 } 1120 1121 static const TypeInfo xen_device_type_info = { 1122 .name = TYPE_XEN_DEVICE, 1123 .parent = TYPE_DEVICE, 1124 .instance_size = sizeof(XenDevice), 1125 .abstract = true, 1126 .class_size = sizeof(XenDeviceClass), 1127 .class_init = xen_device_class_init, 1128 }; 1129 1130 typedef struct XenBridge { 1131 SysBusDevice busdev; 1132 } XenBridge; 1133 1134 #define TYPE_XEN_BRIDGE "xen-bridge" 1135 1136 static const TypeInfo xen_bridge_type_info = { 1137 .name = TYPE_XEN_BRIDGE, 1138 .parent = TYPE_SYS_BUS_DEVICE, 1139 .instance_size = sizeof(XenBridge), 1140 }; 1141 1142 static void xen_register_types(void) 1143 { 1144 type_register_static(&xen_bridge_type_info); 1145 type_register_static(&xen_bus_type_info); 1146 type_register_static(&xen_device_type_info); 1147 } 1148 1149 type_init(xen_register_types) 1150 1151 void xen_bus_init(void) 1152 { 1153 DeviceState *dev = qdev_new(TYPE_XEN_BRIDGE); 1154 BusState *bus = qbus_new(TYPE_XEN_BUS, dev, NULL); 1155 1156 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); 1157 qbus_set_bus_hotplug_handler(bus); 1158 1159 qemu_create_nic_bus_devices(bus, TYPE_XEN_DEVICE, "xen-net-device", 1160 "xen", "xen-net-device"); 1161 } 1162