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