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