1 /* 2 * xen console driver interface to hvc_console.c 3 * 4 * (c) 2007 Gerd Hoffmann <kraxel@suse.de> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21 #include <linux/console.h> 22 #include <linux/delay.h> 23 #include <linux/err.h> 24 #include <linux/irq.h> 25 #include <linux/init.h> 26 #include <linux/types.h> 27 #include <linux/list.h> 28 #include <linux/serial_core.h> 29 30 #include <asm/io.h> 31 #include <asm/xen/hypervisor.h> 32 33 #include <xen/xen.h> 34 #include <xen/interface/xen.h> 35 #include <xen/hvm.h> 36 #include <xen/grant_table.h> 37 #include <xen/page.h> 38 #include <xen/events.h> 39 #include <xen/interface/io/console.h> 40 #include <xen/interface/sched.h> 41 #include <xen/hvc-console.h> 42 #include <xen/xenbus.h> 43 44 #include "hvc_console.h" 45 46 #define HVC_COOKIE 0x58656e /* "Xen" in hex */ 47 48 struct xencons_info { 49 struct list_head list; 50 struct xenbus_device *xbdev; 51 struct xencons_interface *intf; 52 unsigned int evtchn; 53 struct hvc_struct *hvc; 54 int irq; 55 int vtermno; 56 grant_ref_t gntref; 57 }; 58 59 static LIST_HEAD(xenconsoles); 60 static DEFINE_SPINLOCK(xencons_lock); 61 62 /* ------------------------------------------------------------------ */ 63 64 static struct xencons_info *vtermno_to_xencons(int vtermno) 65 { 66 struct xencons_info *entry, *n, *ret = NULL; 67 68 if (list_empty(&xenconsoles)) 69 return NULL; 70 71 list_for_each_entry_safe(entry, n, &xenconsoles, list) { 72 if (entry->vtermno == vtermno) { 73 ret = entry; 74 break; 75 } 76 } 77 78 return ret; 79 } 80 81 static inline int xenbus_devid_to_vtermno(int devid) 82 { 83 return devid + HVC_COOKIE; 84 } 85 86 static inline void notify_daemon(struct xencons_info *cons) 87 { 88 /* Use evtchn: this is called early, before irq is set up. */ 89 notify_remote_via_evtchn(cons->evtchn); 90 } 91 92 static int __write_console(struct xencons_info *xencons, 93 const char *data, int len) 94 { 95 XENCONS_RING_IDX cons, prod; 96 struct xencons_interface *intf = xencons->intf; 97 int sent = 0; 98 99 cons = intf->out_cons; 100 prod = intf->out_prod; 101 mb(); /* update queue values before going on */ 102 BUG_ON((prod - cons) > sizeof(intf->out)); 103 104 while ((sent < len) && ((prod - cons) < sizeof(intf->out))) 105 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; 106 107 wmb(); /* write ring before updating pointer */ 108 intf->out_prod = prod; 109 110 if (sent) 111 notify_daemon(xencons); 112 return sent; 113 } 114 115 static int domU_write_console(uint32_t vtermno, const char *data, int len) 116 { 117 int ret = len; 118 struct xencons_info *cons = vtermno_to_xencons(vtermno); 119 if (cons == NULL) 120 return -EINVAL; 121 122 /* 123 * Make sure the whole buffer is emitted, polling if 124 * necessary. We don't ever want to rely on the hvc daemon 125 * because the most interesting console output is when the 126 * kernel is crippled. 127 */ 128 while (len) { 129 int sent = __write_console(cons, data, len); 130 131 data += sent; 132 len -= sent; 133 134 if (unlikely(len)) 135 HYPERVISOR_sched_op(SCHEDOP_yield, NULL); 136 } 137 138 return ret; 139 } 140 141 static int domU_read_console(uint32_t vtermno, char *buf, int len) 142 { 143 struct xencons_interface *intf; 144 XENCONS_RING_IDX cons, prod; 145 int recv = 0; 146 struct xencons_info *xencons = vtermno_to_xencons(vtermno); 147 if (xencons == NULL) 148 return -EINVAL; 149 intf = xencons->intf; 150 151 cons = intf->in_cons; 152 prod = intf->in_prod; 153 mb(); /* get pointers before reading ring */ 154 BUG_ON((prod - cons) > sizeof(intf->in)); 155 156 while (cons != prod && recv < len) 157 buf[recv++] = intf->in[MASK_XENCONS_IDX(cons++, intf->in)]; 158 159 mb(); /* read ring before consuming */ 160 intf->in_cons = cons; 161 162 notify_daemon(xencons); 163 return recv; 164 } 165 166 static const struct hv_ops domU_hvc_ops = { 167 .get_chars = domU_read_console, 168 .put_chars = domU_write_console, 169 .notifier_add = notifier_add_irq, 170 .notifier_del = notifier_del_irq, 171 .notifier_hangup = notifier_hangup_irq, 172 }; 173 174 static int dom0_read_console(uint32_t vtermno, char *buf, int len) 175 { 176 return HYPERVISOR_console_io(CONSOLEIO_read, len, buf); 177 } 178 179 /* 180 * Either for a dom0 to write to the system console, or a domU with a 181 * debug version of Xen 182 */ 183 static int dom0_write_console(uint32_t vtermno, const char *str, int len) 184 { 185 int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); 186 if (rc < 0) 187 return rc; 188 189 return len; 190 } 191 192 static const struct hv_ops dom0_hvc_ops = { 193 .get_chars = dom0_read_console, 194 .put_chars = dom0_write_console, 195 .notifier_add = notifier_add_irq, 196 .notifier_del = notifier_del_irq, 197 .notifier_hangup = notifier_hangup_irq, 198 }; 199 200 static int xen_hvm_console_init(void) 201 { 202 int r; 203 uint64_t v = 0; 204 unsigned long gfn; 205 struct xencons_info *info; 206 207 if (!xen_hvm_domain()) 208 return -ENODEV; 209 210 info = vtermno_to_xencons(HVC_COOKIE); 211 if (!info) { 212 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); 213 if (!info) 214 return -ENOMEM; 215 } else if (info->intf != NULL) { 216 /* already configured */ 217 return 0; 218 } 219 /* 220 * If the toolstack (or the hypervisor) hasn't set these values, the 221 * default value is 0. Even though gfn = 0 and evtchn = 0 are 222 * theoretically correct values, in practice they never are and they 223 * mean that a legacy toolstack hasn't initialized the pv console correctly. 224 */ 225 r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); 226 if (r < 0 || v == 0) 227 goto err; 228 info->evtchn = v; 229 v = 0; 230 r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); 231 if (r < 0 || v == 0) 232 goto err; 233 gfn = v; 234 info->intf = xen_remap(gfn << XEN_PAGE_SHIFT, XEN_PAGE_SIZE); 235 if (info->intf == NULL) 236 goto err; 237 info->vtermno = HVC_COOKIE; 238 239 spin_lock(&xencons_lock); 240 list_add_tail(&info->list, &xenconsoles); 241 spin_unlock(&xencons_lock); 242 243 return 0; 244 err: 245 kfree(info); 246 return -ENODEV; 247 } 248 249 static int xencons_info_pv_init(struct xencons_info *info, int vtermno) 250 { 251 info->evtchn = xen_start_info->console.domU.evtchn; 252 /* GFN == MFN for PV guest */ 253 info->intf = gfn_to_virt(xen_start_info->console.domU.mfn); 254 info->vtermno = vtermno; 255 256 list_add_tail(&info->list, &xenconsoles); 257 258 return 0; 259 } 260 261 static int xen_pv_console_init(void) 262 { 263 struct xencons_info *info; 264 265 if (!xen_pv_domain()) 266 return -ENODEV; 267 268 if (!xen_start_info->console.domU.evtchn) 269 return -ENODEV; 270 271 info = vtermno_to_xencons(HVC_COOKIE); 272 if (!info) { 273 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); 274 if (!info) 275 return -ENOMEM; 276 } else if (info->intf != NULL) { 277 /* already configured */ 278 return 0; 279 } 280 spin_lock(&xencons_lock); 281 xencons_info_pv_init(info, HVC_COOKIE); 282 spin_unlock(&xencons_lock); 283 284 return 0; 285 } 286 287 static int xen_initial_domain_console_init(void) 288 { 289 struct xencons_info *info; 290 291 if (!xen_initial_domain()) 292 return -ENODEV; 293 294 info = vtermno_to_xencons(HVC_COOKIE); 295 if (!info) { 296 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); 297 if (!info) 298 return -ENOMEM; 299 } 300 301 info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0, false); 302 info->vtermno = HVC_COOKIE; 303 304 spin_lock(&xencons_lock); 305 list_add_tail(&info->list, &xenconsoles); 306 spin_unlock(&xencons_lock); 307 308 return 0; 309 } 310 311 static void xen_console_update_evtchn(struct xencons_info *info) 312 { 313 if (xen_hvm_domain()) { 314 uint64_t v = 0; 315 int err; 316 317 err = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); 318 if (!err && v) 319 info->evtchn = v; 320 } else 321 info->evtchn = xen_start_info->console.domU.evtchn; 322 } 323 324 void xen_console_resume(void) 325 { 326 struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); 327 if (info != NULL && info->irq) { 328 if (!xen_initial_domain()) 329 xen_console_update_evtchn(info); 330 rebind_evtchn_irq(info->evtchn, info->irq); 331 } 332 } 333 334 #ifdef CONFIG_HVC_XEN_FRONTEND 335 static void xencons_disconnect_backend(struct xencons_info *info) 336 { 337 if (info->irq > 0) 338 unbind_from_irqhandler(info->irq, NULL); 339 info->irq = 0; 340 if (info->evtchn > 0) 341 xenbus_free_evtchn(info->xbdev, info->evtchn); 342 info->evtchn = 0; 343 if (info->gntref > 0) 344 gnttab_free_grant_references(info->gntref); 345 info->gntref = 0; 346 if (info->hvc != NULL) 347 hvc_remove(info->hvc); 348 info->hvc = NULL; 349 } 350 351 static void xencons_free(struct xencons_info *info) 352 { 353 free_page((unsigned long)info->intf); 354 info->intf = NULL; 355 info->vtermno = 0; 356 kfree(info); 357 } 358 359 static int xen_console_remove(struct xencons_info *info) 360 { 361 xencons_disconnect_backend(info); 362 spin_lock(&xencons_lock); 363 list_del(&info->list); 364 spin_unlock(&xencons_lock); 365 if (info->xbdev != NULL) 366 xencons_free(info); 367 else { 368 if (xen_hvm_domain()) 369 iounmap(info->intf); 370 kfree(info); 371 } 372 return 0; 373 } 374 375 static int xencons_remove(struct xenbus_device *dev) 376 { 377 return xen_console_remove(dev_get_drvdata(&dev->dev)); 378 } 379 380 static int xencons_connect_backend(struct xenbus_device *dev, 381 struct xencons_info *info) 382 { 383 int ret, evtchn, devid, ref, irq; 384 struct xenbus_transaction xbt; 385 grant_ref_t gref_head; 386 387 ret = xenbus_alloc_evtchn(dev, &evtchn); 388 if (ret) 389 return ret; 390 info->evtchn = evtchn; 391 irq = bind_evtchn_to_irq(evtchn); 392 if (irq < 0) 393 return irq; 394 info->irq = irq; 395 devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; 396 info->hvc = hvc_alloc(xenbus_devid_to_vtermno(devid), 397 irq, &domU_hvc_ops, 256); 398 if (IS_ERR(info->hvc)) 399 return PTR_ERR(info->hvc); 400 ret = gnttab_alloc_grant_references(1, &gref_head); 401 if (ret < 0) 402 return ret; 403 info->gntref = gref_head; 404 ref = gnttab_claim_grant_reference(&gref_head); 405 if (ref < 0) 406 return ref; 407 gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id, 408 virt_to_gfn(info->intf), 0); 409 410 again: 411 ret = xenbus_transaction_start(&xbt); 412 if (ret) { 413 xenbus_dev_fatal(dev, ret, "starting transaction"); 414 return ret; 415 } 416 ret = xenbus_printf(xbt, dev->nodename, "ring-ref", "%d", ref); 417 if (ret) 418 goto error_xenbus; 419 ret = xenbus_printf(xbt, dev->nodename, "port", "%u", 420 evtchn); 421 if (ret) 422 goto error_xenbus; 423 ret = xenbus_transaction_end(xbt, 0); 424 if (ret) { 425 if (ret == -EAGAIN) 426 goto again; 427 xenbus_dev_fatal(dev, ret, "completing transaction"); 428 return ret; 429 } 430 431 xenbus_switch_state(dev, XenbusStateInitialised); 432 return 0; 433 434 error_xenbus: 435 xenbus_transaction_end(xbt, 1); 436 xenbus_dev_fatal(dev, ret, "writing xenstore"); 437 return ret; 438 } 439 440 static int xencons_probe(struct xenbus_device *dev, 441 const struct xenbus_device_id *id) 442 { 443 int ret, devid; 444 struct xencons_info *info; 445 446 devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; 447 if (devid == 0) 448 return -ENODEV; 449 450 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); 451 if (!info) 452 return -ENOMEM; 453 dev_set_drvdata(&dev->dev, info); 454 info->xbdev = dev; 455 info->vtermno = xenbus_devid_to_vtermno(devid); 456 info->intf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); 457 if (!info->intf) 458 goto error_nomem; 459 460 ret = xencons_connect_backend(dev, info); 461 if (ret < 0) 462 goto error; 463 spin_lock(&xencons_lock); 464 list_add_tail(&info->list, &xenconsoles); 465 spin_unlock(&xencons_lock); 466 467 return 0; 468 469 error_nomem: 470 ret = -ENOMEM; 471 xenbus_dev_fatal(dev, ret, "allocating device memory"); 472 error: 473 xencons_disconnect_backend(info); 474 xencons_free(info); 475 return ret; 476 } 477 478 static int xencons_resume(struct xenbus_device *dev) 479 { 480 struct xencons_info *info = dev_get_drvdata(&dev->dev); 481 482 xencons_disconnect_backend(info); 483 memset(info->intf, 0, XEN_PAGE_SIZE); 484 return xencons_connect_backend(dev, info); 485 } 486 487 static void xencons_backend_changed(struct xenbus_device *dev, 488 enum xenbus_state backend_state) 489 { 490 switch (backend_state) { 491 case XenbusStateReconfiguring: 492 case XenbusStateReconfigured: 493 case XenbusStateInitialising: 494 case XenbusStateInitialised: 495 case XenbusStateUnknown: 496 break; 497 498 case XenbusStateInitWait: 499 break; 500 501 case XenbusStateConnected: 502 xenbus_switch_state(dev, XenbusStateConnected); 503 break; 504 505 case XenbusStateClosed: 506 if (dev->state == XenbusStateClosed) 507 break; 508 /* Missed the backend's CLOSING state -- fallthrough */ 509 case XenbusStateClosing: 510 xenbus_frontend_closed(dev); 511 break; 512 } 513 } 514 515 static const struct xenbus_device_id xencons_ids[] = { 516 { "console" }, 517 { "" } 518 }; 519 520 static struct xenbus_driver xencons_driver = { 521 .name = "xenconsole", 522 .ids = xencons_ids, 523 .probe = xencons_probe, 524 .remove = xencons_remove, 525 .resume = xencons_resume, 526 .otherend_changed = xencons_backend_changed, 527 }; 528 #endif /* CONFIG_HVC_XEN_FRONTEND */ 529 530 static int __init xen_hvc_init(void) 531 { 532 int r; 533 struct xencons_info *info; 534 const struct hv_ops *ops; 535 536 if (!xen_domain()) 537 return -ENODEV; 538 539 if (xen_initial_domain()) { 540 ops = &dom0_hvc_ops; 541 r = xen_initial_domain_console_init(); 542 if (r < 0) 543 return r; 544 info = vtermno_to_xencons(HVC_COOKIE); 545 } else { 546 ops = &domU_hvc_ops; 547 if (xen_hvm_domain()) 548 r = xen_hvm_console_init(); 549 else 550 r = xen_pv_console_init(); 551 if (r < 0) 552 return r; 553 554 info = vtermno_to_xencons(HVC_COOKIE); 555 info->irq = bind_evtchn_to_irq(info->evtchn); 556 } 557 if (info->irq < 0) 558 info->irq = 0; /* NO_IRQ */ 559 else 560 irq_set_noprobe(info->irq); 561 562 info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); 563 if (IS_ERR(info->hvc)) { 564 r = PTR_ERR(info->hvc); 565 spin_lock(&xencons_lock); 566 list_del(&info->list); 567 spin_unlock(&xencons_lock); 568 if (info->irq) 569 unbind_from_irqhandler(info->irq, NULL); 570 kfree(info); 571 return r; 572 } 573 574 r = 0; 575 #ifdef CONFIG_HVC_XEN_FRONTEND 576 r = xenbus_register_frontend(&xencons_driver); 577 #endif 578 return r; 579 } 580 device_initcall(xen_hvc_init); 581 582 static int xen_cons_init(void) 583 { 584 const struct hv_ops *ops; 585 586 if (!xen_domain()) 587 return 0; 588 589 if (xen_initial_domain()) 590 ops = &dom0_hvc_ops; 591 else { 592 int r; 593 ops = &domU_hvc_ops; 594 595 if (xen_hvm_domain()) 596 r = xen_hvm_console_init(); 597 else 598 r = xen_pv_console_init(); 599 if (r < 0) 600 return r; 601 } 602 603 hvc_instantiate(HVC_COOKIE, 0, ops); 604 return 0; 605 } 606 console_initcall(xen_cons_init); 607 608 #ifdef CONFIG_X86 609 static void xen_hvm_early_write(uint32_t vtermno, const char *str, int len) 610 { 611 if (xen_cpuid_base()) 612 outsb(0xe9, str, len); 613 } 614 #else 615 static void xen_hvm_early_write(uint32_t vtermno, const char *str, int len) { } 616 #endif 617 618 #ifdef CONFIG_EARLY_PRINTK 619 static int __init xenboot_setup_console(struct console *console, char *string) 620 { 621 static struct xencons_info xenboot; 622 623 if (xen_initial_domain()) 624 return 0; 625 if (!xen_pv_domain()) 626 return -ENODEV; 627 628 return xencons_info_pv_init(&xenboot, 0); 629 } 630 631 static void xenboot_write_console(struct console *console, const char *string, 632 unsigned len) 633 { 634 unsigned int linelen, off = 0; 635 const char *pos; 636 637 if (!xen_pv_domain()) { 638 xen_hvm_early_write(0, string, len); 639 return; 640 } 641 642 dom0_write_console(0, string, len); 643 644 if (xen_initial_domain()) 645 return; 646 647 domU_write_console(0, "(early) ", 8); 648 while (off < len && NULL != (pos = strchr(string+off, '\n'))) { 649 linelen = pos-string+off; 650 if (off + linelen > len) 651 break; 652 domU_write_console(0, string+off, linelen); 653 domU_write_console(0, "\r\n", 2); 654 off += linelen + 1; 655 } 656 if (off < len) 657 domU_write_console(0, string+off, len-off); 658 } 659 660 struct console xenboot_console = { 661 .name = "xenboot", 662 .write = xenboot_write_console, 663 .setup = xenboot_setup_console, 664 .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, 665 .index = -1, 666 }; 667 #endif /* CONFIG_EARLY_PRINTK */ 668 669 void xen_raw_console_write(const char *str) 670 { 671 ssize_t len = strlen(str); 672 int rc = 0; 673 674 if (xen_domain()) { 675 rc = dom0_write_console(0, str, len); 676 if (rc != -ENOSYS || !xen_hvm_domain()) 677 return; 678 } 679 xen_hvm_early_write(0, str, len); 680 } 681 682 void xen_raw_printk(const char *fmt, ...) 683 { 684 static char buf[512]; 685 va_list ap; 686 687 va_start(ap, fmt); 688 vsnprintf(buf, sizeof(buf), fmt, ap); 689 va_end(ap); 690 691 xen_raw_console_write(buf); 692 } 693 694 static void xenboot_earlycon_write(struct console *console, 695 const char *string, 696 unsigned len) 697 { 698 dom0_write_console(0, string, len); 699 } 700 701 static int __init xenboot_earlycon_setup(struct earlycon_device *device, 702 const char *opt) 703 { 704 device->con->write = xenboot_earlycon_write; 705 return 0; 706 } 707 EARLYCON_DECLARE(xenboot, xenboot_earlycon_setup); 708