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 0; 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 | __GFP_ZERO); 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 = ioremap(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 | __GFP_ZERO); 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 | __GFP_ZERO); 288 if (!info) 289 return -ENOMEM; 290 } 291 292 info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); 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 void xen_console_resume(void) 303 { 304 struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); 305 if (info != NULL && info->irq) 306 rebind_evtchn_irq(info->evtchn, info->irq); 307 } 308 309 static void xencons_disconnect_backend(struct xencons_info *info) 310 { 311 if (info->irq > 0) 312 unbind_from_irqhandler(info->irq, NULL); 313 info->irq = 0; 314 if (info->evtchn > 0) 315 xenbus_free_evtchn(info->xbdev, info->evtchn); 316 info->evtchn = 0; 317 if (info->gntref > 0) 318 gnttab_free_grant_references(info->gntref); 319 info->gntref = 0; 320 if (info->hvc != NULL) 321 hvc_remove(info->hvc); 322 info->hvc = NULL; 323 } 324 325 static void xencons_free(struct xencons_info *info) 326 { 327 free_page((unsigned long)info->intf); 328 info->intf = NULL; 329 info->vtermno = 0; 330 kfree(info); 331 } 332 333 static int xen_console_remove(struct xencons_info *info) 334 { 335 xencons_disconnect_backend(info); 336 spin_lock(&xencons_lock); 337 list_del(&info->list); 338 spin_unlock(&xencons_lock); 339 if (info->xbdev != NULL) 340 xencons_free(info); 341 else { 342 if (xen_hvm_domain()) 343 iounmap(info->intf); 344 kfree(info); 345 } 346 return 0; 347 } 348 349 #ifdef CONFIG_HVC_XEN_FRONTEND 350 static struct xenbus_driver xencons_driver; 351 352 static int xencons_remove(struct xenbus_device *dev) 353 { 354 return xen_console_remove(dev_get_drvdata(&dev->dev)); 355 } 356 357 static int xencons_connect_backend(struct xenbus_device *dev, 358 struct xencons_info *info) 359 { 360 int ret, evtchn, devid, ref, irq; 361 struct xenbus_transaction xbt; 362 grant_ref_t gref_head; 363 unsigned long mfn; 364 365 ret = xenbus_alloc_evtchn(dev, &evtchn); 366 if (ret) 367 return ret; 368 info->evtchn = evtchn; 369 irq = bind_evtchn_to_irq(evtchn); 370 if (irq < 0) 371 return irq; 372 info->irq = irq; 373 devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; 374 info->hvc = hvc_alloc(xenbus_devid_to_vtermno(devid), 375 irq, &domU_hvc_ops, 256); 376 if (IS_ERR(info->hvc)) 377 return PTR_ERR(info->hvc); 378 if (xen_pv_domain()) 379 mfn = virt_to_mfn(info->intf); 380 else 381 mfn = __pa(info->intf) >> PAGE_SHIFT; 382 ret = gnttab_alloc_grant_references(1, &gref_head); 383 if (ret < 0) 384 return ret; 385 info->gntref = gref_head; 386 ref = gnttab_claim_grant_reference(&gref_head); 387 if (ref < 0) 388 return ref; 389 gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id, 390 mfn, 0); 391 392 again: 393 ret = xenbus_transaction_start(&xbt); 394 if (ret) { 395 xenbus_dev_fatal(dev, ret, "starting transaction"); 396 return ret; 397 } 398 ret = xenbus_printf(xbt, dev->nodename, "ring-ref", "%d", ref); 399 if (ret) 400 goto error_xenbus; 401 ret = xenbus_printf(xbt, dev->nodename, "port", "%u", 402 evtchn); 403 if (ret) 404 goto error_xenbus; 405 ret = xenbus_printf(xbt, dev->nodename, "type", "ioemu"); 406 if (ret) 407 goto error_xenbus; 408 ret = xenbus_transaction_end(xbt, 0); 409 if (ret) { 410 if (ret == -EAGAIN) 411 goto again; 412 xenbus_dev_fatal(dev, ret, "completing transaction"); 413 return ret; 414 } 415 416 xenbus_switch_state(dev, XenbusStateInitialised); 417 return 0; 418 419 error_xenbus: 420 xenbus_transaction_end(xbt, 1); 421 xenbus_dev_fatal(dev, ret, "writing xenstore"); 422 return ret; 423 } 424 425 static int xencons_probe(struct xenbus_device *dev, 426 const struct xenbus_device_id *id) 427 { 428 int ret, devid; 429 struct xencons_info *info; 430 431 devid = dev->nodename[strlen(dev->nodename) - 1] - '0'; 432 if (devid == 0) 433 return -ENODEV; 434 435 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); 436 if (!info) 437 return -ENOMEM; 438 dev_set_drvdata(&dev->dev, info); 439 info->xbdev = dev; 440 info->vtermno = xenbus_devid_to_vtermno(devid); 441 info->intf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); 442 if (!info->intf) 443 goto error_nomem; 444 445 ret = xencons_connect_backend(dev, info); 446 if (ret < 0) 447 goto error; 448 spin_lock(&xencons_lock); 449 list_add_tail(&info->list, &xenconsoles); 450 spin_unlock(&xencons_lock); 451 452 return 0; 453 454 error_nomem: 455 ret = -ENOMEM; 456 xenbus_dev_fatal(dev, ret, "allocating device memory"); 457 error: 458 xencons_disconnect_backend(info); 459 xencons_free(info); 460 return ret; 461 } 462 463 static int xencons_resume(struct xenbus_device *dev) 464 { 465 struct xencons_info *info = dev_get_drvdata(&dev->dev); 466 467 xencons_disconnect_backend(info); 468 memset(info->intf, 0, PAGE_SIZE); 469 return xencons_connect_backend(dev, info); 470 } 471 472 static void xencons_backend_changed(struct xenbus_device *dev, 473 enum xenbus_state backend_state) 474 { 475 switch (backend_state) { 476 case XenbusStateReconfiguring: 477 case XenbusStateReconfigured: 478 case XenbusStateInitialising: 479 case XenbusStateInitialised: 480 case XenbusStateUnknown: 481 break; 482 483 case XenbusStateInitWait: 484 break; 485 486 case XenbusStateConnected: 487 xenbus_switch_state(dev, XenbusStateConnected); 488 break; 489 490 case XenbusStateClosed: 491 if (dev->state == XenbusStateClosed) 492 break; 493 /* Missed the backend's CLOSING state -- fallthrough */ 494 case XenbusStateClosing: 495 xenbus_frontend_closed(dev); 496 break; 497 } 498 } 499 500 static const struct xenbus_device_id xencons_ids[] = { 501 { "console" }, 502 { "" } 503 }; 504 505 506 static DEFINE_XENBUS_DRIVER(xencons, "xenconsole", 507 .probe = xencons_probe, 508 .remove = xencons_remove, 509 .resume = xencons_resume, 510 .otherend_changed = xencons_backend_changed, 511 ); 512 #endif /* CONFIG_HVC_XEN_FRONTEND */ 513 514 static int __init xen_hvc_init(void) 515 { 516 int r; 517 struct xencons_info *info; 518 const struct hv_ops *ops; 519 520 if (!xen_domain()) 521 return -ENODEV; 522 523 if (xen_initial_domain()) { 524 ops = &dom0_hvc_ops; 525 r = xen_initial_domain_console_init(); 526 if (r < 0) 527 return r; 528 info = vtermno_to_xencons(HVC_COOKIE); 529 } else { 530 ops = &domU_hvc_ops; 531 if (xen_hvm_domain()) 532 r = xen_hvm_console_init(); 533 else 534 r = xen_pv_console_init(); 535 if (r < 0) 536 return r; 537 538 info = vtermno_to_xencons(HVC_COOKIE); 539 info->irq = bind_evtchn_to_irq(info->evtchn); 540 } 541 if (info->irq < 0) 542 info->irq = 0; /* NO_IRQ */ 543 else 544 irq_set_noprobe(info->irq); 545 546 info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256); 547 if (IS_ERR(info->hvc)) { 548 r = PTR_ERR(info->hvc); 549 spin_lock(&xencons_lock); 550 list_del(&info->list); 551 spin_unlock(&xencons_lock); 552 if (info->irq) 553 unbind_from_irqhandler(info->irq, NULL); 554 kfree(info); 555 return r; 556 } 557 558 r = 0; 559 #ifdef CONFIG_HVC_XEN_FRONTEND 560 r = xenbus_register_frontend(&xencons_driver); 561 #endif 562 return r; 563 } 564 565 static void __exit xen_hvc_fini(void) 566 { 567 struct xencons_info *entry, *next; 568 569 if (list_empty(&xenconsoles)) 570 return; 571 572 list_for_each_entry_safe(entry, next, &xenconsoles, list) { 573 xen_console_remove(entry); 574 } 575 } 576 577 static int xen_cons_init(void) 578 { 579 const struct hv_ops *ops; 580 581 if (!xen_domain()) 582 return 0; 583 584 if (xen_initial_domain()) 585 ops = &dom0_hvc_ops; 586 else { 587 int r; 588 ops = &domU_hvc_ops; 589 590 if (xen_hvm_domain()) 591 r = xen_hvm_console_init(); 592 else 593 r = xen_pv_console_init(); 594 if (r < 0) 595 return r; 596 } 597 598 hvc_instantiate(HVC_COOKIE, 0, ops); 599 return 0; 600 } 601 602 603 module_init(xen_hvc_init); 604 module_exit(xen_hvc_fini); 605 console_initcall(xen_cons_init); 606 607 #ifdef CONFIG_EARLY_PRINTK 608 static void xenboot_write_console(struct console *console, const char *string, 609 unsigned len) 610 { 611 unsigned int linelen, off = 0; 612 const char *pos; 613 614 if (!xen_pv_domain()) 615 return; 616 617 dom0_write_console(0, string, len); 618 619 if (xen_initial_domain()) 620 return; 621 622 domU_write_console(0, "(early) ", 8); 623 while (off < len && NULL != (pos = strchr(string+off, '\n'))) { 624 linelen = pos-string+off; 625 if (off + linelen > len) 626 break; 627 domU_write_console(0, string+off, linelen); 628 domU_write_console(0, "\r\n", 2); 629 off += linelen + 1; 630 } 631 if (off < len) 632 domU_write_console(0, string+off, len-off); 633 } 634 635 struct console xenboot_console = { 636 .name = "xenboot", 637 .write = xenboot_write_console, 638 .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME, 639 }; 640 #endif /* CONFIG_EARLY_PRINTK */ 641 642 void xen_raw_console_write(const char *str) 643 { 644 dom0_write_console(0, str, strlen(str)); 645 } 646 647 void xen_raw_printk(const char *fmt, ...) 648 { 649 static char buf[512]; 650 va_list ap; 651 652 va_start(ap, fmt); 653 vsnprintf(buf, sizeof(buf), fmt, ap); 654 va_end(ap); 655 656 xen_raw_console_write(buf); 657 } 658