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