1 /* 2 * Copyright (C) International Business Machines Corp., 2005 3 * Author(s): Anthony Liguori <aliguori@us.ibm.com> 4 * 5 * Copyright (C) Red Hat 2007 6 * 7 * Xen Console 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; under version 2 of the License. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include "qemu/osdep.h" 23 #include "qemu/cutils.h" 24 #include <sys/select.h> 25 #include <termios.h> 26 27 #include "qapi/error.h" 28 #include "sysemu/sysemu.h" 29 #include "chardev/char-fe.h" 30 #include "hw/xen/xen-backend.h" 31 #include "hw/xen/xen-bus-helper.h" 32 #include "hw/qdev-properties.h" 33 #include "hw/qdev-properties-system.h" 34 #include "hw/xen/interface/io/console.h" 35 #include "hw/xen/interface/io/xs_wire.h" 36 #include "hw/xen/interface/grant_table.h" 37 #include "hw/i386/kvm/xen_primary_console.h" 38 #include "trace.h" 39 40 struct buffer { 41 uint8_t *data; 42 size_t consumed; 43 size_t size; 44 size_t capacity; 45 size_t max_capacity; 46 }; 47 48 struct XenConsole { 49 struct XenDevice xendev; /* must be first */ 50 XenEventChannel *event_channel; 51 int dev; 52 struct buffer buffer; 53 char *fe_path; 54 unsigned int ring_ref; 55 void *sring; 56 CharBackend chr; 57 int backlog; 58 }; 59 typedef struct XenConsole XenConsole; 60 61 #define TYPE_XEN_CONSOLE_DEVICE "xen-console" 62 OBJECT_DECLARE_SIMPLE_TYPE(XenConsole, XEN_CONSOLE_DEVICE) 63 64 static bool buffer_append(XenConsole *con) 65 { 66 struct buffer *buffer = &con->buffer; 67 XENCONS_RING_IDX cons, prod, size; 68 struct xencons_interface *intf = con->sring; 69 70 cons = intf->out_cons; 71 prod = intf->out_prod; 72 xen_mb(); 73 74 size = prod - cons; 75 if ((size == 0) || (size > sizeof(intf->out))) 76 return false; 77 78 if ((buffer->capacity - buffer->size) < size) { 79 buffer->capacity += (size + 1024); 80 buffer->data = g_realloc(buffer->data, buffer->capacity); 81 } 82 83 while (cons != prod) 84 buffer->data[buffer->size++] = intf->out[ 85 MASK_XENCONS_IDX(cons++, intf->out)]; 86 87 xen_mb(); 88 intf->out_cons = cons; 89 xen_device_notify_event_channel(XEN_DEVICE(con), con->event_channel, NULL); 90 91 if (buffer->max_capacity && 92 buffer->size > buffer->max_capacity) { 93 /* Discard the middle of the data. */ 94 95 size_t over = buffer->size - buffer->max_capacity; 96 uint8_t *maxpos = buffer->data + buffer->max_capacity; 97 98 memmove(maxpos - over, maxpos, over); 99 buffer->data = g_realloc(buffer->data, buffer->max_capacity); 100 buffer->size = buffer->capacity = buffer->max_capacity; 101 102 if (buffer->consumed > buffer->max_capacity - over) 103 buffer->consumed = buffer->max_capacity - over; 104 } 105 return true; 106 } 107 108 static void buffer_advance(struct buffer *buffer, size_t len) 109 { 110 buffer->consumed += len; 111 if (buffer->consumed == buffer->size) { 112 buffer->consumed = 0; 113 buffer->size = 0; 114 } 115 } 116 117 static int ring_free_bytes(XenConsole *con) 118 { 119 struct xencons_interface *intf = con->sring; 120 XENCONS_RING_IDX cons, prod, space; 121 122 cons = intf->in_cons; 123 prod = intf->in_prod; 124 xen_mb(); 125 126 space = prod - cons; 127 if (space > sizeof(intf->in)) 128 return 0; /* ring is screwed: ignore it */ 129 130 return (sizeof(intf->in) - space); 131 } 132 133 static int xencons_can_receive(void *opaque) 134 { 135 XenConsole *con = opaque; 136 return ring_free_bytes(con); 137 } 138 139 static void xencons_receive(void *opaque, const uint8_t *buf, int len) 140 { 141 XenConsole *con = opaque; 142 struct xencons_interface *intf = con->sring; 143 XENCONS_RING_IDX prod; 144 int i, max; 145 146 max = ring_free_bytes(con); 147 /* The can_receive() func limits this, but check again anyway */ 148 if (max < len) 149 len = max; 150 151 prod = intf->in_prod; 152 for (i = 0; i < len; i++) { 153 intf->in[MASK_XENCONS_IDX(prod++, intf->in)] = 154 buf[i]; 155 } 156 xen_wmb(); 157 intf->in_prod = prod; 158 xen_device_notify_event_channel(XEN_DEVICE(con), con->event_channel, NULL); 159 } 160 161 static bool xencons_send(XenConsole *con) 162 { 163 ssize_t len, size; 164 165 size = con->buffer.size - con->buffer.consumed; 166 if (qemu_chr_fe_backend_connected(&con->chr)) { 167 len = qemu_chr_fe_write(&con->chr, 168 con->buffer.data + con->buffer.consumed, 169 size); 170 } else { 171 len = size; 172 } 173 if (len < 1) { 174 if (!con->backlog) { 175 con->backlog = 1; 176 } 177 } else { 178 buffer_advance(&con->buffer, len); 179 if (con->backlog && len == size) { 180 con->backlog = 0; 181 } 182 } 183 return len > 0; 184 } 185 186 /* -------------------------------------------------------------------- */ 187 188 static bool con_event(void *_xendev) 189 { 190 XenConsole *con = XEN_CONSOLE_DEVICE(_xendev); 191 bool done_something; 192 193 if (xen_device_backend_get_state(&con->xendev) != XenbusStateConnected) { 194 return false; 195 } 196 197 done_something = buffer_append(con); 198 199 if (con->buffer.size - con->buffer.consumed) { 200 done_something |= xencons_send(con); 201 } 202 return done_something; 203 } 204 205 /* -------------------------------------------------------------------- */ 206 207 static bool xen_console_connect(XenDevice *xendev, Error **errp) 208 { 209 ERRP_GUARD(); 210 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 211 unsigned int port, limit; 212 213 if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", 214 &con->ring_ref) != 1) { 215 error_setg(errp, "failed to read ring-ref"); 216 return false; 217 } 218 219 if (xen_device_frontend_scanf(xendev, "port", "%u", &port) != 1) { 220 error_setg(errp, "failed to read remote port"); 221 return false; 222 } 223 224 if (xen_device_frontend_scanf(xendev, "limit", "%u", &limit) == 1) { 225 con->buffer.max_capacity = limit; 226 } 227 228 con->event_channel = xen_device_bind_event_channel(xendev, port, 229 con_event, 230 con, 231 errp); 232 if (!con->event_channel) { 233 return false; 234 } 235 236 switch (con->dev) { 237 case 0: 238 /* 239 * The primary console is special. For real Xen the ring-ref is 240 * actually a GFN which needs to be mapped as foreignmem. 241 */ 242 if (xen_mode != XEN_EMULATE) { 243 xen_pfn_t mfn = (xen_pfn_t)con->ring_ref; 244 con->sring = qemu_xen_foreignmem_map(xendev->frontend_id, NULL, 245 PROT_READ | PROT_WRITE, 246 1, &mfn, NULL); 247 if (!con->sring) { 248 error_setg(errp, "failed to map console page"); 249 return false; 250 } 251 break; 252 } 253 254 /* 255 * For Xen emulation, we still follow the convention of ring-ref 256 * holding the GFN, but we map the fixed GNTTAB_RESERVED_CONSOLE 257 * grant ref because there is no implementation of foreignmem 258 * operations for emulated mode. The emulation code which handles 259 * the guest-side page and event channel also needs to be informed 260 * of the backend event channel port, in order to reconnect to it 261 * after a soft reset. 262 */ 263 xen_primary_console_set_be_port( 264 xen_event_channel_get_local_port(con->event_channel)); 265 con->ring_ref = GNTTAB_RESERVED_CONSOLE; 266 /* fallthrough */ 267 default: 268 con->sring = xen_device_map_grant_refs(xendev, 269 &con->ring_ref, 1, 270 PROT_READ | PROT_WRITE, 271 errp); 272 if (!con->sring) { 273 error_prepend(errp, "failed to map console grant ref: "); 274 return false; 275 } 276 break; 277 } 278 279 trace_xen_console_connect(con->dev, con->ring_ref, port, 280 con->buffer.max_capacity); 281 282 qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive, 283 xencons_receive, NULL, NULL, con, NULL, 284 true); 285 return true; 286 } 287 288 static void xen_console_disconnect(XenDevice *xendev, Error **errp) 289 { 290 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 291 292 trace_xen_console_disconnect(con->dev); 293 294 qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL, 295 con, NULL, true); 296 297 if (con->event_channel) { 298 xen_device_unbind_event_channel(xendev, con->event_channel, 299 errp); 300 con->event_channel = NULL; 301 302 if (xen_mode == XEN_EMULATE && !con->dev) { 303 xen_primary_console_set_be_port(0); 304 } 305 } 306 307 if (con->sring) { 308 if (!con->dev && xen_mode != XEN_EMULATE) { 309 qemu_xen_foreignmem_unmap(con->sring, 1); 310 } else { 311 xen_device_unmap_grant_refs(xendev, con->sring, 312 &con->ring_ref, 1, errp); 313 } 314 con->sring = NULL; 315 } 316 } 317 318 static void xen_console_frontend_changed(XenDevice *xendev, 319 enum xenbus_state frontend_state, 320 Error **errp) 321 { 322 ERRP_GUARD(); 323 enum xenbus_state backend_state = xen_device_backend_get_state(xendev); 324 325 switch (frontend_state) { 326 case XenbusStateInitialised: 327 case XenbusStateConnected: 328 if (backend_state == XenbusStateConnected) { 329 break; 330 } 331 332 xen_console_disconnect(xendev, errp); 333 if (*errp) { 334 break; 335 } 336 337 if (!xen_console_connect(xendev, errp)) { 338 xen_device_backend_set_state(xendev, XenbusStateClosing); 339 break; 340 } 341 342 xen_device_backend_set_state(xendev, XenbusStateConnected); 343 break; 344 345 case XenbusStateClosing: 346 xen_device_backend_set_state(xendev, XenbusStateClosing); 347 break; 348 349 case XenbusStateClosed: 350 case XenbusStateUnknown: 351 xen_console_disconnect(xendev, errp); 352 if (*errp) { 353 break; 354 } 355 356 xen_device_backend_set_state(xendev, XenbusStateClosed); 357 break; 358 359 default: 360 break; 361 } 362 } 363 364 static char *xen_console_get_name(XenDevice *xendev, Error **errp) 365 { 366 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 367 368 if (con->dev == -1) { 369 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 370 char fe_path[XENSTORE_ABS_PATH_MAX + 1]; 371 int idx = (xen_mode == XEN_EMULATE) ? 0 : 1; 372 char *value; 373 374 /* Theoretically we could go up to INT_MAX here but that's overkill */ 375 while (idx < 100) { 376 if (!idx) { 377 snprintf(fe_path, sizeof(fe_path), 378 "/local/domain/%u/console", xendev->frontend_id); 379 } else { 380 snprintf(fe_path, sizeof(fe_path), 381 "/local/domain/%u/device/console/%u", 382 xendev->frontend_id, idx); 383 } 384 value = qemu_xen_xs_read(xenbus->xsh, XBT_NULL, fe_path, NULL); 385 if (!value) { 386 if (errno == ENOENT) { 387 con->dev = idx; 388 goto found; 389 } 390 error_setg(errp, "cannot read %s: %s", fe_path, 391 strerror(errno)); 392 return NULL; 393 } 394 free(value); 395 idx++; 396 } 397 error_setg(errp, "cannot find device index for console device"); 398 return NULL; 399 } 400 found: 401 return g_strdup_printf("%u", con->dev); 402 } 403 404 static void xen_console_unrealize(XenDevice *xendev) 405 { 406 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 407 408 trace_xen_console_unrealize(con->dev); 409 410 /* Disconnect from the frontend in case this has not already happened */ 411 xen_console_disconnect(xendev, NULL); 412 413 qemu_chr_fe_deinit(&con->chr, false); 414 } 415 416 static void xen_console_realize(XenDevice *xendev, Error **errp) 417 { 418 ERRP_GUARD(); 419 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 420 Chardev *cs = qemu_chr_fe_get_driver(&con->chr); 421 unsigned int u; 422 423 if (!cs) { 424 error_setg(errp, "no backing character device"); 425 return; 426 } 427 428 if (con->dev == -1) { 429 error_setg(errp, "no device index provided"); 430 return; 431 } 432 433 /* 434 * The Xen primary console is special. The ring-ref is actually a GFN to 435 * be mapped directly as foreignmem (not a grant ref), and the guest port 436 * was allocated *for* the guest by the toolstack. The guest gets these 437 * through HVMOP_get_param and can use the console long before it's got 438 * XenStore up and running. We cannot create those for a true Xen guest, 439 * but we can for Xen emulation. 440 */ 441 if (!con->dev) { 442 if (xen_mode == XEN_EMULATE) { 443 xen_primary_console_create(); 444 } else if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", &u) 445 != 1 || 446 xen_device_frontend_scanf(xendev, "port", "%u", &u) != 1) { 447 error_setg(errp, "cannot create primary Xen console"); 448 return; 449 } 450 } 451 452 trace_xen_console_realize(con->dev, object_get_typename(OBJECT(cs))); 453 454 if (CHARDEV_IS_PTY(cs)) { 455 /* Strip the leading 'pty:' */ 456 xen_device_frontend_printf(xendev, "tty", "%s", cs->filename + 4); 457 } 458 459 /* No normal PV driver initialization for the primary console under Xen */ 460 if (!con->dev && xen_mode != XEN_EMULATE) { 461 xen_console_connect(xendev, errp); 462 } 463 } 464 465 static char *console_frontend_path(struct qemu_xs_handle *xenstore, 466 unsigned int dom_id, unsigned int dev) 467 { 468 if (!dev) { 469 return g_strdup_printf("/local/domain/%u/console", dom_id); 470 } else { 471 return g_strdup_printf("/local/domain/%u/device/console/%u", dom_id, 472 dev); 473 } 474 } 475 476 static char *xen_console_get_frontend_path(XenDevice *xendev, Error **errp) 477 { 478 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 479 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 480 char *ret = console_frontend_path(xenbus->xsh, xendev->frontend_id, 481 con->dev); 482 483 if (!ret) { 484 error_setg(errp, "failed to create frontend path"); 485 } 486 return ret; 487 } 488 489 490 static Property xen_console_properties[] = { 491 DEFINE_PROP_CHR("chardev", XenConsole, chr), 492 DEFINE_PROP_INT32("idx", XenConsole, dev, -1), 493 DEFINE_PROP_END_OF_LIST(), 494 }; 495 496 static void xen_console_class_init(ObjectClass *class, void *data) 497 { 498 DeviceClass *dev_class = DEVICE_CLASS(class); 499 XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class); 500 501 xendev_class->backend = "console"; 502 xendev_class->device = "console"; 503 xendev_class->get_name = xen_console_get_name; 504 xendev_class->realize = xen_console_realize; 505 xendev_class->frontend_changed = xen_console_frontend_changed; 506 xendev_class->unrealize = xen_console_unrealize; 507 xendev_class->get_frontend_path = xen_console_get_frontend_path; 508 509 device_class_set_props(dev_class, xen_console_properties); 510 } 511 512 static const TypeInfo xen_console_type_info = { 513 .name = TYPE_XEN_CONSOLE_DEVICE, 514 .parent = TYPE_XEN_DEVICE, 515 .instance_size = sizeof(XenConsole), 516 .class_init = xen_console_class_init, 517 }; 518 519 static void xen_console_register_types(void) 520 { 521 type_register_static(&xen_console_type_info); 522 } 523 524 type_init(xen_console_register_types) 525 526 /* Called to instantiate a XenConsole when the backend is detected. */ 527 static void xen_console_device_create(XenBackendInstance *backend, 528 QDict *opts, Error **errp) 529 { 530 ERRP_GUARD(); 531 XenBus *xenbus = xen_backend_get_bus(backend); 532 const char *name = xen_backend_get_name(backend); 533 unsigned long number; 534 char *fe = NULL, *type = NULL, *output = NULL; 535 char label[32]; 536 XenDevice *xendev = NULL; 537 XenConsole *con; 538 Chardev *cd = NULL; 539 struct qemu_xs_handle *xsh = xenbus->xsh; 540 541 if (qemu_strtoul(name, NULL, 10, &number) || number > INT_MAX) { 542 error_setg(errp, "failed to parse name '%s'", name); 543 goto fail; 544 } 545 546 trace_xen_console_device_create(number); 547 548 fe = console_frontend_path(xsh, xen_domid, number); 549 if (fe == NULL) { 550 error_setg(errp, "failed to generate frontend path"); 551 goto fail; 552 } 553 554 if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) { 555 error_prepend(errp, "failed to read console device type: "); 556 goto fail; 557 } 558 559 if (strcmp(type, "ioemu")) { 560 error_setg(errp, "declining to handle console type '%s'", 561 type); 562 goto fail; 563 } 564 565 xendev = XEN_DEVICE(qdev_new(TYPE_XEN_CONSOLE_DEVICE)); 566 con = XEN_CONSOLE_DEVICE(xendev); 567 568 con->dev = number; 569 570 snprintf(label, sizeof(label), "xencons%ld", number); 571 572 if (xs_node_scanf(xsh, XBT_NULL, fe, "output", NULL, "%ms", &output) == 1) { 573 /* 574 * FIXME: sure we want to support implicit 575 * muxed monitors here? 576 */ 577 cd = qemu_chr_new_mux_mon(label, output, NULL); 578 if (!cd) { 579 error_setg(errp, "console: No valid chardev found at '%s': ", 580 output); 581 goto fail; 582 } 583 } else if (number) { 584 cd = serial_hd(number); 585 if (!cd) { 586 error_prepend(errp, "console: No serial device #%ld found: ", 587 number); 588 goto fail; 589 } 590 } else { 591 /* No 'output' node on primary console: use null. */ 592 cd = qemu_chr_new(label, "null", NULL); 593 if (!cd) { 594 error_setg(errp, "console: failed to create null device"); 595 goto fail; 596 } 597 } 598 599 if (!qemu_chr_fe_init(&con->chr, cd, errp)) { 600 error_prepend(errp, "console: failed to initialize backing chardev: "); 601 goto fail; 602 } 603 604 if (qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) { 605 xen_backend_set_device(backend, xendev); 606 goto done; 607 } 608 609 error_prepend(errp, "realization of console device %lu failed: ", 610 number); 611 612 fail: 613 if (xendev) { 614 object_unparent(OBJECT(xendev)); 615 } 616 done: 617 g_free(fe); 618 free(type); 619 free(output); 620 } 621 622 static void xen_console_device_destroy(XenBackendInstance *backend, 623 Error **errp) 624 { 625 ERRP_GUARD(); 626 XenDevice *xendev = xen_backend_get_device(backend); 627 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 628 629 trace_xen_console_device_destroy(con->dev); 630 631 object_unparent(OBJECT(xendev)); 632 } 633 634 static const XenBackendInfo xen_console_backend_info = { 635 .type = "console", 636 .create = xen_console_device_create, 637 .destroy = xen_console_device_destroy, 638 }; 639 640 static void xen_console_register_backend(void) 641 { 642 xen_backend_register(&xen_console_backend_info); 643 } 644 645 xen_backend_init(xen_console_register_backend); 646