1 /* 2 * Copyright (c) 2015 Julien Grall <julien.grall@citrix.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/module.h> 29 #include <sys/systm.h> 30 #include <sys/eventhandler.h> 31 #include <sys/consio.h> 32 #include <sys/priv.h> 33 #include <sys/proc.h> 34 #include <sys/uio.h> 35 #include <sys/tty.h> 36 #include <sys/systm.h> 37 #include <sys/taskqueue.h> 38 #include <sys/conf.h> 39 #include <sys/kernel.h> 40 #include <sys/bus.h> 41 #include <sys/cons.h> 42 #include <sys/kdb.h> 43 #include <sys/proc.h> 44 #include <sys/reboot.h> 45 46 #include <machine/stdarg.h> 47 48 #include <vm/vm.h> 49 #include <vm/pmap.h> 50 51 #include <xen/xen-os.h> 52 #include <xen/hypervisor.h> 53 #include <xen/xen_intr.h> 54 #include <contrib/xen/io/console.h> 55 56 #include "opt_ddb.h" 57 #include "opt_printf.h" 58 59 #ifdef DDB 60 #include <ddb/ddb.h> 61 #endif 62 63 static char driver_name[] = "xc"; 64 65 struct xencons_priv; 66 67 typedef void xencons_early_init_t(struct xencons_priv *cons); 68 typedef int xencons_init_t(device_t dev, struct tty *tp, 69 driver_intr_t intr_handler); 70 typedef int xencons_read_t(struct xencons_priv *cons, char *buffer, 71 unsigned int size); 72 typedef int xencons_write_t(struct xencons_priv *cons, const char *buffer, 73 unsigned int size); 74 75 struct xencons_ops { 76 /* 77 * Called by the low-level driver during early boot. 78 * Only the minimal set up to get a console should be done here. 79 */ 80 xencons_early_init_t *early_init; 81 /* Prepare the console to be fully use */ 82 xencons_init_t *init; 83 /* Read/write helpers */ 84 xencons_read_t *read; 85 xencons_write_t *write; 86 }; 87 88 struct xencons_priv { 89 /* Mutex to protect the shared ring and the internal buffers */ 90 struct mtx mtx; 91 /* Interrupt handler used for notify the backend */ 92 xen_intr_handle_t intr_handle; 93 /* KDB internal state */ 94 #ifdef KDB 95 int altbrk; 96 #endif 97 /* Status of the tty */ 98 bool opened; 99 /* Callout used when the write buffer is full */ 100 struct callout callout; 101 102 /* Internal buffers must be used with mtx locked */ 103 #define WBUF_SIZE 4096 104 #define WBUF_MASK(_i) ((_i)&(WBUF_SIZE-1)) 105 char wbuf[WBUF_SIZE]; 106 unsigned int wc, wp; /* Consumer/producer wbuf */ 107 108 #define RBUF_SIZE 1024 109 #define RBUF_MASK(_i) ((_i)&(RBUF_SIZE-1)) 110 char rbuf[RBUF_SIZE]; 111 unsigned int rc, rp; /* Consumer/producer rbuf */ 112 113 /* Pointer to the console operations */ 114 const struct xencons_ops *ops; 115 116 /* 117 * Ring specific fields 118 * XXX: make an union? 119 */ 120 /* Event channel number for early notification (PV only) */ 121 uint32_t evtchn; 122 /* Console shared page */ 123 struct xencons_interface *intf; 124 }; 125 126 /* 127 * Data for the main console 128 * Necessary to support low-level console driver 129 */ 130 static struct xencons_priv main_cons; 131 132 #define XC_POLLTIME (hz/10) 133 134 /*----------------------------- Debug function ------------------------------*/ 135 struct putchar_arg { 136 char *buf; 137 size_t size; 138 size_t n_next; 139 }; 140 141 static void 142 putchar(int c, void *arg) 143 { 144 struct putchar_arg *pca; 145 146 pca = (struct putchar_arg *)arg; 147 148 if (pca->buf == NULL) { 149 /* 150 * We have no buffer, output directly to the 151 * console char by char. 152 */ 153 HYPERVISOR_console_write((char *)&c, 1); 154 } else { 155 pca->buf[pca->n_next++] = c; 156 if ((pca->size == pca->n_next) || (c = '\0')) { 157 /* Flush the buffer */ 158 HYPERVISOR_console_write(pca->buf, pca->n_next); 159 pca->n_next = 0; 160 } 161 } 162 } 163 164 void 165 xc_printf(const char *fmt, ...) 166 { 167 va_list ap; 168 struct putchar_arg pca; 169 #ifdef PRINTF_BUFR_SIZE 170 char buf[PRINTF_BUFR_SIZE]; 171 172 pca.buf = buf; 173 pca.size = sizeof(buf); 174 pca.n_next = 0; 175 #else 176 pca.buf = NULL; 177 pca.size = 0; 178 #endif 179 180 KASSERT((xen_domain()), ("call to xc_printf from non Xen guest")); 181 182 va_start(ap, fmt); 183 kvprintf(fmt, putchar, &pca, 10, ap); 184 va_end(ap); 185 186 #ifdef PRINTF_BUFR_SIZE 187 if (pca.n_next != 0) 188 HYPERVISOR_console_write(buf, pca.n_next); 189 #endif 190 } 191 192 /*---------------------- Helpers for the console lock -----------------------*/ 193 /* 194 * The lock is not used when the kernel is panicing as it will never recover 195 * and we want to output no matter what it costs. 196 */ 197 static inline void xencons_lock(struct xencons_priv *cons) 198 { 199 200 if (!KERNEL_PANICKED()) 201 mtx_lock_spin(&cons->mtx); 202 203 } 204 205 static inline void xencons_unlock(struct xencons_priv *cons) 206 { 207 208 if (!KERNEL_PANICKED()) 209 mtx_unlock_spin(&cons->mtx); 210 } 211 212 #define xencons_lock_assert(cons) mtx_assert(&(cons)->mtx, MA_OWNED) 213 214 /*------------------ Helpers for the hypervisor console ---------------------*/ 215 static void 216 xencons_early_init_hypervisor(struct xencons_priv *cons) 217 { 218 /* 219 * Nothing to setup for the low-level console when using 220 * the hypervisor console. 221 */ 222 } 223 224 static int 225 xencons_init_hypervisor(device_t dev, struct tty *tp, 226 driver_intr_t intr_handler) 227 { 228 struct xencons_priv *cons; 229 int err; 230 231 cons = tty_softc(tp); 232 233 err = xen_intr_bind_virq(dev, VIRQ_CONSOLE, 0, NULL, 234 intr_handler, tp, INTR_TYPE_TTY | INTR_MPSAFE, &cons->intr_handle); 235 if (err != 0) 236 device_printf(dev, "Can't register console interrupt\n"); 237 238 return (err); 239 } 240 241 static int 242 xencons_write_hypervisor(struct xencons_priv *cons, const char *buffer, 243 unsigned int size) 244 { 245 246 HYPERVISOR_console_io(CONSOLEIO_write, size, buffer); 247 248 return (size); 249 } 250 251 static int 252 xencons_read_hypervisor(struct xencons_priv *cons, char *buffer, 253 unsigned int size) 254 { 255 256 xencons_lock_assert(cons); 257 258 return (HYPERVISOR_console_io(CONSOLEIO_read, size, buffer)); 259 } 260 261 static const struct xencons_ops xencons_hypervisor_ops = { 262 .early_init = xencons_early_init_hypervisor, 263 .init = xencons_init_hypervisor, 264 .read = xencons_read_hypervisor, 265 .write = xencons_write_hypervisor, 266 }; 267 268 /*------------------ Helpers for the ring console ---------------------------*/ 269 static void 270 xencons_early_init_ring(struct xencons_priv *cons) 271 { 272 cons->intf = pmap_mapdev_attr(ptoa(xen_get_console_mfn()), PAGE_SIZE, 273 VM_MEMATTR_XEN); 274 cons->evtchn = xen_get_console_evtchn(); 275 } 276 277 static int 278 xencons_init_ring(device_t dev, struct tty *tp, driver_intr_t intr_handler) 279 { 280 struct xencons_priv *cons; 281 int err; 282 283 cons = tty_softc(tp); 284 285 if (cons->evtchn == 0) 286 return (ENODEV); 287 288 err = xen_intr_bind_local_port(dev, cons->evtchn, NULL, 289 intr_handler, tp, INTR_TYPE_TTY | INTR_MPSAFE, &cons->intr_handle); 290 if (err != 0) 291 return (err); 292 293 return (0); 294 } 295 296 static void 297 xencons_notify_ring(struct xencons_priv *cons) 298 { 299 /* 300 * The console may be used before the ring interrupt is properly 301 * initialized. 302 * If so, fallback to directly use the event channel hypercall. 303 */ 304 if (__predict_true(cons->intr_handle != NULL)) 305 xen_intr_signal(cons->intr_handle); 306 else { 307 struct evtchn_send send = { 308 .port = cons->evtchn 309 }; 310 311 HYPERVISOR_event_channel_op(EVTCHNOP_send, &send); 312 } 313 } 314 315 static int 316 xencons_write_ring(struct xencons_priv *cons, const char *buffer, 317 unsigned int size) 318 { 319 struct xencons_interface *intf; 320 XENCONS_RING_IDX wcons, wprod; 321 int sent; 322 323 intf = cons->intf; 324 325 xencons_lock_assert(cons); 326 327 wcons = intf->out_cons; 328 wprod = intf->out_prod; 329 330 mb(); 331 KASSERT((wprod - wcons) <= sizeof(intf->out), 332 ("console send ring inconsistent")); 333 334 for (sent = 0; sent < size; sent++, wprod++) { 335 if ((wprod - wcons) >= sizeof(intf->out)) 336 break; 337 intf->out[MASK_XENCONS_IDX(wprod, intf->out)] = buffer[sent]; 338 } 339 340 wmb(); 341 intf->out_prod = wprod; 342 343 xencons_notify_ring(cons); 344 345 return (sent); 346 } 347 348 static int 349 xencons_read_ring(struct xencons_priv *cons, char *buffer, unsigned int size) 350 { 351 struct xencons_interface *intf; 352 XENCONS_RING_IDX rcons, rprod; 353 unsigned int rsz; 354 355 intf = cons->intf; 356 357 xencons_lock_assert(cons); 358 359 rcons = intf->in_cons; 360 rprod = intf->in_prod; 361 rmb(); 362 363 for (rsz = 0; rsz < size; rsz++, rcons++) { 364 if (rprod == rcons) 365 break; 366 buffer[rsz] = intf->in[MASK_XENCONS_IDX(rcons, intf->in)]; 367 } 368 369 wmb(); 370 intf->in_cons = rcons; 371 372 /* No need to notify the backend if nothing has been read */ 373 if (rsz != 0) 374 xencons_notify_ring(cons); 375 376 return (rsz); 377 } 378 379 static const struct xencons_ops xencons_ring_ops = { 380 .early_init = xencons_early_init_ring, 381 .init = xencons_init_ring, 382 .read = xencons_read_ring, 383 .write = xencons_write_ring, 384 }; 385 386 /*------------------ Common implementation of the console -------------------*/ 387 388 /* 389 * Called by the low-level driver during early boot to initialize the 390 * main console driver. 391 * Only the minimal set up to get a console should be done here. 392 */ 393 static void 394 xencons_early_init(void) 395 { 396 397 mtx_init(&main_cons.mtx, "XCONS LOCK", NULL, MTX_SPIN); 398 399 if (xen_get_console_evtchn() == 0) 400 main_cons.ops = &xencons_hypervisor_ops; 401 else 402 main_cons.ops = &xencons_ring_ops; 403 404 main_cons.ops->early_init(&main_cons); 405 } 406 407 /* 408 * Receive character from the console and put them in the internal buffer 409 * XXX: Handle overflow of the internal buffer 410 */ 411 static void 412 xencons_rx(struct xencons_priv *cons) 413 { 414 char buf[16]; 415 int sz; 416 417 xencons_lock(cons); 418 while ((sz = cons->ops->read(cons, buf, sizeof(buf))) > 0) { 419 int i; 420 421 for (i = 0; i < sz; i++) 422 cons->rbuf[RBUF_MASK(cons->rp++)] = buf[i]; 423 } 424 xencons_unlock(cons); 425 } 426 427 /* Return true if the write buffer is full */ 428 static bool 429 xencons_tx_full(struct xencons_priv *cons) 430 { 431 unsigned int used; 432 433 xencons_lock(cons); 434 used = cons->wp - cons->wc; 435 xencons_unlock(cons); 436 437 return (used >= WBUF_SIZE); 438 } 439 440 static void 441 xencons_tx_flush(struct xencons_priv *cons, int force) 442 { 443 int sz; 444 445 xencons_lock(cons); 446 while (cons->wc != cons->wp) { 447 int sent; 448 sz = cons->wp - cons->wc; 449 if (sz > (WBUF_SIZE - WBUF_MASK(cons->wc))) 450 sz = WBUF_SIZE - WBUF_MASK(cons->wc); 451 sent = cons->ops->write(cons, &cons->wbuf[WBUF_MASK(cons->wc)], 452 sz); 453 454 /* 455 * The other end may not have been initialized. Ignore 456 * the force. 457 */ 458 if (__predict_false(sent < 0)) 459 break; 460 461 /* 462 * If force is set, spin until the console data is 463 * flushed through the domain controller. 464 */ 465 if (sent == 0 && __predict_true(!force)) 466 break; 467 468 cons->wc += sent; 469 } 470 xencons_unlock(cons); 471 } 472 473 static bool 474 xencons_putc(struct xencons_priv *cons, int c, bool force_flush) 475 { 476 477 xencons_lock(cons); 478 if ((cons->wp - cons->wc) < WBUF_SIZE) 479 cons->wbuf[WBUF_MASK(cons->wp++)] = c; 480 xencons_unlock(cons); 481 482 xencons_tx_flush(cons, force_flush); 483 484 return (xencons_tx_full(cons)); 485 } 486 487 static int 488 xencons_getc(struct xencons_priv *cons) 489 { 490 int ret; 491 492 xencons_lock(cons); 493 if (cons->rp != cons->rc) { 494 /* We need to return only one char */ 495 ret = (int)cons->rbuf[RBUF_MASK(cons->rc)]; 496 cons->rc++; 497 } else { 498 ret = -1; 499 } 500 501 xencons_unlock(cons); 502 503 return (ret); 504 } 505 506 static bool 507 xencons_tx(struct tty *tp) 508 { 509 bool cons_full; 510 char c; 511 struct xencons_priv *cons; 512 513 cons = tty_softc(tp); 514 515 tty_assert_locked(tp); 516 517 /* 518 * Don't transmit any character if the buffer is full. Otherwise, 519 * characters may be lost 520 */ 521 if (xencons_tx_full(cons)) 522 return (false); 523 524 cons_full = false; 525 while (!cons_full && ttydisc_getc(tp, &c, 1) == 1) 526 cons_full = xencons_putc(cons, c, false); 527 528 return (!cons_full); 529 } 530 531 static void 532 xencons_intr(void *arg) 533 { 534 struct tty *tp; 535 struct xencons_priv *cons; 536 int ret; 537 538 tp = arg; 539 cons = tty_softc(tp); 540 541 /* 542 * The input will be used by the low-level console when KDB is active 543 */ 544 if (kdb_active) 545 return; 546 547 /* 548 * It's not necessary to retrieve input when the tty is not opened 549 */ 550 if (!cons->opened) 551 return; 552 553 xencons_rx(cons); 554 555 tty_lock(tp); 556 while ((ret = xencons_getc(cons)) != -1) { 557 #ifdef KDB 558 kdb_alt_break(ret, &cons->altbrk); 559 #endif 560 ttydisc_rint(tp, ret, 0); 561 } 562 ttydisc_rint_done(tp); 563 tty_unlock(tp); 564 565 /* Try to flush remaining characters if necessary */ 566 xencons_tx_flush(cons, 0); 567 } 568 569 /* 570 * Helpers to call while shutting down: 571 * - Force flush all output 572 */ 573 static void 574 xencons_shutdown(void *arg, int howto) 575 { 576 struct tty *tp; 577 578 tp = arg; 579 580 xencons_tx_flush(tty_softc(tp), 1); 581 } 582 583 /*---------------------- Low-level console driver ---------------------------*/ 584 static void 585 xencons_cnprobe(struct consdev *cp) 586 { 587 588 if (!xen_domain()) 589 return; 590 591 cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL; 592 sprintf(cp->cn_name, "%s0", driver_name); 593 } 594 595 static void 596 xencons_cninit(struct consdev *cp) 597 { 598 599 xencons_early_init(); 600 } 601 602 static void 603 xencons_cnterm(struct consdev *cp) 604 { 605 } 606 607 static void 608 xencons_cngrab(struct consdev *cp) 609 { 610 } 611 612 static void 613 xencons_cnungrab(struct consdev *cp) 614 { 615 } 616 617 static int 618 xencons_cngetc(struct consdev *dev) 619 { 620 621 xencons_rx(&main_cons); 622 623 return (xencons_getc(&main_cons)); 624 } 625 626 static void 627 xencons_cnputc(struct consdev *dev, int c) 628 { 629 /* 630 * The low-level console is used by KDB and panic. We have to ensure 631 * that any character sent will be seen by the backend. 632 */ 633 xencons_putc(&main_cons, c, true); 634 } 635 636 CONSOLE_DRIVER(xencons); 637 638 /*----------------------------- TTY driver ---------------------------------*/ 639 640 static int 641 xencons_tty_open(struct tty *tp) 642 { 643 struct xencons_priv *cons; 644 645 cons = tty_softc(tp); 646 647 cons->opened = true; 648 649 return (0); 650 } 651 652 static void 653 xencons_tty_close(struct tty *tp) 654 { 655 struct xencons_priv *cons; 656 657 cons = tty_softc(tp); 658 659 cons->opened = false; 660 } 661 662 static void 663 xencons_timeout(void *v) 664 { 665 struct tty *tp; 666 struct xencons_priv *cons; 667 668 tp = v; 669 cons = tty_softc(tp); 670 671 if (!xencons_tx(tp)) 672 callout_reset(&cons->callout, XC_POLLTIME, 673 xencons_timeout, tp); 674 } 675 676 static void 677 xencons_tty_outwakeup(struct tty *tp) 678 { 679 struct xencons_priv *cons; 680 681 cons = tty_softc(tp); 682 683 callout_stop(&cons->callout); 684 685 if (!xencons_tx(tp)) 686 callout_reset(&cons->callout, XC_POLLTIME, 687 xencons_timeout, tp); 688 } 689 690 static struct ttydevsw xencons_ttydevsw = { 691 .tsw_flags = TF_NOPREFIX, 692 .tsw_open = xencons_tty_open, 693 .tsw_close = xencons_tty_close, 694 .tsw_outwakeup = xencons_tty_outwakeup, 695 }; 696 697 /*------------------------ Main console driver ------------------------------*/ 698 static void 699 xencons_identify(driver_t *driver, device_t parent) 700 { 701 device_t child __unused; 702 703 if (main_cons.ops == NULL) 704 return; 705 706 child = BUS_ADD_CHILD(parent, 0, driver_name, 0); 707 } 708 709 static int 710 xencons_probe(device_t dev) 711 { 712 713 device_set_desc(dev, "Xen Console"); 714 return (BUS_PROBE_NOWILDCARD); 715 } 716 717 static int 718 xencons_attach(device_t dev) 719 { 720 struct tty *tp; 721 /* 722 * The main console is already allocated statically in order to 723 * support low-level console 724 */ 725 struct xencons_priv *cons; 726 int err; 727 728 cons = &main_cons; 729 730 tp = tty_alloc(&xencons_ttydevsw, cons); 731 tty_makedev(tp, NULL, "%s%r", driver_name, 0); 732 device_set_softc(dev, tp); 733 734 callout_init_mtx(&cons->callout, tty_getlock(tp), 0); 735 736 err = cons->ops->init(dev, tp, xencons_intr); 737 if (err != 0) { 738 device_printf(dev, "Unable to initialize the console (%d)\n", 739 err); 740 return (err); 741 } 742 743 /* register handler to flush console on shutdown */ 744 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, xencons_shutdown, 745 tp, SHUTDOWN_PRI_DEFAULT)) == NULL) 746 device_printf(dev, "shutdown event registration failed!\n"); 747 748 return (0); 749 } 750 751 static int 752 xencons_resume(device_t dev) 753 { 754 struct xencons_priv *cons; 755 struct tty *tp; 756 int err; 757 758 tp = device_get_softc(dev); 759 cons = tty_softc(tp); 760 xen_intr_unbind(&cons->intr_handle); 761 762 err = cons->ops->init(dev, tp, xencons_intr); 763 if (err != 0) { 764 device_printf(dev, "Unable to resume the console (%d)\n", err); 765 return (err); 766 } 767 768 return (0); 769 } 770 771 static device_method_t xencons_methods[] = { 772 DEVMETHOD(device_identify, xencons_identify), 773 DEVMETHOD(device_probe, xencons_probe), 774 DEVMETHOD(device_attach, xencons_attach), 775 DEVMETHOD(device_resume, xencons_resume), 776 777 DEVMETHOD_END 778 }; 779 780 static driver_t xencons_driver = { 781 driver_name, 782 xencons_methods, 783 0, 784 }; 785 786 DRIVER_MODULE(xc, xenpv, xencons_driver, 0, 0); 787