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