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 void __weak_symbol 142 xen_emergency_print(const char *str, size_t size) 143 { 144 KASSERT((xen_domain()), ("call to xc_printf from non Xen guest")); 145 HYPERVISOR_console_write(str, size); 146 } 147 148 static void 149 putchar(int c, void *arg) 150 { 151 struct putchar_arg *pca; 152 153 pca = (struct putchar_arg *)arg; 154 155 if (pca->buf == NULL) { 156 /* 157 * We have no buffer, output directly to the 158 * console char by char. 159 */ 160 xen_emergency_print((char *)&c, 1); 161 } else { 162 pca->buf[pca->n_next++] = c; 163 if ((pca->size == pca->n_next) || (c = '\0')) { 164 /* Flush the buffer */ 165 xen_emergency_print(pca->buf, pca->n_next); 166 pca->n_next = 0; 167 } 168 } 169 } 170 171 void 172 xc_printf(const char *fmt, ...) 173 { 174 va_list ap; 175 struct putchar_arg pca; 176 #ifdef PRINTF_BUFR_SIZE 177 char buf[PRINTF_BUFR_SIZE]; 178 179 pca.buf = buf; 180 pca.size = sizeof(buf); 181 pca.n_next = 0; 182 #else 183 pca.buf = NULL; 184 pca.size = 0; 185 #endif 186 187 va_start(ap, fmt); 188 kvprintf(fmt, putchar, &pca, 10, ap); 189 va_end(ap); 190 191 #ifdef PRINTF_BUFR_SIZE 192 if (pca.n_next != 0) 193 xen_emergency_print(buf, pca.n_next); 194 #endif 195 } 196 197 /*---------------------- Helpers for the console lock -----------------------*/ 198 /* 199 * The lock is not used when the kernel is panicing as it will never recover 200 * and we want to output no matter what it costs. 201 */ 202 static inline void xencons_lock(struct xencons_priv *cons) 203 { 204 205 if (!KERNEL_PANICKED()) 206 mtx_lock_spin(&cons->mtx); 207 208 } 209 210 static inline void xencons_unlock(struct xencons_priv *cons) 211 { 212 213 if (!KERNEL_PANICKED()) 214 mtx_unlock_spin(&cons->mtx); 215 } 216 217 #define xencons_lock_assert(cons) mtx_assert(&(cons)->mtx, MA_OWNED) 218 219 /*------------------ Helpers for the hypervisor console ---------------------*/ 220 static void 221 xencons_early_init_hypervisor(struct xencons_priv *cons) 222 { 223 /* 224 * Nothing to setup for the low-level console when using 225 * the hypervisor console. 226 */ 227 } 228 229 static int 230 xencons_init_hypervisor(device_t dev, struct tty *tp, 231 driver_intr_t intr_handler) 232 { 233 struct xencons_priv *cons; 234 int err; 235 236 cons = tty_softc(tp); 237 238 err = xen_intr_bind_virq(dev, VIRQ_CONSOLE, 0, NULL, 239 intr_handler, tp, INTR_TYPE_TTY | INTR_MPSAFE, &cons->intr_handle); 240 if (err != 0) 241 device_printf(dev, "Can't register console interrupt\n"); 242 243 return (err); 244 } 245 246 static int 247 xencons_write_hypervisor(struct xencons_priv *cons, const char *buffer, 248 unsigned int size) 249 { 250 251 HYPERVISOR_console_io(CONSOLEIO_write, size, buffer); 252 253 return (size); 254 } 255 256 static int 257 xencons_read_hypervisor(struct xencons_priv *cons, char *buffer, 258 unsigned int size) 259 { 260 261 xencons_lock_assert(cons); 262 263 return (HYPERVISOR_console_io(CONSOLEIO_read, size, buffer)); 264 } 265 266 static const struct xencons_ops xencons_hypervisor_ops = { 267 .early_init = xencons_early_init_hypervisor, 268 .init = xencons_init_hypervisor, 269 .read = xencons_read_hypervisor, 270 .write = xencons_write_hypervisor, 271 }; 272 273 /*------------------ Helpers for the ring console ---------------------------*/ 274 static void 275 xencons_early_init_ring(struct xencons_priv *cons) 276 { 277 cons->intf = pmap_mapdev_attr(ptoa(xen_get_console_mfn()), PAGE_SIZE, 278 VM_MEMATTR_XEN); 279 cons->evtchn = xen_get_console_evtchn(); 280 } 281 282 static int 283 xencons_init_ring(device_t dev, struct tty *tp, driver_intr_t intr_handler) 284 { 285 struct xencons_priv *cons; 286 int err; 287 288 cons = tty_softc(tp); 289 290 if (cons->evtchn == 0) 291 return (ENODEV); 292 293 err = xen_intr_bind_local_port(dev, cons->evtchn, NULL, 294 intr_handler, tp, INTR_TYPE_TTY | INTR_MPSAFE, &cons->intr_handle); 295 if (err != 0) 296 return (err); 297 298 return (0); 299 } 300 301 static void 302 xencons_notify_ring(struct xencons_priv *cons) 303 { 304 /* 305 * The console may be used before the ring interrupt is properly 306 * initialized. 307 * If so, fallback to directly use the event channel hypercall. 308 */ 309 if (__predict_true(cons->intr_handle != NULL)) 310 xen_intr_signal(cons->intr_handle); 311 else { 312 struct evtchn_send send = { 313 .port = cons->evtchn 314 }; 315 316 HYPERVISOR_event_channel_op(EVTCHNOP_send, &send); 317 } 318 } 319 320 static int 321 xencons_write_ring(struct xencons_priv *cons, const char *buffer, 322 unsigned int size) 323 { 324 struct xencons_interface *intf; 325 XENCONS_RING_IDX wcons, wprod; 326 int sent; 327 328 intf = cons->intf; 329 330 xencons_lock_assert(cons); 331 332 wcons = intf->out_cons; 333 wprod = intf->out_prod; 334 335 mb(); 336 KASSERT((wprod - wcons) <= sizeof(intf->out), 337 ("console send ring inconsistent")); 338 339 for (sent = 0; sent < size; sent++, wprod++) { 340 if ((wprod - wcons) >= sizeof(intf->out)) 341 break; 342 intf->out[MASK_XENCONS_IDX(wprod, intf->out)] = buffer[sent]; 343 } 344 345 wmb(); 346 intf->out_prod = wprod; 347 348 xencons_notify_ring(cons); 349 350 return (sent); 351 } 352 353 static int 354 xencons_read_ring(struct xencons_priv *cons, char *buffer, unsigned int size) 355 { 356 struct xencons_interface *intf; 357 XENCONS_RING_IDX rcons, rprod; 358 unsigned int rsz; 359 360 intf = cons->intf; 361 362 xencons_lock_assert(cons); 363 364 rcons = intf->in_cons; 365 rprod = intf->in_prod; 366 rmb(); 367 368 for (rsz = 0; rsz < size; rsz++, rcons++) { 369 if (rprod == rcons) 370 break; 371 buffer[rsz] = intf->in[MASK_XENCONS_IDX(rcons, intf->in)]; 372 } 373 374 wmb(); 375 intf->in_cons = rcons; 376 377 /* No need to notify the backend if nothing has been read */ 378 if (rsz != 0) 379 xencons_notify_ring(cons); 380 381 return (rsz); 382 } 383 384 static const struct xencons_ops xencons_ring_ops = { 385 .early_init = xencons_early_init_ring, 386 .init = xencons_init_ring, 387 .read = xencons_read_ring, 388 .write = xencons_write_ring, 389 }; 390 391 /*------------------ Common implementation of the console -------------------*/ 392 393 /* 394 * Called by the low-level driver during early boot to initialize the 395 * main console driver. 396 * Only the minimal set up to get a console should be done here. 397 */ 398 static void 399 xencons_early_init(void) 400 { 401 402 mtx_init(&main_cons.mtx, "XCONS LOCK", NULL, MTX_SPIN); 403 404 if (xen_get_console_evtchn() == 0) 405 main_cons.ops = &xencons_hypervisor_ops; 406 else 407 main_cons.ops = &xencons_ring_ops; 408 409 main_cons.ops->early_init(&main_cons); 410 } 411 412 /* 413 * Receive character from the console and put them in the internal buffer 414 * XXX: Handle overflow of the internal buffer 415 */ 416 static void 417 xencons_rx(struct xencons_priv *cons) 418 { 419 char buf[16]; 420 int sz; 421 422 xencons_lock(cons); 423 while ((sz = cons->ops->read(cons, buf, sizeof(buf))) > 0) { 424 int i; 425 426 for (i = 0; i < sz; i++) 427 cons->rbuf[RBUF_MASK(cons->rp++)] = buf[i]; 428 } 429 xencons_unlock(cons); 430 } 431 432 /* Return true if the write buffer is full */ 433 static bool 434 xencons_tx_full(struct xencons_priv *cons) 435 { 436 unsigned int used; 437 438 xencons_lock(cons); 439 used = cons->wp - cons->wc; 440 xencons_unlock(cons); 441 442 return (used >= WBUF_SIZE); 443 } 444 445 static void 446 xencons_tx_flush(struct xencons_priv *cons, int force) 447 { 448 int sz; 449 450 xencons_lock(cons); 451 while (cons->wc != cons->wp) { 452 int sent; 453 sz = cons->wp - cons->wc; 454 if (sz > (WBUF_SIZE - WBUF_MASK(cons->wc))) 455 sz = WBUF_SIZE - WBUF_MASK(cons->wc); 456 sent = cons->ops->write(cons, &cons->wbuf[WBUF_MASK(cons->wc)], 457 sz); 458 459 /* 460 * The other end may not have been initialized. Ignore 461 * the force. 462 */ 463 if (__predict_false(sent < 0)) 464 break; 465 466 /* 467 * If force is set, spin until the console data is 468 * flushed through the domain controller. 469 */ 470 if (sent == 0 && __predict_true(!force)) 471 break; 472 473 cons->wc += sent; 474 } 475 xencons_unlock(cons); 476 } 477 478 static bool 479 xencons_putc(struct xencons_priv *cons, int c, bool force_flush) 480 { 481 482 xencons_lock(cons); 483 if ((cons->wp - cons->wc) < WBUF_SIZE) 484 cons->wbuf[WBUF_MASK(cons->wp++)] = c; 485 xencons_unlock(cons); 486 487 xencons_tx_flush(cons, force_flush); 488 489 return (xencons_tx_full(cons)); 490 } 491 492 static int 493 xencons_getc(struct xencons_priv *cons) 494 { 495 int ret; 496 497 xencons_lock(cons); 498 if (cons->rp != cons->rc) { 499 /* We need to return only one char */ 500 ret = (int)cons->rbuf[RBUF_MASK(cons->rc)]; 501 cons->rc++; 502 } else { 503 ret = -1; 504 } 505 506 xencons_unlock(cons); 507 508 return (ret); 509 } 510 511 static bool 512 xencons_tx(struct tty *tp) 513 { 514 bool cons_full; 515 char c; 516 struct xencons_priv *cons; 517 518 cons = tty_softc(tp); 519 520 tty_assert_locked(tp); 521 522 /* 523 * Don't transmit any character if the buffer is full. Otherwise, 524 * characters may be lost 525 */ 526 if (xencons_tx_full(cons)) 527 return (false); 528 529 cons_full = false; 530 while (!cons_full && ttydisc_getc(tp, &c, 1) == 1) 531 cons_full = xencons_putc(cons, c, false); 532 533 return (!cons_full); 534 } 535 536 static void 537 xencons_intr(void *arg) 538 { 539 struct tty *tp; 540 struct xencons_priv *cons; 541 int ret; 542 543 tp = arg; 544 cons = tty_softc(tp); 545 546 /* 547 * The input will be used by the low-level console when KDB is active 548 */ 549 if (kdb_active) 550 return; 551 552 /* 553 * It's not necessary to retrieve input when the tty is not opened 554 */ 555 if (!cons->opened) 556 return; 557 558 xencons_rx(cons); 559 560 tty_lock(tp); 561 while ((ret = xencons_getc(cons)) != -1) { 562 #ifdef KDB 563 kdb_alt_break(ret, &cons->altbrk); 564 #endif 565 ttydisc_rint(tp, ret, 0); 566 } 567 ttydisc_rint_done(tp); 568 tty_unlock(tp); 569 570 /* Try to flush remaining characters if necessary */ 571 xencons_tx_flush(cons, 0); 572 } 573 574 /* 575 * Helpers to call while shutting down: 576 * - Force flush all output 577 */ 578 static void 579 xencons_shutdown(void *arg, int howto) 580 { 581 struct tty *tp; 582 583 tp = arg; 584 585 xencons_tx_flush(tty_softc(tp), 1); 586 } 587 588 /*---------------------- Low-level console driver ---------------------------*/ 589 static void 590 xencons_cnprobe(struct consdev *cp) 591 { 592 593 if (!xen_domain()) 594 return; 595 596 cp->cn_pri = (boothowto & RB_SERIAL) ? CN_REMOTE : CN_NORMAL; 597 sprintf(cp->cn_name, "%s0", driver_name); 598 } 599 600 static void 601 xencons_cninit(struct consdev *cp) 602 { 603 604 xencons_early_init(); 605 } 606 607 static void 608 xencons_cnterm(struct consdev *cp) 609 { 610 } 611 612 static void 613 xencons_cngrab(struct consdev *cp) 614 { 615 } 616 617 static void 618 xencons_cnungrab(struct consdev *cp) 619 { 620 } 621 622 static int 623 xencons_cngetc(struct consdev *dev) 624 { 625 626 xencons_rx(&main_cons); 627 628 return (xencons_getc(&main_cons)); 629 } 630 631 static void 632 xencons_cnputc(struct consdev *dev, int c) 633 { 634 /* 635 * The low-level console is used by KDB and panic. We have to ensure 636 * that any character sent will be seen by the backend. 637 */ 638 xencons_putc(&main_cons, c, true); 639 } 640 641 CONSOLE_DRIVER(xencons); 642 643 /*----------------------------- TTY driver ---------------------------------*/ 644 645 static int 646 xencons_tty_open(struct tty *tp) 647 { 648 struct xencons_priv *cons; 649 650 cons = tty_softc(tp); 651 652 cons->opened = true; 653 654 return (0); 655 } 656 657 static void 658 xencons_tty_close(struct tty *tp) 659 { 660 struct xencons_priv *cons; 661 662 cons = tty_softc(tp); 663 664 cons->opened = false; 665 } 666 667 static void 668 xencons_timeout(void *v) 669 { 670 struct tty *tp; 671 struct xencons_priv *cons; 672 673 tp = v; 674 cons = tty_softc(tp); 675 676 if (!xencons_tx(tp)) 677 callout_reset(&cons->callout, XC_POLLTIME, 678 xencons_timeout, tp); 679 } 680 681 static void 682 xencons_tty_outwakeup(struct tty *tp) 683 { 684 struct xencons_priv *cons; 685 686 cons = tty_softc(tp); 687 688 callout_stop(&cons->callout); 689 690 if (!xencons_tx(tp)) 691 callout_reset(&cons->callout, XC_POLLTIME, 692 xencons_timeout, tp); 693 } 694 695 static struct ttydevsw xencons_ttydevsw = { 696 .tsw_flags = TF_NOPREFIX, 697 .tsw_open = xencons_tty_open, 698 .tsw_close = xencons_tty_close, 699 .tsw_outwakeup = xencons_tty_outwakeup, 700 }; 701 702 /*------------------------ Main console driver ------------------------------*/ 703 static void 704 xencons_identify(driver_t *driver, device_t parent) 705 { 706 device_t child __unused; 707 708 if (main_cons.ops == NULL) 709 return; 710 711 child = BUS_ADD_CHILD(parent, 0, driver_name, 0); 712 } 713 714 static int 715 xencons_probe(device_t dev) 716 { 717 718 device_set_desc(dev, "Xen Console"); 719 return (BUS_PROBE_NOWILDCARD); 720 } 721 722 static int 723 xencons_attach(device_t dev) 724 { 725 struct tty *tp; 726 /* 727 * The main console is already allocated statically in order to 728 * support low-level console 729 */ 730 struct xencons_priv *cons; 731 int err; 732 733 cons = &main_cons; 734 735 tp = tty_alloc(&xencons_ttydevsw, cons); 736 tty_makedev(tp, NULL, "%s%r", driver_name, 0); 737 device_set_softc(dev, tp); 738 739 callout_init_mtx(&cons->callout, tty_getlock(tp), 0); 740 741 err = cons->ops->init(dev, tp, xencons_intr); 742 if (err != 0) { 743 device_printf(dev, "Unable to initialize the console (%d)\n", 744 err); 745 return (err); 746 } 747 748 /* register handler to flush console on shutdown */ 749 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, xencons_shutdown, 750 tp, SHUTDOWN_PRI_DEFAULT)) == NULL) 751 device_printf(dev, "shutdown event registration failed!\n"); 752 753 return (0); 754 } 755 756 static int 757 xencons_resume(device_t dev) 758 { 759 struct xencons_priv *cons; 760 struct tty *tp; 761 int err; 762 763 tp = device_get_softc(dev); 764 cons = tty_softc(tp); 765 xen_intr_unbind(&cons->intr_handle); 766 767 err = cons->ops->init(dev, tp, xencons_intr); 768 if (err != 0) { 769 device_printf(dev, "Unable to resume the console (%d)\n", err); 770 return (err); 771 } 772 773 return (0); 774 } 775 776 static device_method_t xencons_methods[] = { 777 DEVMETHOD(device_identify, xencons_identify), 778 DEVMETHOD(device_probe, xencons_probe), 779 DEVMETHOD(device_attach, xencons_attach), 780 DEVMETHOD(device_resume, xencons_resume), 781 782 DEVMETHOD_END 783 }; 784 785 static driver_t xencons_driver = { 786 driver_name, 787 xencons_methods, 788 0, 789 }; 790 791 DRIVER_MODULE(xc, xenpv, xencons_driver, 0, 0); 792