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 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 210 unsigned int port, limit; 211 212 if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", 213 &con->ring_ref) != 1) { 214 error_setg(errp, "failed to read ring-ref"); 215 return false; 216 } 217 218 if (xen_device_frontend_scanf(xendev, "port", "%u", &port) != 1) { 219 error_setg(errp, "failed to read remote port"); 220 return false; 221 } 222 223 if (xen_device_frontend_scanf(xendev, "limit", "%u", &limit) == 1) { 224 con->buffer.max_capacity = limit; 225 } 226 227 con->event_channel = xen_device_bind_event_channel(xendev, port, 228 con_event, 229 con, 230 errp); 231 if (!con->event_channel) { 232 return false; 233 } 234 235 switch (con->dev) { 236 case 0: 237 /* 238 * The primary console is special. For real Xen the ring-ref is 239 * actually a GFN which needs to be mapped as foreignmem. 240 */ 241 if (xen_mode != XEN_EMULATE) { 242 xen_pfn_t mfn = (xen_pfn_t)con->ring_ref; 243 con->sring = qemu_xen_foreignmem_map(xendev->frontend_id, NULL, 244 PROT_READ | PROT_WRITE, 245 1, &mfn, NULL); 246 if (!con->sring) { 247 error_setg(errp, "failed to map console page"); 248 return false; 249 } 250 break; 251 } 252 253 /* 254 * For Xen emulation, we still follow the convention of ring-ref 255 * holding the GFN, but we map the fixed GNTTAB_RESERVED_CONSOLE 256 * grant ref because there is no implementation of foreignmem 257 * operations for emulated mode. The emulation code which handles 258 * the guest-side page and event channel also needs to be informed 259 * of the backend event channel port, in order to reconnect to it 260 * after a soft reset. 261 */ 262 xen_primary_console_set_be_port( 263 xen_event_channel_get_local_port(con->event_channel)); 264 con->ring_ref = GNTTAB_RESERVED_CONSOLE; 265 /* fallthrough */ 266 default: 267 con->sring = xen_device_map_grant_refs(xendev, 268 &con->ring_ref, 1, 269 PROT_READ | PROT_WRITE, 270 errp); 271 if (!con->sring) { 272 error_prepend(errp, "failed to map console grant ref: "); 273 return false; 274 } 275 break; 276 } 277 278 trace_xen_console_connect(con->dev, con->ring_ref, port, 279 con->buffer.max_capacity); 280 281 qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive, 282 xencons_receive, NULL, NULL, con, NULL, 283 true); 284 return true; 285 } 286 287 static void xen_console_disconnect(XenDevice *xendev, Error **errp) 288 { 289 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 290 291 trace_xen_console_disconnect(con->dev); 292 293 qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL, 294 con, NULL, true); 295 296 if (con->event_channel) { 297 xen_device_unbind_event_channel(xendev, con->event_channel, 298 errp); 299 con->event_channel = NULL; 300 301 if (xen_mode == XEN_EMULATE && !con->dev) { 302 xen_primary_console_set_be_port(0); 303 } 304 } 305 306 if (con->sring) { 307 if (!con->dev && xen_mode != XEN_EMULATE) { 308 qemu_xen_foreignmem_unmap(con->sring, 1); 309 } else { 310 xen_device_unmap_grant_refs(xendev, con->sring, 311 &con->ring_ref, 1, errp); 312 } 313 con->sring = NULL; 314 } 315 } 316 317 static void xen_console_frontend_changed(XenDevice *xendev, 318 enum xenbus_state frontend_state, 319 Error **errp) 320 { 321 ERRP_GUARD(); 322 enum xenbus_state backend_state = xen_device_backend_get_state(xendev); 323 324 switch (frontend_state) { 325 case XenbusStateInitialised: 326 case XenbusStateConnected: 327 if (backend_state == XenbusStateConnected) { 328 break; 329 } 330 331 xen_console_disconnect(xendev, errp); 332 if (*errp) { 333 break; 334 } 335 336 if (!xen_console_connect(xendev, errp)) { 337 xen_device_backend_set_state(xendev, XenbusStateClosing); 338 break; 339 } 340 341 xen_device_backend_set_state(xendev, XenbusStateConnected); 342 break; 343 344 case XenbusStateClosing: 345 xen_device_backend_set_state(xendev, XenbusStateClosing); 346 break; 347 348 case XenbusStateClosed: 349 case XenbusStateUnknown: 350 xen_console_disconnect(xendev, errp); 351 if (*errp) { 352 break; 353 } 354 355 xen_device_backend_set_state(xendev, XenbusStateClosed); 356 break; 357 358 default: 359 break; 360 } 361 } 362 363 static char *xen_console_get_name(XenDevice *xendev, Error **errp) 364 { 365 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 366 367 if (con->dev == -1) { 368 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 369 char fe_path[XENSTORE_ABS_PATH_MAX + 1]; 370 int idx = (xen_mode == XEN_EMULATE) ? 0 : 1; 371 char *value; 372 373 /* Theoretically we could go up to INT_MAX here but that's overkill */ 374 while (idx < 100) { 375 if (!idx) { 376 snprintf(fe_path, sizeof(fe_path), 377 "/local/domain/%u/console", xendev->frontend_id); 378 } else { 379 snprintf(fe_path, sizeof(fe_path), 380 "/local/domain/%u/device/console/%u", 381 xendev->frontend_id, idx); 382 } 383 value = qemu_xen_xs_read(xenbus->xsh, XBT_NULL, fe_path, NULL); 384 if (!value) { 385 if (errno == ENOENT) { 386 con->dev = idx; 387 goto found; 388 } 389 error_setg(errp, "cannot read %s: %s", fe_path, 390 strerror(errno)); 391 return NULL; 392 } 393 free(value); 394 idx++; 395 } 396 error_setg(errp, "cannot find device index for console device"); 397 return NULL; 398 } 399 found: 400 return g_strdup_printf("%u", con->dev); 401 } 402 403 static void xen_console_unrealize(XenDevice *xendev) 404 { 405 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 406 407 trace_xen_console_unrealize(con->dev); 408 409 /* Disconnect from the frontend in case this has not already happened */ 410 xen_console_disconnect(xendev, NULL); 411 412 qemu_chr_fe_deinit(&con->chr, false); 413 } 414 415 static void xen_console_realize(XenDevice *xendev, Error **errp) 416 { 417 ERRP_GUARD(); 418 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 419 Chardev *cs = qemu_chr_fe_get_driver(&con->chr); 420 unsigned int u; 421 422 if (!cs) { 423 error_setg(errp, "no backing character device"); 424 return; 425 } 426 427 if (con->dev == -1) { 428 error_setg(errp, "no device index provided"); 429 return; 430 } 431 432 /* 433 * The Xen primary console is special. The ring-ref is actually a GFN to 434 * be mapped directly as foreignmem (not a grant ref), and the guest port 435 * was allocated *for* the guest by the toolstack. The guest gets these 436 * through HVMOP_get_param and can use the console long before it's got 437 * XenStore up and running. We cannot create those for a true Xen guest, 438 * but we can for Xen emulation. 439 */ 440 if (!con->dev) { 441 if (xen_mode == XEN_EMULATE) { 442 xen_primary_console_create(); 443 } else if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", &u) 444 != 1 || 445 xen_device_frontend_scanf(xendev, "port", "%u", &u) != 1) { 446 error_setg(errp, "cannot create primary Xen console"); 447 return; 448 } 449 } 450 451 trace_xen_console_realize(con->dev, object_get_typename(OBJECT(cs))); 452 453 if (CHARDEV_IS_PTY(cs)) { 454 /* Strip the leading 'pty:' */ 455 xen_device_frontend_printf(xendev, "tty", "%s", cs->filename + 4); 456 } 457 458 /* No normal PV driver initialization for the primary console under Xen */ 459 if (!con->dev && xen_mode != XEN_EMULATE) { 460 xen_console_connect(xendev, errp); 461 } 462 } 463 464 static char *console_frontend_path(struct qemu_xs_handle *xenstore, 465 unsigned int dom_id, unsigned int dev) 466 { 467 if (!dev) { 468 return g_strdup_printf("/local/domain/%u/console", dom_id); 469 } else { 470 return g_strdup_printf("/local/domain/%u/device/console/%u", dom_id, 471 dev); 472 } 473 } 474 475 static char *xen_console_get_frontend_path(XenDevice *xendev, Error **errp) 476 { 477 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 478 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev))); 479 char *ret = console_frontend_path(xenbus->xsh, xendev->frontend_id, 480 con->dev); 481 482 if (!ret) { 483 error_setg(errp, "failed to create frontend path"); 484 } 485 return ret; 486 } 487 488 489 static Property xen_console_properties[] = { 490 DEFINE_PROP_CHR("chardev", XenConsole, chr), 491 DEFINE_PROP_INT32("idx", XenConsole, dev, -1), 492 DEFINE_PROP_END_OF_LIST(), 493 }; 494 495 static void xen_console_class_init(ObjectClass *class, void *data) 496 { 497 DeviceClass *dev_class = DEVICE_CLASS(class); 498 XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class); 499 500 xendev_class->backend = "console"; 501 xendev_class->device = "console"; 502 xendev_class->get_name = xen_console_get_name; 503 xendev_class->realize = xen_console_realize; 504 xendev_class->frontend_changed = xen_console_frontend_changed; 505 xendev_class->unrealize = xen_console_unrealize; 506 xendev_class->get_frontend_path = xen_console_get_frontend_path; 507 508 device_class_set_props(dev_class, xen_console_properties); 509 } 510 511 static const TypeInfo xen_console_type_info = { 512 .name = TYPE_XEN_CONSOLE_DEVICE, 513 .parent = TYPE_XEN_DEVICE, 514 .instance_size = sizeof(XenConsole), 515 .class_init = xen_console_class_init, 516 }; 517 518 static void xen_console_register_types(void) 519 { 520 type_register_static(&xen_console_type_info); 521 } 522 523 type_init(xen_console_register_types) 524 525 /* Called to instantiate a XenConsole when the backend is detected. */ 526 static void xen_console_device_create(XenBackendInstance *backend, 527 QDict *opts, Error **errp) 528 { 529 ERRP_GUARD(); 530 XenBus *xenbus = xen_backend_get_bus(backend); 531 const char *name = xen_backend_get_name(backend); 532 unsigned long number; 533 char *fe = NULL, *type = NULL, *output = NULL; 534 char label[32]; 535 XenDevice *xendev = NULL; 536 XenConsole *con; 537 Chardev *cd = NULL; 538 struct qemu_xs_handle *xsh = xenbus->xsh; 539 540 if (qemu_strtoul(name, NULL, 10, &number) || number > INT_MAX) { 541 error_setg(errp, "failed to parse name '%s'", name); 542 goto fail; 543 } 544 545 trace_xen_console_device_create(number); 546 547 fe = console_frontend_path(xsh, xen_domid, number); 548 if (fe == NULL) { 549 error_setg(errp, "failed to generate frontend path"); 550 goto fail; 551 } 552 553 if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) { 554 error_prepend(errp, "failed to read console device type: "); 555 goto fail; 556 } 557 558 if (strcmp(type, "ioemu")) { 559 error_setg(errp, "declining to handle console type '%s'", 560 type); 561 goto fail; 562 } 563 564 xendev = XEN_DEVICE(qdev_new(TYPE_XEN_CONSOLE_DEVICE)); 565 con = XEN_CONSOLE_DEVICE(xendev); 566 567 con->dev = number; 568 569 snprintf(label, sizeof(label), "xencons%ld", number); 570 571 if (xs_node_scanf(xsh, XBT_NULL, fe, "output", NULL, "%ms", &output) == 1) { 572 /* 573 * FIXME: sure we want to support implicit 574 * muxed monitors here? 575 */ 576 cd = qemu_chr_new_mux_mon(label, output, NULL); 577 if (!cd) { 578 error_setg(errp, "console: No valid chardev found at '%s': ", 579 output); 580 goto fail; 581 } 582 } else if (number) { 583 cd = serial_hd(number); 584 if (!cd) { 585 error_prepend(errp, "console: No serial device #%ld found: ", 586 number); 587 goto fail; 588 } 589 } else { 590 /* No 'output' node on primary console: use null. */ 591 cd = qemu_chr_new(label, "null", NULL); 592 if (!cd) { 593 error_setg(errp, "console: failed to create null device"); 594 goto fail; 595 } 596 } 597 598 if (!qemu_chr_fe_init(&con->chr, cd, errp)) { 599 error_prepend(errp, "console: failed to initialize backing chardev: "); 600 goto fail; 601 } 602 603 if (qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) { 604 xen_backend_set_device(backend, xendev); 605 goto done; 606 } 607 608 error_prepend(errp, "realization of console device %lu failed: ", 609 number); 610 611 fail: 612 if (xendev) { 613 object_unparent(OBJECT(xendev)); 614 } 615 done: 616 g_free(fe); 617 free(type); 618 free(output); 619 } 620 621 static void xen_console_device_destroy(XenBackendInstance *backend, 622 Error **errp) 623 { 624 ERRP_GUARD(); 625 XenDevice *xendev = xen_backend_get_device(backend); 626 XenConsole *con = XEN_CONSOLE_DEVICE(xendev); 627 628 trace_xen_console_device_destroy(con->dev); 629 630 object_unparent(OBJECT(xendev)); 631 } 632 633 static const XenBackendInfo xen_console_backend_info = { 634 .type = "console", 635 .create = xen_console_device_create, 636 .destroy = xen_console_device_destroy, 637 }; 638 639 static void xen_console_register_backend(void) 640 { 641 xen_backend_register(&xen_console_backend_info); 642 } 643 644 xen_backend_init(xen_console_register_backend); 645