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