2 * A bus for connecting virtio serial and console ports
4 * Copyright (C) 2009, 2010 Red Hat, Inc.
9 * Some earlier parts are:
10 * Copyright IBM, Corp. 2008
14 * This work is licensed under the terms of the GNU GPL, version 2. See
15 * the COPYING file in the top-level directory.
20 #include "qemu-queue.h"
22 #include "virtio-serial.h"
24 /* The virtio-serial bus on top of which the ports will ride as devices */
25 struct VirtIOSerialBus {
28 /* This is the parent device that provides the bus for ports. */
31 /* The maximum number of ports that can ride on top of this bus */
32 uint32_t max_nr_ports;
38 VirtQueue *c_ivq, *c_ovq;
39 /* Arrays of ivqs and ovqs: one per port */
40 VirtQueue **ivqs, **ovqs;
44 QTAILQ_HEAD(, VirtIOSerialPort) ports;
46 /* bitmap for identifying active ports */
49 struct virtio_console_config config;
52 static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
54 VirtIOSerialPort *port;
56 if (id == VIRTIO_CONSOLE_BAD_ID) {
60 QTAILQ_FOREACH(port, &vser->ports, next) {
67 static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq)
69 VirtIOSerialPort *port;
71 QTAILQ_FOREACH(port, &vser->ports, next) {
72 if (port->ivq == vq || port->ovq == vq)
78 static bool use_multiport(VirtIOSerial *vser)
80 return vser->vdev.guest_features & (1 << VIRTIO_CONSOLE_F_MULTIPORT);
83 static size_t write_to_port(VirtIOSerialPort *port,
84 const uint8_t *buf, size_t size)
86 VirtQueueElement elem;
91 if (!virtio_queue_ready(vq)) {
96 while (offset < size) {
99 if (!virtqueue_pop(vq, &elem)) {
103 len = iov_from_buf(elem.in_sg, elem.in_num,
104 buf + offset, size - offset);
107 virtqueue_push(vq, &elem, len);
110 virtio_notify(&port->vser->vdev, vq);
114 static size_t send_control_msg(VirtIOSerialPort *port, void *buf, size_t len)
116 VirtQueueElement elem;
118 struct virtio_console_control *cpkt;
120 vq = port->vser->c_ivq;
121 if (!virtio_queue_ready(vq)) {
124 if (!virtqueue_pop(vq, &elem)) {
128 cpkt = (struct virtio_console_control *)buf;
129 stl_p(&cpkt->id, port->id);
130 memcpy(elem.in_sg[0].iov_base, buf, len);
132 virtqueue_push(vq, &elem, len);
133 virtio_notify(&port->vser->vdev, vq);
137 static size_t send_control_event(VirtIOSerialPort *port, uint16_t event,
140 struct virtio_console_control cpkt;
142 stw_p(&cpkt.event, event);
143 stw_p(&cpkt.value, value);
145 return send_control_msg(port, &cpkt, sizeof(cpkt));
148 /* Functions for use inside qemu to open and read from/write to ports */
149 int virtio_serial_open(VirtIOSerialPort *port)
151 /* Don't allow opening an already-open port */
152 if (port->host_connected) {
155 /* Send port open notification to the guest */
156 port->host_connected = true;
157 send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
162 int virtio_serial_close(VirtIOSerialPort *port)
164 port->host_connected = false;
165 send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 0);
170 /* Individual ports/apps call this function to write to the guest. */
171 ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
174 if (!port || !port->host_connected || !port->guest_connected) {
177 return write_to_port(port, buf, size);
181 * Readiness of the guest to accept data on a port.
182 * Returns max. data the guest can receive
184 size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
186 VirtQueue *vq = port->ivq;
188 if (!virtio_queue_ready(vq) ||
189 !(port->vser->vdev.status & VIRTIO_CONFIG_S_DRIVER_OK) ||
190 virtio_queue_empty(vq)) {
193 if (use_multiport(port->vser) && !port->guest_connected) {
197 if (virtqueue_avail_bytes(vq, 4096, 0)) {
200 if (virtqueue_avail_bytes(vq, 1, 0)) {
206 /* Guest wants to notify us of some event */
207 static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
209 struct VirtIOSerialPort *port;
210 struct virtio_console_control cpkt, *gcpkt;
216 if (len < sizeof(cpkt)) {
217 /* The guest sent an invalid control packet */
221 cpkt.event = lduw_p(&gcpkt->event);
222 cpkt.value = lduw_p(&gcpkt->value);
224 port = find_port_by_id(vser, ldl_p(&gcpkt->id));
225 if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)
229 case VIRTIO_CONSOLE_DEVICE_READY:
231 error_report("virtio-serial-bus: Guest failure in adding device %s\n",
232 vser->bus->qbus.name);
236 * The device is up, we can now tell the device about all the
237 * ports we have here.
239 QTAILQ_FOREACH(port, &vser->ports, next) {
240 send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);
244 case VIRTIO_CONSOLE_PORT_READY:
246 error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",
247 port->id, vser->bus->qbus.name);
251 * Now that we know the guest asked for the port name, we're
252 * sure the guest has initialised whatever state is necessary
253 * for this port. Now's a good time to let the guest know if
254 * this port is a console port so that the guest can hook it
257 if (port->is_console) {
258 send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
262 stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME);
263 stw_p(&cpkt.value, 1);
265 buffer_len = sizeof(cpkt) + strlen(port->name) + 1;
266 buffer = qemu_malloc(buffer_len);
268 memcpy(buffer, &cpkt, sizeof(cpkt));
269 memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));
270 buffer[buffer_len - 1] = 0;
272 send_control_msg(port, buffer, buffer_len);
276 if (port->host_connected) {
277 send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);
281 * When the guest has asked us for this information it means
282 * the guest is all setup and has its virtqueues
283 * initialised. If some app is interested in knowing about
284 * this event, let it know.
286 if (port->info->guest_ready) {
287 port->info->guest_ready(port);
291 case VIRTIO_CONSOLE_PORT_OPEN:
292 port->guest_connected = cpkt.value;
293 if (cpkt.value && port->info->guest_open) {
294 /* Send the guest opened notification if an app is interested */
295 port->info->guest_open(port);
298 if (!cpkt.value && port->info->guest_close) {
299 /* Send the guest closed notification if an app is interested */
300 port->info->guest_close(port);
306 static void control_in(VirtIODevice *vdev, VirtQueue *vq)
310 static void control_out(VirtIODevice *vdev, VirtQueue *vq)
312 VirtQueueElement elem;
317 vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
321 while (virtqueue_pop(vq, &elem)) {
322 size_t cur_len, copied;
324 cur_len = iov_size(elem.out_sg, elem.out_num);
326 * Allocate a new buf only if we didn't have one previously or
327 * if the size of the buf differs
332 buf = qemu_malloc(cur_len);
335 copied = iov_to_buf(elem.out_sg, elem.out_num, buf, 0, len);
337 handle_control_message(vser, buf, copied);
338 virtqueue_push(vq, &elem, copied);
341 virtio_notify(vdev, vq);
344 /* Guest wrote something to some port. */
345 static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
348 VirtQueueElement elem;
350 vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
352 while (virtqueue_pop(vq, &elem)) {
353 VirtIOSerialPort *port;
356 port = find_port_by_vq(vser, vq);
362 if (!port->host_connected) {
368 * A port may not have any handler registered for consuming the
369 * data that the guest sends or it may not have a chardev associated
370 * with it. Just ignore the data in that case.
372 if (!port->info->have_data) {
377 /* The guest always sends only one sg */
378 ret = port->info->have_data(port, elem.out_sg[0].iov_base,
379 elem.out_sg[0].iov_len);
382 virtqueue_push(vq, &elem, ret);
384 virtio_notify(vdev, vq);
387 static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
391 static uint32_t get_features(VirtIODevice *vdev, uint32_t features)
395 vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
397 if (vser->bus->max_nr_ports > 1) {
398 features |= (1 << VIRTIO_CONSOLE_F_MULTIPORT);
403 /* Guest requested config info */
404 static void get_config(VirtIODevice *vdev, uint8_t *config_data)
408 vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
409 memcpy(config_data, &vser->config, sizeof(struct virtio_console_config));
412 static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
414 struct virtio_console_config config;
416 memcpy(&config, config_data, sizeof(config));
419 static void virtio_serial_save(QEMUFile *f, void *opaque)
421 VirtIOSerial *s = opaque;
422 VirtIOSerialPort *port;
423 uint32_t nr_active_ports;
426 /* The virtio device */
427 virtio_save(&s->vdev, f);
429 /* The config space */
430 qemu_put_be16s(f, &s->config.cols);
431 qemu_put_be16s(f, &s->config.rows);
433 qemu_put_be32s(f, &s->config.max_nr_ports);
437 for (i = 0; i < (s->config.max_nr_ports + 31) / 32; i++) {
438 qemu_put_be32s(f, &s->ports_map[i]);
444 QTAILQ_FOREACH(port, &s->ports, next) {
448 qemu_put_be32s(f, &nr_active_ports);
451 * Items in struct VirtIOSerialPort.
453 QTAILQ_FOREACH(port, &s->ports, next) {
454 qemu_put_be32s(f, &port->id);
455 qemu_put_byte(f, port->guest_connected);
456 qemu_put_byte(f, port->host_connected);
460 static int virtio_serial_load(QEMUFile *f, void *opaque, int version_id)
462 VirtIOSerial *s = opaque;
463 VirtIOSerialPort *port;
464 size_t ports_map_size;
465 uint32_t max_nr_ports, nr_active_ports, *ports_map;
468 if (version_id > 2) {
472 /* The virtio device */
473 virtio_load(&s->vdev, f);
475 if (version_id < 2) {
479 /* The config space */
480 qemu_get_be16s(f, &s->config.cols);
481 qemu_get_be16s(f, &s->config.rows);
483 qemu_get_be32s(f, &max_nr_ports);
484 if (max_nr_ports > s->config.max_nr_ports) {
485 /* Source could have had more ports than us. Fail migration. */
489 ports_map_size = sizeof(uint32_t) * (max_nr_ports + 31) / 32;
490 ports_map = qemu_malloc(ports_map_size);
492 for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
493 qemu_get_be32s(f, &ports_map[i]);
495 if (ports_map[i] != s->ports_map[i]) {
497 * Ports active on source and destination don't
498 * match. Fail migration.
500 qemu_free(ports_map);
504 qemu_free(ports_map);
506 qemu_get_be32s(f, &nr_active_ports);
508 /* Items in struct VirtIOSerialPort */
509 for (i = 0; i < nr_active_ports; i++) {
513 id = qemu_get_be32(f);
514 port = find_port_by_id(s, id);
516 port->guest_connected = qemu_get_byte(f);
517 host_connected = qemu_get_byte(f);
518 if (host_connected != port->host_connected) {
520 * We have to let the guest know of the host connection
523 send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN,
524 port->host_connected);
530 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);
532 static struct BusInfo virtser_bus_info = {
533 .name = "virtio-serial-bus",
534 .size = sizeof(VirtIOSerialBus),
535 .print_dev = virtser_bus_dev_print,
538 static VirtIOSerialBus *virtser_bus_new(DeviceState *dev)
540 VirtIOSerialBus *bus;
542 bus = FROM_QBUS(VirtIOSerialBus, qbus_create(&virtser_bus_info, dev, NULL));
543 bus->qbus.allow_hotplug = 1;
548 static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
550 VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
551 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
553 monitor_printf(mon, "%*s dev-prop-int: id: %u\n",
554 indent, "", port->id);
555 monitor_printf(mon, "%*s dev-prop-int: guest_connected: %d\n",
556 indent, "", port->guest_connected);
557 monitor_printf(mon, "%*s dev-prop-int: host_connected: %d\n",
558 indent, "", port->host_connected);
561 /* This function is only used if a port id is not provided by the user */
562 static uint32_t find_free_port_id(VirtIOSerial *vser)
566 for (i = 0; i < (vser->config.max_nr_ports + 31) / 32; i++) {
569 map = vser->ports_map[i];
572 return (bit - 1) + i * 32;
575 return VIRTIO_CONSOLE_BAD_ID;
578 static void mark_port_added(VirtIOSerial *vser, uint32_t port_id)
583 vser->ports_map[i] |= 1U << (port_id % 32);
586 static void add_port(VirtIOSerial *vser, uint32_t port_id)
588 mark_port_added(vser, port_id);
590 send_control_event(find_port_by_id(vser, port_id),
591 VIRTIO_CONSOLE_PORT_ADD, 1);
594 static void remove_port(VirtIOSerial *vser, uint32_t port_id)
599 vser->ports_map[i] &= ~(1U << (port_id % 32));
601 send_control_event(find_port_by_id(vser, port_id),
602 VIRTIO_CONSOLE_PORT_REMOVE, 1);
605 static int virtser_port_qdev_init(DeviceState *qdev, DeviceInfo *base)
607 VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
608 VirtIOSerialPortInfo *info = DO_UPCAST(VirtIOSerialPortInfo, qdev, base);
609 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
610 VirtIOSerialBus *bus = DO_UPCAST(VirtIOSerialBus, qbus, qdev->parent_bus);
614 port->vser = bus->vser;
617 * Is the first console port we're seeing? If so, put it up at
618 * location 0. This is done for backward compatibility (old
621 plugging_port0 = port->is_console && !find_port_by_id(port->vser, 0);
623 if (find_port_by_id(port->vser, port->id)) {
624 error_report("virtio-serial-bus: A port already exists at id %u\n",
629 if (port->id == VIRTIO_CONSOLE_BAD_ID) {
630 if (plugging_port0) {
633 port->id = find_free_port_id(port->vser);
634 if (port->id == VIRTIO_CONSOLE_BAD_ID) {
635 error_report("virtio-serial-bus: Maximum port limit for this device reached\n");
641 if (port->id >= port->vser->config.max_nr_ports) {
642 error_report("virtio-serial-bus: Out-of-range port id specified, max. allowed: %u\n",
643 port->vser->config.max_nr_ports - 1);
648 ret = info->init(dev);
653 if (!use_multiport(port->vser)) {
655 * Allow writes to guest in this case; we have no way of
656 * knowing if a guest port is connected.
658 port->guest_connected = true;
661 QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
662 port->ivq = port->vser->ivqs[port->id];
663 port->ovq = port->vser->ovqs[port->id];
665 add_port(port->vser, port->id);
667 /* Send an update to the guest about this new port added */
668 virtio_notify_config(&port->vser->vdev);
673 static int virtser_port_qdev_exit(DeviceState *qdev)
675 VirtIOSerialDevice *dev = DO_UPCAST(VirtIOSerialDevice, qdev, qdev);
676 VirtIOSerialPort *port = DO_UPCAST(VirtIOSerialPort, dev, &dev->qdev);
677 VirtIOSerial *vser = port->vser;
679 remove_port(port->vser, port->id);
681 QTAILQ_REMOVE(&vser->ports, port, next);
683 if (port->info->exit)
684 port->info->exit(dev);
689 void virtio_serial_port_qdev_register(VirtIOSerialPortInfo *info)
691 info->qdev.init = virtser_port_qdev_init;
692 info->qdev.bus_info = &virtser_bus_info;
693 info->qdev.exit = virtser_port_qdev_exit;
694 info->qdev.unplug = qdev_simple_unplug_cb;
695 qdev_register(&info->qdev);
698 VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)
707 vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,
708 sizeof(struct virtio_console_config),
709 sizeof(VirtIOSerial));
711 vser = DO_UPCAST(VirtIOSerial, vdev, vdev);
713 /* Spawn a new virtio-serial bus on which the ports will ride as devices */
714 vser->bus = virtser_bus_new(dev);
715 vser->bus->vser = vser;
716 QTAILQ_INIT(&vser->ports);
718 vser->bus->max_nr_ports = max_nr_ports;
719 vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
720 vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));
722 /* Add a queue for host to guest transfers for port 0 (backward compat) */
723 vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
724 /* Add a queue for guest to host transfers for port 0 (backward compat) */
725 vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);
727 /* control queue: host to guest */
728 vser->c_ivq = virtio_add_queue(vdev, 16, control_in);
729 /* control queue: guest to host */
730 vser->c_ovq = virtio_add_queue(vdev, 16, control_out);
732 for (i = 1; i < vser->bus->max_nr_ports; i++) {
733 /* Add a per-port queue for host to guest transfers */
734 vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);
735 /* Add a per-per queue for guest to host transfers */
736 vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
739 vser->config.max_nr_ports = max_nr_ports;
740 vser->ports_map = qemu_mallocz((max_nr_ports + 31) / 32);
742 * Reserve location 0 for a console port for backward compat
743 * (old kernel, new qemu)
745 mark_port_added(vser, 0);
747 vser->vdev.get_features = get_features;
748 vser->vdev.get_config = get_config;
749 vser->vdev.set_config = set_config;
752 * Register for the savevm section with the virtio-console name
753 * to preserve backward compat
755 register_savevm("virtio-console", -1, 2, virtio_serial_save,
756 virtio_serial_load, vser);