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