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