xen_console.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654
  1. /*
  2. * Copyright (C) International Business Machines Corp., 2005
  3. * Author(s): Anthony Liguori <aliguori@us.ibm.com>
  4. *
  5. * Copyright (C) Red Hat 2007
  6. *
  7. * Xen Console
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; under version 2 of the License.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, see <http://www.gnu.org/licenses/>.
  20. */
  21. #include "qemu/osdep.h"
  22. #include "qemu/cutils.h"
  23. #include <sys/select.h>
  24. #include <termios.h>
  25. #include "qapi/error.h"
  26. #include "system/system.h"
  27. #include "chardev/char-fe.h"
  28. #include "hw/xen/xen-backend.h"
  29. #include "hw/xen/xen-bus-helper.h"
  30. #include "hw/qdev-properties.h"
  31. #include "hw/qdev-properties-system.h"
  32. #include "hw/xen/interface/io/console.h"
  33. #include "hw/xen/interface/io/xs_wire.h"
  34. #include "hw/xen/interface/grant_table.h"
  35. #include "hw/i386/kvm/xen_primary_console.h"
  36. #include "trace.h"
  37. struct buffer {
  38. uint8_t *data;
  39. size_t consumed;
  40. size_t size;
  41. size_t capacity;
  42. size_t max_capacity;
  43. };
  44. struct XenConsole {
  45. struct XenDevice xendev; /* must be first */
  46. XenEventChannel *event_channel;
  47. int dev;
  48. struct buffer buffer;
  49. char *fe_path;
  50. unsigned int ring_ref;
  51. void *sring;
  52. CharBackend chr;
  53. int backlog;
  54. };
  55. typedef struct XenConsole XenConsole;
  56. #define TYPE_XEN_CONSOLE_DEVICE "xen-console"
  57. OBJECT_DECLARE_SIMPLE_TYPE(XenConsole, XEN_CONSOLE_DEVICE)
  58. static bool buffer_append(XenConsole *con)
  59. {
  60. struct buffer *buffer = &con->buffer;
  61. XENCONS_RING_IDX cons, prod, size;
  62. struct xencons_interface *intf = con->sring;
  63. cons = intf->out_cons;
  64. prod = intf->out_prod;
  65. xen_mb();
  66. size = prod - cons;
  67. if ((size == 0) || (size > sizeof(intf->out)))
  68. return false;
  69. if ((buffer->capacity - buffer->size) < size) {
  70. buffer->capacity += (size + 1024);
  71. buffer->data = g_realloc(buffer->data, buffer->capacity);
  72. }
  73. while (cons != prod)
  74. buffer->data[buffer->size++] = intf->out[
  75. MASK_XENCONS_IDX(cons++, intf->out)];
  76. xen_mb();
  77. intf->out_cons = cons;
  78. xen_device_notify_event_channel(XEN_DEVICE(con), con->event_channel, NULL);
  79. if (buffer->max_capacity &&
  80. buffer->size > buffer->max_capacity) {
  81. /* Discard the middle of the data. */
  82. size_t over = buffer->size - buffer->max_capacity;
  83. uint8_t *maxpos = buffer->data + buffer->max_capacity;
  84. memmove(maxpos - over, maxpos, over);
  85. buffer->data = g_realloc(buffer->data, buffer->max_capacity);
  86. buffer->size = buffer->capacity = buffer->max_capacity;
  87. if (buffer->consumed > buffer->max_capacity - over)
  88. buffer->consumed = buffer->max_capacity - over;
  89. }
  90. return true;
  91. }
  92. static void buffer_advance(struct buffer *buffer, size_t len)
  93. {
  94. buffer->consumed += len;
  95. if (buffer->consumed == buffer->size) {
  96. buffer->consumed = 0;
  97. buffer->size = 0;
  98. }
  99. }
  100. static int ring_free_bytes(XenConsole *con)
  101. {
  102. struct xencons_interface *intf = con->sring;
  103. XENCONS_RING_IDX cons, prod, space;
  104. cons = intf->in_cons;
  105. prod = intf->in_prod;
  106. xen_mb();
  107. space = prod - cons;
  108. if (space > sizeof(intf->in))
  109. return 0; /* ring is screwed: ignore it */
  110. return (sizeof(intf->in) - space);
  111. }
  112. static int xencons_can_receive(void *opaque)
  113. {
  114. XenConsole *con = opaque;
  115. return ring_free_bytes(con);
  116. }
  117. static void xencons_receive(void *opaque, const uint8_t *buf, int len)
  118. {
  119. XenConsole *con = opaque;
  120. struct xencons_interface *intf = con->sring;
  121. XENCONS_RING_IDX prod;
  122. int i, max;
  123. max = ring_free_bytes(con);
  124. /* The can_receive() func limits this, but check again anyway */
  125. if (max < len)
  126. len = max;
  127. prod = intf->in_prod;
  128. for (i = 0; i < len; i++) {
  129. intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
  130. buf[i];
  131. }
  132. xen_wmb();
  133. intf->in_prod = prod;
  134. xen_device_notify_event_channel(XEN_DEVICE(con), con->event_channel, NULL);
  135. }
  136. static bool xencons_send(XenConsole *con)
  137. {
  138. ssize_t len, size;
  139. size = con->buffer.size - con->buffer.consumed;
  140. if (qemu_chr_fe_backend_connected(&con->chr)) {
  141. len = qemu_chr_fe_write(&con->chr,
  142. con->buffer.data + con->buffer.consumed,
  143. size);
  144. } else {
  145. len = size;
  146. }
  147. if (len < 1) {
  148. if (!con->backlog) {
  149. con->backlog = 1;
  150. }
  151. } else {
  152. buffer_advance(&con->buffer, len);
  153. if (con->backlog && len == size) {
  154. con->backlog = 0;
  155. }
  156. }
  157. return len > 0;
  158. }
  159. /* -------------------------------------------------------------------- */
  160. static bool con_event(void *_xendev)
  161. {
  162. XenConsole *con = XEN_CONSOLE_DEVICE(_xendev);
  163. bool done_something;
  164. if (xen_device_backend_get_state(&con->xendev) != XenbusStateConnected) {
  165. return false;
  166. }
  167. done_something = buffer_append(con);
  168. if (con->buffer.size - con->buffer.consumed) {
  169. done_something |= xencons_send(con);
  170. }
  171. return done_something;
  172. }
  173. /* -------------------------------------------------------------------- */
  174. static bool xen_console_connect(XenDevice *xendev, Error **errp)
  175. {
  176. ERRP_GUARD();
  177. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  178. unsigned int port, limit;
  179. if (xen_device_frontend_scanf(xendev, "ring-ref", "%u",
  180. &con->ring_ref) != 1) {
  181. error_setg(errp, "failed to read ring-ref");
  182. return false;
  183. }
  184. if (xen_device_frontend_scanf(xendev, "port", "%u", &port) != 1) {
  185. error_setg(errp, "failed to read remote port");
  186. return false;
  187. }
  188. if (xen_device_frontend_scanf(xendev, "limit", "%u", &limit) == 1) {
  189. con->buffer.max_capacity = limit;
  190. }
  191. con->event_channel = xen_device_bind_event_channel(xendev, port,
  192. con_event,
  193. con,
  194. errp);
  195. if (!con->event_channel) {
  196. return false;
  197. }
  198. switch (con->dev) {
  199. case 0:
  200. /*
  201. * The primary console is special. For real Xen the ring-ref is
  202. * actually a GFN which needs to be mapped as foreignmem.
  203. */
  204. if (xen_mode != XEN_EMULATE) {
  205. xen_pfn_t mfn = (xen_pfn_t)con->ring_ref;
  206. con->sring = qemu_xen_foreignmem_map(xendev->frontend_id, NULL,
  207. PROT_READ | PROT_WRITE,
  208. 1, &mfn, NULL);
  209. if (!con->sring) {
  210. error_setg(errp, "failed to map console page");
  211. return false;
  212. }
  213. break;
  214. }
  215. /*
  216. * For Xen emulation, we still follow the convention of ring-ref
  217. * holding the GFN, but we map the fixed GNTTAB_RESERVED_CONSOLE
  218. * grant ref because there is no implementation of foreignmem
  219. * operations for emulated mode. The emulation code which handles
  220. * the guest-side page and event channel also needs to be informed
  221. * of the backend event channel port, in order to reconnect to it
  222. * after a soft reset.
  223. */
  224. xen_primary_console_set_be_port(
  225. xen_event_channel_get_local_port(con->event_channel));
  226. con->ring_ref = GNTTAB_RESERVED_CONSOLE;
  227. /* fallthrough */
  228. default:
  229. con->sring = xen_device_map_grant_refs(xendev,
  230. &con->ring_ref, 1,
  231. PROT_READ | PROT_WRITE,
  232. errp);
  233. if (!con->sring) {
  234. error_prepend(errp, "failed to map console grant ref: ");
  235. return false;
  236. }
  237. break;
  238. }
  239. trace_xen_console_connect(con->dev, con->ring_ref, port,
  240. con->buffer.max_capacity);
  241. qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
  242. xencons_receive, NULL, NULL, con, NULL,
  243. true);
  244. return true;
  245. }
  246. static void xen_console_disconnect(XenDevice *xendev, Error **errp)
  247. {
  248. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  249. trace_xen_console_disconnect(con->dev);
  250. qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL,
  251. con, NULL, true);
  252. if (con->event_channel) {
  253. xen_device_unbind_event_channel(xendev, con->event_channel,
  254. errp);
  255. con->event_channel = NULL;
  256. if (xen_mode == XEN_EMULATE && !con->dev) {
  257. xen_primary_console_set_be_port(0);
  258. }
  259. }
  260. if (con->sring) {
  261. if (!con->dev && xen_mode != XEN_EMULATE) {
  262. qemu_xen_foreignmem_unmap(con->sring, 1);
  263. } else {
  264. xen_device_unmap_grant_refs(xendev, con->sring,
  265. &con->ring_ref, 1, errp);
  266. }
  267. con->sring = NULL;
  268. }
  269. }
  270. static void xen_console_frontend_changed(XenDevice *xendev,
  271. enum xenbus_state frontend_state,
  272. Error **errp)
  273. {
  274. ERRP_GUARD();
  275. enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
  276. switch (frontend_state) {
  277. case XenbusStateInitialised:
  278. case XenbusStateConnected:
  279. if (backend_state == XenbusStateConnected) {
  280. break;
  281. }
  282. xen_console_disconnect(xendev, errp);
  283. if (*errp) {
  284. break;
  285. }
  286. if (!xen_console_connect(xendev, errp)) {
  287. xen_device_backend_set_state(xendev, XenbusStateClosing);
  288. break;
  289. }
  290. xen_device_backend_set_state(xendev, XenbusStateConnected);
  291. break;
  292. case XenbusStateClosing:
  293. xen_device_backend_set_state(xendev, XenbusStateClosing);
  294. break;
  295. case XenbusStateClosed:
  296. case XenbusStateUnknown:
  297. xen_console_disconnect(xendev, errp);
  298. if (*errp) {
  299. break;
  300. }
  301. xen_device_backend_set_state(xendev, XenbusStateClosed);
  302. break;
  303. default:
  304. break;
  305. }
  306. }
  307. static char *xen_console_get_name(XenDevice *xendev, Error **errp)
  308. {
  309. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  310. if (con->dev == -1) {
  311. XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
  312. int idx = (xen_mode == XEN_EMULATE) ? 0 : 1;
  313. Error *local_err = NULL;
  314. char *value;
  315. /* Theoretically we could go up to INT_MAX here but that's overkill */
  316. while (idx < 100) {
  317. if (!idx) {
  318. value = xs_node_read(xenbus->xsh, XBT_NULL, NULL, &local_err,
  319. "/local/domain/%u/console",
  320. xendev->frontend_id);
  321. } else {
  322. value = xs_node_read(xenbus->xsh, XBT_NULL, NULL, &local_err,
  323. "/local/domain/%u/device/console/%u",
  324. xendev->frontend_id, idx);
  325. }
  326. if (!value) {
  327. if (errno == ENOENT) {
  328. con->dev = idx;
  329. error_free(local_err);
  330. goto found;
  331. }
  332. error_propagate(errp, local_err);
  333. return NULL;
  334. }
  335. free(value);
  336. idx++;
  337. }
  338. error_setg(errp, "cannot find device index for console device");
  339. return NULL;
  340. }
  341. found:
  342. return g_strdup_printf("%u", con->dev);
  343. }
  344. static void xen_console_unrealize(XenDevice *xendev)
  345. {
  346. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  347. trace_xen_console_unrealize(con->dev);
  348. /* Disconnect from the frontend in case this has not already happened */
  349. xen_console_disconnect(xendev, NULL);
  350. qemu_chr_fe_deinit(&con->chr, false);
  351. }
  352. static void xen_console_realize(XenDevice *xendev, Error **errp)
  353. {
  354. ERRP_GUARD();
  355. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  356. Chardev *cs = qemu_chr_fe_get_driver(&con->chr);
  357. unsigned int u;
  358. if (!cs) {
  359. error_setg(errp, "no backing character device");
  360. return;
  361. }
  362. if (con->dev == -1) {
  363. error_setg(errp, "no device index provided");
  364. return;
  365. }
  366. /*
  367. * The Xen primary console is special. The ring-ref is actually a GFN to
  368. * be mapped directly as foreignmem (not a grant ref), and the guest port
  369. * was allocated *for* the guest by the toolstack. The guest gets these
  370. * through HVMOP_get_param and can use the console long before it's got
  371. * XenStore up and running. We cannot create those for a true Xen guest,
  372. * but we can for Xen emulation.
  373. */
  374. if (!con->dev) {
  375. if (xen_mode == XEN_EMULATE) {
  376. xen_primary_console_create();
  377. } else if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", &u)
  378. != 1 ||
  379. xen_device_frontend_scanf(xendev, "port", "%u", &u) != 1) {
  380. error_setg(errp, "cannot create primary Xen console");
  381. return;
  382. }
  383. }
  384. trace_xen_console_realize(con->dev, object_get_typename(OBJECT(cs)));
  385. if (CHARDEV_IS_PTY(cs)) {
  386. /* Strip the leading 'pty:' */
  387. xen_device_frontend_printf(xendev, "tty", "%s", cs->filename + 4);
  388. }
  389. /* No normal PV driver initialization for the primary console under Xen */
  390. if (!con->dev && xen_mode != XEN_EMULATE) {
  391. xen_console_connect(xendev, errp);
  392. }
  393. }
  394. static char *console_frontend_path(struct qemu_xs_handle *xenstore,
  395. unsigned int dom_id, unsigned int dev)
  396. {
  397. if (!dev) {
  398. return g_strdup_printf("/local/domain/%u/console", dom_id);
  399. } else {
  400. return g_strdup_printf("/local/domain/%u/device/console/%u", dom_id,
  401. dev);
  402. }
  403. }
  404. static char *xen_console_get_frontend_path(XenDevice *xendev, Error **errp)
  405. {
  406. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  407. XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
  408. char *ret = console_frontend_path(xenbus->xsh, xendev->frontend_id,
  409. con->dev);
  410. if (!ret) {
  411. error_setg(errp, "failed to create frontend path");
  412. }
  413. return ret;
  414. }
  415. static const Property xen_console_properties[] = {
  416. DEFINE_PROP_CHR("chardev", XenConsole, chr),
  417. DEFINE_PROP_INT32("idx", XenConsole, dev, -1),
  418. };
  419. static void xen_console_class_init(ObjectClass *class, void *data)
  420. {
  421. DeviceClass *dev_class = DEVICE_CLASS(class);
  422. XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);
  423. xendev_class->backend = "console";
  424. xendev_class->device = "console";
  425. xendev_class->get_name = xen_console_get_name;
  426. xendev_class->realize = xen_console_realize;
  427. xendev_class->frontend_changed = xen_console_frontend_changed;
  428. xendev_class->unrealize = xen_console_unrealize;
  429. xendev_class->get_frontend_path = xen_console_get_frontend_path;
  430. device_class_set_props(dev_class, xen_console_properties);
  431. }
  432. static const TypeInfo xen_console_type_info = {
  433. .name = TYPE_XEN_CONSOLE_DEVICE,
  434. .parent = TYPE_XEN_DEVICE,
  435. .instance_size = sizeof(XenConsole),
  436. .class_init = xen_console_class_init,
  437. };
  438. static void xen_console_register_types(void)
  439. {
  440. type_register_static(&xen_console_type_info);
  441. }
  442. type_init(xen_console_register_types)
  443. /* Called to instantiate a XenConsole when the backend is detected. */
  444. static void xen_console_device_create(XenBackendInstance *backend,
  445. QDict *opts, Error **errp)
  446. {
  447. ERRP_GUARD();
  448. XenBus *xenbus = xen_backend_get_bus(backend);
  449. const char *name = xen_backend_get_name(backend);
  450. unsigned long number;
  451. char *fe = NULL, *type = NULL, *output = NULL;
  452. char label[32];
  453. XenDevice *xendev = NULL;
  454. XenConsole *con;
  455. Chardev *cd = NULL;
  456. struct qemu_xs_handle *xsh = xenbus->xsh;
  457. if (qemu_strtoul(name, NULL, 10, &number) || number > INT_MAX) {
  458. error_setg(errp, "failed to parse name '%s'", name);
  459. goto fail;
  460. }
  461. trace_xen_console_device_create(number);
  462. fe = console_frontend_path(xsh, xen_domid, number);
  463. if (fe == NULL) {
  464. error_setg(errp, "failed to generate frontend path");
  465. goto fail;
  466. }
  467. type = xs_node_read(xsh, XBT_NULL, NULL, errp, "%s/%s", fe, "type");
  468. if (!type) {
  469. error_prepend(errp, "failed to read console device type: ");
  470. goto fail;
  471. }
  472. if (strcmp(type, "ioemu")) {
  473. error_setg(errp, "declining to handle console type '%s'",
  474. type);
  475. goto fail;
  476. }
  477. xendev = XEN_DEVICE(qdev_new(TYPE_XEN_CONSOLE_DEVICE));
  478. con = XEN_CONSOLE_DEVICE(xendev);
  479. con->dev = number;
  480. snprintf(label, sizeof(label), "xencons%ld", number);
  481. output = xs_node_read(xsh, XBT_NULL, NULL, errp, "%s/%s", fe, "output");
  482. if (output) {
  483. /*
  484. * FIXME: sure we want to support implicit
  485. * muxed monitors here?
  486. */
  487. cd = qemu_chr_new_mux_mon(label, output, NULL);
  488. if (!cd) {
  489. error_setg(errp, "console: No valid chardev found at '%s': ",
  490. output);
  491. goto fail;
  492. }
  493. } else if (errno != ENOENT) {
  494. error_prepend(errp, "console: No valid chardev found: ");
  495. goto fail;
  496. } else {
  497. error_free(*errp);
  498. *errp = NULL;
  499. if (number) {
  500. cd = serial_hd(number);
  501. if (!cd) {
  502. error_setg(errp, "console: No serial device #%ld found",
  503. number);
  504. goto fail;
  505. }
  506. } else {
  507. /* No 'output' node on primary console: use null. */
  508. cd = qemu_chr_new(label, "null", NULL);
  509. if (!cd) {
  510. error_setg(errp, "console: failed to create null device");
  511. goto fail;
  512. }
  513. }
  514. }
  515. if (!qemu_chr_fe_init(&con->chr, cd, errp)) {
  516. error_prepend(errp, "console: failed to initialize backing chardev: ");
  517. goto fail;
  518. }
  519. if (qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) {
  520. xen_backend_set_device(backend, xendev);
  521. goto done;
  522. }
  523. error_prepend(errp, "realization of console device %lu failed: ",
  524. number);
  525. fail:
  526. if (xendev) {
  527. object_unparent(OBJECT(xendev));
  528. }
  529. done:
  530. g_free(fe);
  531. free(type);
  532. free(output);
  533. }
  534. static void xen_console_device_destroy(XenBackendInstance *backend,
  535. Error **errp)
  536. {
  537. ERRP_GUARD();
  538. XenDevice *xendev = xen_backend_get_device(backend);
  539. XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
  540. trace_xen_console_device_destroy(con->dev);
  541. object_unparent(OBJECT(xendev));
  542. }
  543. static const XenBackendInfo xen_console_backend_info = {
  544. .type = "console",
  545. .create = xen_console_device_create,
  546. .destroy = xen_console_device_destroy,
  547. };
  548. static void xen_console_register_backend(void)
  549. {
  550. xen_backend_register(&xen_console_backend_info);
  551. }
  552. xen_backend_init(xen_console_register_backend);