virtio-serial-bus.c 33.5 KB
Newer Older
1 2 3
/*
 * A bus for connecting virtio serial and console ports
 *
4
 * Copyright (C) 2009, 2010 Red Hat, Inc.
5 6 7 8 9 10 11 12 13 14 15
 *
 * Author(s):
 *  Amit Shah <amit.shah@redhat.com>
 *
 * Some earlier parts are:
 *  Copyright IBM, Corp. 2008
 * authored by
 *  Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
16 17 18
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
19 20
 */

P
Peter Maydell 已提交
21
#include "qemu/osdep.h"
22
#include "qapi/error.h"
23
#include "qemu/iov.h"
24
#include "monitor/monitor.h"
25
#include "qemu/error-report.h"
26
#include "qemu/queue.h"
27
#include "hw/sysbus.h"
A
Amit Shah 已提交
28
#include "trace.h"
P
Paolo Bonzini 已提交
29
#include "hw/virtio/virtio-serial.h"
30
#include "hw/virtio/virtio-access.h"
31

32
static struct VirtIOSerialDevices {
33 34 35
    QLIST_HEAD(, VirtIOSerial) devices;
} vserdevices;

36 37 38 39
static VirtIOSerialPort *find_port_by_id(VirtIOSerial *vser, uint32_t id)
{
    VirtIOSerialPort *port;

40 41 42 43
    if (id == VIRTIO_CONSOLE_BAD_ID) {
        return NULL;
    }

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
    QTAILQ_FOREACH(port, &vser->ports, next) {
        if (port->id == id)
            return port;
    }
    return NULL;
}

static VirtIOSerialPort *find_port_by_vq(VirtIOSerial *vser, VirtQueue *vq)
{
    VirtIOSerialPort *port;

    QTAILQ_FOREACH(port, &vser->ports, next) {
        if (port->ivq == vq || port->ovq == vq)
            return port;
    }
    return NULL;
}

62 63 64 65 66 67 68 69
static VirtIOSerialPort *find_port_by_name(char *name)
{
    VirtIOSerial *vser;

    QLIST_FOREACH(vser, &vserdevices.devices, next) {
        VirtIOSerialPort *port;

        QTAILQ_FOREACH(port, &vser->ports, next) {
70
            if (port->name && !strcmp(port->name, name)) {
71 72 73 74 75 76 77
                return port;
            }
        }
    }
    return NULL;
}

78 79 80 81 82 83 84 85 86 87 88 89 90
static VirtIOSerialPort *find_first_connected_console(VirtIOSerial *vser)
{
    VirtIOSerialPort *port;

    QTAILQ_FOREACH(port, &vser->ports, next) {
        VirtIOSerialPortClass const *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
        if (vsc->is_console && port->host_connected) {
            return port;
        }
    }
    return NULL;
}

91 92
static bool use_multiport(VirtIOSerial *vser)
{
93
    VirtIODevice *vdev = VIRTIO_DEVICE(vser);
94
    return virtio_vdev_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT);
95 96
}

97 98 99
static size_t write_to_port(VirtIOSerialPort *port,
                            const uint8_t *buf, size_t size)
{
100
    VirtQueueElement *elem;
101
    VirtQueue *vq;
102
    size_t offset;
103 104 105 106 107 108

    vq = port->ivq;
    if (!virtio_queue_ready(vq)) {
        return 0;
    }

109
    offset = 0;
110
    while (offset < size) {
111
        size_t len;
112

113 114
        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
        if (!elem) {
115 116 117
            break;
        }

118
        len = iov_from_buf(elem->in_sg, elem->in_num, 0,
119
                           buf + offset, size - offset);
120
        offset += len;
121

122 123
        virtqueue_push(vq, elem, len);
        g_free(elem);
124 125
    }

126
    virtio_notify(VIRTIO_DEVICE(port->vser), vq);
127 128 129
    return offset;
}

130
static void discard_vq_data(VirtQueue *vq, VirtIODevice *vdev)
131
{
132
    VirtQueueElement *elem;
133

134 135 136
    if (!virtio_queue_ready(vq)) {
        return;
    }
137 138 139 140 141 142 143
    for (;;) {
        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
        if (!elem) {
            break;
        }
        virtqueue_push(vq, elem, 0);
        g_free(elem);
144 145 146 147
    }
    virtio_notify(vdev, vq);
}

148 149 150 151 152 153 154 155 156
static void discard_throttle_data(VirtIOSerialPort *port)
{
    if (port->elem) {
        virtqueue_detach_element(port->ovq, port->elem, 0);
        g_free(port->elem);
        port->elem = NULL;
    }
}

157
static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
158
                                 VirtIODevice *vdev)
159
{
160
    VirtIOSerialPortClass *vsc;
161

162
    assert(port);
163
    assert(virtio_queue_ready(vq));
164

165
    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
166

167
    while (!port->throttled) {
168
        unsigned int i;
169

170
        /* Pop an elem only if we haven't left off a previous one mid-way */
171 172 173
        if (!port->elem) {
            port->elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
            if (!port->elem) {
174 175 176 177 178
                break;
            }
            port->iov_idx = 0;
            port->iov_offset = 0;
        }
179

180
        for (i = port->iov_idx; i < port->elem->out_num; i++) {
181 182 183
            size_t buf_size;
            ssize_t ret;

184
            buf_size = port->elem->out_sg[i].iov_len - port->iov_offset;
185
            ret = vsc->have_data(port,
186
                                  port->elem->out_sg[i].iov_base
187 188
                                  + port->iov_offset,
                                  buf_size);
189
            if (port->throttled) {
190 191 192 193 194 195 196
                port->iov_idx = i;
                if (ret > 0) {
                    port->iov_offset += ret;
                }
                break;
            }
            port->iov_offset = 0;
197
        }
198 199 200
        if (port->throttled) {
            break;
        }
201 202 203
        virtqueue_push(vq, port->elem, 0);
        g_free(port->elem);
        port->elem = NULL;
204 205 206 207
    }
    virtio_notify(vdev, vq);
}

208
static void flush_queued_data(VirtIOSerialPort *port)
209
{
210
    assert(port);
211

212 213 214
    if (!virtio_queue_ready(port->ovq)) {
        return;
    }
215
    do_flush_queued_data(port, port->ovq, VIRTIO_DEVICE(port->vser));
216 217
}

218
static size_t send_control_msg(VirtIOSerial *vser, void *buf, size_t len)
219
{
220
    VirtQueueElement *elem;
221 222
    VirtQueue *vq;

223
    vq = vser->c_ivq;
224 225 226
    if (!virtio_queue_ready(vq)) {
        return 0;
    }
227 228 229

    elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
    if (!elem) {
230 231 232
        return 0;
    }

233
    /* TODO: detect a buffer that's too short, set NEEDS_RESET */
234
    iov_from_buf(elem->in_sg, elem->in_num, 0, buf, len);
235

236
    virtqueue_push(vq, elem, len);
237
    virtio_notify(VIRTIO_DEVICE(vser), vq);
238 239
    g_free(elem);

240 241 242
    return len;
}

243 244
static size_t send_control_event(VirtIOSerial *vser, uint32_t port_id,
                                 uint16_t event, uint16_t value)
245
{
246
    VirtIODevice *vdev = VIRTIO_DEVICE(vser);
247 248
    struct virtio_console_control cpkt;

249 250 251
    virtio_stl_p(vdev, &cpkt.id, port_id);
    virtio_stw_p(vdev, &cpkt.event, event);
    virtio_stw_p(vdev, &cpkt.value, value);
252

253 254
    trace_virtio_serial_send_control_event(port_id, event, value);
    return send_control_msg(vser, &cpkt, sizeof(cpkt));
255 256 257 258 259
}

/* Functions for use inside qemu to open and read from/write to ports */
int virtio_serial_open(VirtIOSerialPort *port)
{
260 261 262 263 264 265
    /* Don't allow opening an already-open port */
    if (port->host_connected) {
        return 0;
    }
    /* Send port open notification to the guest */
    port->host_connected = true;
266
    send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 1);
267

268 269 270 271 272
    return 0;
}

int virtio_serial_close(VirtIOSerialPort *port)
{
273
    port->host_connected = false;
274 275 276 277 278
    /*
     * If there's any data the guest sent which the app didn't
     * consume, reset the throttling flag and discard the data.
     */
    port->throttled = false;
279
    discard_throttle_data(port);
280
    discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser));
281

282
    send_control_event(port->vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 0);
283

284 285 286 287 288 289 290
    return 0;
}

/* Individual ports/apps call this function to write to the guest. */
ssize_t virtio_serial_write(VirtIOSerialPort *port, const uint8_t *buf,
                            size_t size)
{
291 292 293
    if (!port || !port->host_connected || !port->guest_connected) {
        return 0;
    }
294 295 296 297 298 299 300 301 302
    return write_to_port(port, buf, size);
}

/*
 * Readiness of the guest to accept data on a port.
 * Returns max. data the guest can receive
 */
size_t virtio_serial_guest_ready(VirtIOSerialPort *port)
{
303
    VirtIODevice *vdev = VIRTIO_DEVICE(port->vser);
304
    VirtQueue *vq = port->ivq;
305
    unsigned int bytes;
306 307

    if (!virtio_queue_ready(vq) ||
308
        !(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) ||
309 310 311
        virtio_queue_empty(vq)) {
        return 0;
    }
312 313 314
    if (use_multiport(port->vser) && !port->guest_connected) {
        return 0;
    }
315
    virtqueue_get_avail_bytes(vq, &bytes, NULL, 4096, 0);
316
    return bytes;
317 318
}

319 320 321 322 323 324 325
static void flush_queued_data_bh(void *opaque)
{
    VirtIOSerialPort *port = opaque;

    flush_queued_data(port);
}

326 327 328 329 330 331
void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle)
{
    if (!port) {
        return;
    }

A
Amit Shah 已提交
332
    trace_virtio_serial_throttle_port(port->id, throttle);
333 334 335 336
    port->throttled = throttle;
    if (throttle) {
        return;
    }
337
    qemu_bh_schedule(port->bh);
338 339
}

340
/* Guest wants to notify us of some event */
341
static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)
342
{
343
    VirtIODevice *vdev = VIRTIO_DEVICE(vser);
344
    struct VirtIOSerialPort *port;
345
    VirtIOSerialPortClass *vsc;
346
    struct virtio_console_control cpkt, *gcpkt;
347 348
    uint8_t *buffer;
    size_t buffer_len;
349 350 351

    gcpkt = buf;

352 353 354 355 356
    if (len < sizeof(cpkt)) {
        /* The guest sent an invalid control packet */
        return;
    }

357 358
    cpkt.event = virtio_lduw_p(vdev, &gcpkt->event);
    cpkt.value = virtio_lduw_p(vdev, &gcpkt->value);
359

A
Amit Shah 已提交
360 361
    trace_virtio_serial_handle_control_message(cpkt.event, cpkt.value);

362
    if (cpkt.event == VIRTIO_CONSOLE_DEVICE_READY) {
363
        if (!cpkt.value) {
364
            error_report("virtio-serial-bus: Guest failure in adding device %s",
365
                         vser->bus.qbus.name);
366
            return;
367
        }
368 369 370 371 372
        /*
         * The device is up, we can now tell the device about all the
         * ports we have here.
         */
        QTAILQ_FOREACH(port, &vser->ports, next) {
373
            send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_ADD, 1);
374
        }
375 376
        return;
    }
377

378
    port = find_port_by_id(vser, virtio_ldl_p(vdev, &gcpkt->id));
379
    if (!port) {
380
        error_report("virtio-serial-bus: Unexpected port id %u for device %s",
381
                     virtio_ldl_p(vdev, &gcpkt->id), vser->bus.qbus.name);
382 383 384
        return;
    }

A
Amit Shah 已提交
385 386
    trace_virtio_serial_handle_control_message_port(port->id);

387
    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
388 389

    switch(cpkt.event) {
390
    case VIRTIO_CONSOLE_PORT_READY:
391
        if (!cpkt.value) {
392
            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s",
393
                         port->id, vser->bus.qbus.name);
394 395
            break;
        }
396 397 398 399 400 401 402
        /*
         * Now that we know the guest asked for the port name, we're
         * sure the guest has initialised whatever state is necessary
         * for this port. Now's a good time to let the guest know if
         * this port is a console port so that the guest can hook it
         * up to hvc.
         */
403
        if (vsc->is_console) {
404
            send_control_event(vser, port->id, VIRTIO_CONSOLE_CONSOLE_PORT, 1);
405
        }
406

407
        if (port->name) {
408 409 410
            virtio_stl_p(vdev, &cpkt.id, port->id);
            virtio_stw_p(vdev, &cpkt.event, VIRTIO_CONSOLE_PORT_NAME);
            virtio_stw_p(vdev, &cpkt.value, 1);
411 412

            buffer_len = sizeof(cpkt) + strlen(port->name) + 1;
413
            buffer = g_malloc(buffer_len);
414 415 416 417 418

            memcpy(buffer, &cpkt, sizeof(cpkt));
            memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));
            buffer[buffer_len - 1] = 0;

419
            send_control_msg(vser, buffer, buffer_len);
420
            g_free(buffer);
421 422
        }

423
        if (port->host_connected) {
424
            send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_OPEN, 1);
425 426
        }

427 428 429 430 431 432
        /*
         * When the guest has asked us for this information it means
         * the guest is all setup and has its virtqueues
         * initialised. If some app is interested in knowing about
         * this event, let it know.
         */
433 434
        if (vsc->guest_ready) {
            vsc->guest_ready(port);
435 436
        }
        break;
437 438 439

    case VIRTIO_CONSOLE_PORT_OPEN:
        port->guest_connected = cpkt.value;
440
        if (vsc->set_guest_connected) {
441
            /* Send the guest opened notification if an app is interested */
442
            vsc->set_guest_connected(port, cpkt.value);
443 444
        }
        break;
445 446 447 448 449 450 451 452 453
    }
}

static void control_in(VirtIODevice *vdev, VirtQueue *vq)
{
}

static void control_out(VirtIODevice *vdev, VirtQueue *vq)
{
454
    VirtQueueElement *elem;
455
    VirtIOSerial *vser;
456 457
    uint8_t *buf;
    size_t len;
458

459
    vser = VIRTIO_SERIAL(vdev);
460

461 462
    len = 0;
    buf = NULL;
463
    for (;;) {
464
        size_t cur_len;
465

466 467 468 469 470 471
        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
        if (!elem) {
            break;
        }

        cur_len = iov_size(elem->out_sg, elem->out_num);
472 473 474 475 476
        /*
         * Allocate a new buf only if we didn't have one previously or
         * if the size of the buf differs
         */
        if (cur_len > len) {
477
            g_free(buf);
478

479
            buf = g_malloc(cur_len);
480 481
            len = cur_len;
        }
482
        iov_to_buf(elem->out_sg, elem->out_num, 0, buf, cur_len);
483

484
        handle_control_message(vser, buf, cur_len);
485 486
        virtqueue_push(vq, elem, 0);
        g_free(elem);
487
    }
488
    g_free(buf);
489 490 491 492 493 494 495
    virtio_notify(vdev, vq);
}

/* Guest wrote something to some port. */
static void handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOSerial *vser;
496
    VirtIOSerialPort *port;
497

498
    vser = VIRTIO_SERIAL(vdev);
499
    port = find_port_by_vq(vser, vq);
500

501
    if (!port || !port->host_connected) {
502 503 504
        discard_vq_data(vq, vdev);
        return;
    }
505 506 507

    if (!port->throttled) {
        do_flush_queued_data(port, vq, vdev);
508 509
        return;
    }
510 511 512 513
}

static void handle_input(VirtIODevice *vdev, VirtQueue *vq)
{
514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
    /*
     * Users of virtio-serial would like to know when guest becomes
     * writable again -- i.e. if a vq had stuff queued up and the
     * guest wasn't reading at all, the host would not be able to
     * write to the vq anymore.  Once the guest reads off something,
     * we can start queueing things up again.  However, this call is
     * made for each buffer addition by the guest -- even though free
     * buffers existed prior to the current buffer addition.  This is
     * done so as not to maintain previous state, which will need
     * additional live-migration-related changes.
     */
    VirtIOSerial *vser;
    VirtIOSerialPort *port;
    VirtIOSerialPortClass *vsc;

    vser = VIRTIO_SERIAL(vdev);
    port = find_port_by_vq(vser, vq);

    if (!port) {
        return;
    }
    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);

    /*
     * If guest_connected is false, this call is being made by the
     * early-boot queueing up of descriptors, which is just noise for
     * the host apps -- don't disturb them in that case.
     */
    if (port->guest_connected && port->host_connected && vsc->guest_writable) {
        vsc->guest_writable(port);
    }
545 546
}

J
Jason Wang 已提交
547 548
static uint64_t get_features(VirtIODevice *vdev, uint64_t features,
                             Error **errp)
549
{
550 551
    VirtIOSerial *vser;

552
    vser = VIRTIO_SERIAL(vdev);
553

554
    features |= vser->host_features;
555
    if (vser->bus.max_nr_ports > 1) {
556
        virtio_add_feature(&features, VIRTIO_CONSOLE_F_MULTIPORT);
557
    }
558 559 560 561 562 563
    return features;
}

/* Guest requested config info */
static void get_config(VirtIODevice *vdev, uint8_t *config_data)
{
564 565 566
    VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
    struct virtio_console_config *config =
        (struct virtio_console_config *)config_data;
567

568 569 570 571
    config->cols = 0;
    config->rows = 0;
    config->max_nr_ports = virtio_tswap32(vdev,
                                          vser->serial.max_virtserial_ports);
572 573
}

574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
/* Guest sent new config info */
static void set_config(VirtIODevice *vdev, const uint8_t *config_data)
{
    VirtIOSerial *vser = VIRTIO_SERIAL(vdev);
    struct virtio_console_config *config =
        (struct virtio_console_config *)config_data;
    uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr);
    VirtIOSerialPort *port = find_first_connected_console(vser);
    VirtIOSerialPortClass *vsc;

    if (!config->emerg_wr) {
        return;
    }
    /* Make sure we don't misdetect an emergency write when the guest
     * does a short config write after an emergency write. */
    config->emerg_wr = 0;
    if (!port) {
        return;
    }
    vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
    (void)vsc->have_data(port, &emerg_wr_lo, 1);
}

597 598 599 600 601 602 603
static void guest_reset(VirtIOSerial *vser)
{
    VirtIOSerialPort *port;
    VirtIOSerialPortClass *vsc;

    QTAILQ_FOREACH(port, &vser->ports, next) {
        vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
604 605 606

        discard_throttle_data(port);

607 608
        if (port->guest_connected) {
            port->guest_connected = false;
609 610 611
            if (vsc->set_guest_connected) {
                vsc->set_guest_connected(port, false);
            }
612 613 614 615
        }
    }
}

616 617 618 619 620
static void set_status(VirtIODevice *vdev, uint8_t status)
{
    VirtIOSerial *vser;
    VirtIOSerialPort *port;

621
    vser = VIRTIO_SERIAL(vdev);
622 623 624 625 626 627 628 629 630 631 632 633
    port = find_port_by_id(vser, 0);

    if (port && !use_multiport(port->vser)
        && (status & VIRTIO_CONFIG_S_DRIVER_OK)) {
        /*
         * Non-multiport guests won't be able to tell us guest
         * open/close status.  Such guests can only have a port at id
         * 0, so set guest_connected for such ports as soon as guest
         * is up.
         */
        port->guest_connected = true;
    }
634 635 636 637 638 639 640 641 642
    if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {
        guest_reset(vser);
    }
}

static void vser_reset(VirtIODevice *vdev)
{
    VirtIOSerial *vser;

643
    vser = VIRTIO_SERIAL(vdev);
644
    guest_reset(vser);
645 646
}

647 648 649
static void virtio_serial_save_device(VirtIODevice *vdev, QEMUFile *f)
{
    VirtIOSerial *s = VIRTIO_SERIAL(vdev);
650 651
    VirtIOSerialPort *port;
    uint32_t nr_active_ports;
652
    unsigned int i, max_nr_ports;
653
    struct virtio_console_config config;
654

655 656 657 658 659
    /* The config space (ignored on the far end in current versions) */
    get_config(vdev, (uint8_t *)&config);
    qemu_put_be16s(f, &config.cols);
    qemu_put_be16s(f, &config.rows);
    qemu_put_be32s(f, &config.max_nr_ports);
660 661

    /* The ports map */
662
    max_nr_ports = s->serial.max_virtserial_ports;
663
    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
664 665
        qemu_put_be32s(f, &s->ports_map[i]);
    }
666

667
    /* Ports */
668

669
    nr_active_ports = 0;
670
    QTAILQ_FOREACH(port, &s->ports, next) {
671
        nr_active_ports++;
672
    }
673 674 675 676 677 678 679

    qemu_put_be32s(f, &nr_active_ports);

    /*
     * Items in struct VirtIOSerialPort.
     */
    QTAILQ_FOREACH(port, &s->ports, next) {
680 681
        uint32_t elem_popped;

682 683
        qemu_put_be32s(f, &port->id);
        qemu_put_byte(f, port->guest_connected);
684
        qemu_put_byte(f, port->host_connected);
685 686

	elem_popped = 0;
687
        if (port->elem) {
688 689 690 691 692 693
            elem_popped = 1;
        }
        qemu_put_be32s(f, &elem_popped);
        if (elem_popped) {
            qemu_put_be32s(f, &port->iov_idx);
            qemu_put_be64s(f, &port->iov_offset);
694
            qemu_put_virtqueue_element(f, port->elem);
695
        }
696
    }
697 698
}

699 700
static void virtio_serial_post_load_timer_cb(void *opaque)
{
701
    uint32_t i;
702
    VirtIOSerial *s = VIRTIO_SERIAL(opaque);
703 704
    VirtIOSerialPort *port;
    uint8_t host_connected;
705
    VirtIOSerialPortClass *vsc;
706

707 708 709 710 711 712
    if (!s->post_load) {
        return;
    }
    for (i = 0 ; i < s->post_load->nr_active_ports; ++i) {
        port = s->post_load->connected[i].port;
        host_connected = s->post_load->connected[i].host_connected;
713 714 715 716 717
        if (host_connected != port->host_connected) {
            /*
             * We have to let the guest know of the host connection
             * status change
             */
718
            send_control_event(s, port->id, VIRTIO_CONSOLE_PORT_OPEN,
719 720
                               port->host_connected);
        }
721 722 723 724
        vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
        if (vsc->set_guest_connected) {
            vsc->set_guest_connected(port, port->guest_connected);
        }
725
    }
726
    g_free(s->post_load->connected);
727
    timer_free(s->post_load->timer);
728 729
    g_free(s->post_load);
    s->post_load = NULL;
730 731
}

732
static int fetch_active_ports_list(QEMUFile *f,
733 734
                                   VirtIOSerial *s, uint32_t nr_active_ports)
{
J
Jason Wang 已提交
735
    VirtIODevice *vdev = VIRTIO_DEVICE(s);
736 737
    uint32_t i;

738 739 740 741 742
    s->post_load = g_malloc0(sizeof(*s->post_load));
    s->post_load->nr_active_ports = nr_active_ports;
    s->post_load->connected =
        g_malloc0(sizeof(*s->post_load->connected) * nr_active_ports);

743
    s->post_load->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
744 745
                                            virtio_serial_post_load_timer_cb,
                                            s);
746 747 748 749

    /* Items in struct VirtIOSerialPort */
    for (i = 0; i < nr_active_ports; i++) {
        VirtIOSerialPort *port;
750
        uint32_t elem_popped;
751 752 753 754 755 756 757 758 759
        uint32_t id;

        id = qemu_get_be32(f);
        port = find_port_by_id(s, id);
        if (!port) {
            return -EINVAL;
        }

        port->guest_connected = qemu_get_byte(f);
760 761
        s->post_load->connected[i].port = port;
        s->post_load->connected[i].host_connected = qemu_get_byte(f);
762

763 764 765 766
        qemu_get_be32s(f, &elem_popped);
        if (elem_popped) {
            qemu_get_be32s(f, &port->iov_idx);
            qemu_get_be64s(f, &port->iov_offset);
767

768
            port->elem =
J
Jason Wang 已提交
769
                qemu_get_virtqueue_element(vdev, f, sizeof(VirtQueueElement));
770

771 772 773 774 775
            /*
             *  Port was throttled on source machine.  Let's
             *  unthrottle it here so data starts flowing again.
             */
            virtio_serial_throttle_port(port, false);
776 777
        }
    }
778
    timer_mod(s->post_load->timer, 1);
779 780 781
    return 0;
}

782 783 784 785 786 787 788 789
static int virtio_serial_load_device(VirtIODevice *vdev, QEMUFile *f,
                                     int version_id)
{
    VirtIOSerial *s = VIRTIO_SERIAL(vdev);
    uint32_t max_nr_ports, nr_active_ports, ports_map;
    unsigned int i;
    int ret;
    uint32_t tmp;
790

791 792 793 794
    /* Unused */
    qemu_get_be16s(f, (uint16_t *) &tmp);
    qemu_get_be16s(f, (uint16_t *) &tmp);
    qemu_get_be32s(f, &tmp);
795

796
    max_nr_ports = s->serial.max_virtserial_ports;
797
    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
798
        qemu_get_be32s(f, &ports_map);
799

800
        if (ports_map != s->ports_map[i]) {
801 802 803 804 805 806
            /*
             * Ports active on source and destination don't
             * match. Fail migration.
             */
            return -EINVAL;
        }
807 808
    }

809 810
    qemu_get_be32s(f, &nr_active_ports);

811
    if (nr_active_ports) {
812
        ret = fetch_active_ports_list(f, s, nr_active_ports);
813 814
        if (ret) {
            return ret;
815
        }
816
    }
817 818 819 820 821
    return 0;
}

static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent);

822 823 824 825 826 827
static Property virtser_props[] = {
    DEFINE_PROP_UINT32("nr", VirtIOSerialPort, id, VIRTIO_CONSOLE_BAD_ID),
    DEFINE_PROP_STRING("name", VirtIOSerialPort, name),
    DEFINE_PROP_END_OF_LIST()
};

828 829 830 831 832 833 834 835 836 837 838 839 840 841 842
#define TYPE_VIRTIO_SERIAL_BUS "virtio-serial-bus"
#define VIRTIO_SERIAL_BUS(obj) \
      OBJECT_CHECK(VirtIOSerialBus, (obj), TYPE_VIRTIO_SERIAL_BUS)

static void virtser_bus_class_init(ObjectClass *klass, void *data)
{
    BusClass *k = BUS_CLASS(klass);
    k->print_dev = virtser_bus_dev_print;
}

static const TypeInfo virtser_bus_info = {
    .name = TYPE_VIRTIO_SERIAL_BUS,
    .parent = TYPE_BUS,
    .instance_size = sizeof(VirtIOSerialBus),
    .class_init = virtser_bus_class_init,
843 844 845 846
};

static void virtser_bus_dev_print(Monitor *mon, DeviceState *qdev, int indent)
{
847
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(qdev);
848

849 850 851 852 853
    monitor_printf(mon, "%*sport %d, guest %s, host %s, throttle %s\n",
                   indent, "", port->id,
                   port->guest_connected ? "on" : "off",
                   port->host_connected ? "on" : "off",
                   port->throttled ? "on" : "off");
854 855
}

856 857 858
/* This function is only used if a port id is not provided by the user */
static uint32_t find_free_port_id(VirtIOSerial *vser)
{
859
    unsigned int i, max_nr_ports;
860

861
    max_nr_ports = vser->serial.max_virtserial_ports;
862
    for (i = 0; i < (max_nr_ports + 31) / 32; i++) {
863
        uint32_t map, zeroes;
864 865

        map = vser->ports_map[i];
866 867 868
        zeroes = ctz32(~map);
        if (zeroes != 32) {
            return zeroes + i * 32;
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
        }
    }
    return VIRTIO_CONSOLE_BAD_ID;
}

static void mark_port_added(VirtIOSerial *vser, uint32_t port_id)
{
    unsigned int i;

    i = port_id / 32;
    vser->ports_map[i] |= 1U << (port_id % 32);
}

static void add_port(VirtIOSerial *vser, uint32_t port_id)
{
    mark_port_added(vser, port_id);
885
    send_control_event(vser, port_id, VIRTIO_CONSOLE_PORT_ADD, 1);
886 887 888 889
}

static void remove_port(VirtIOSerial *vser, uint32_t port_id)
{
890
    VirtIOSerialPort *port;
891

892 893 894 895 896 897 898 899 900 901 902
    /*
     * Don't mark port 0 removed -- we explicitly reserve it for
     * backward compat with older guests, ensure a virtconsole device
     * unplug retains the reservation.
     */
    if (port_id) {
        unsigned int i;

        i = port_id / 32;
        vser->ports_map[i] &= ~(1U << (port_id % 32));
    }
903

904
    port = find_port_by_id(vser, port_id);
905 906 907 908 909 910
    /*
     * This function is only called from qdev's unplug callback; if we
     * get a NULL port here, we're in trouble.
     */
    assert(port);

911
    /* Flush out any unconsumed buffers first */
912
    discard_throttle_data(port);
913
    discard_vq_data(port->ovq, VIRTIO_DEVICE(port->vser));
914

915
    send_control_event(vser, port->id, VIRTIO_CONSOLE_PORT_REMOVE, 1);
916 917
}

918
static void virtser_port_device_realize(DeviceState *dev, Error **errp)
919
{
920
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
921
    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(port);
922 923
    VirtIOSerialBus *bus = VIRTIO_SERIAL_BUS(qdev_get_parent_bus(dev));
    int max_nr_ports;
924
    bool plugging_port0;
925
    Error *err = NULL;
926 927

    port->vser = bus->vser;
928
    port->bh = qemu_bh_new(flush_queued_data_bh, port);
929

930
    assert(vsc->have_data);
931

932 933 934 935 936
    /*
     * Is the first console port we're seeing? If so, put it up at
     * location 0. This is done for backward compatibility (old
     * kernel, new qemu).
     */
937
    plugging_port0 = vsc->is_console && !find_port_by_id(port->vser, 0);
938

939
    if (find_port_by_id(port->vser, port->id)) {
940 941 942
        error_setg(errp, "virtio-serial-bus: A port already exists at id %u",
                   port->id);
        return;
943 944
    }

945
    if (port->name != NULL && find_port_by_name(port->name)) {
946 947 948 949 950
        error_setg(errp, "virtio-serial-bus: A port already exists by name %s",
                   port->name);
        return;
    }

951 952 953 954 955 956
    if (port->id == VIRTIO_CONSOLE_BAD_ID) {
        if (plugging_port0) {
            port->id = 0;
        } else {
            port->id = find_free_port_id(port->vser);
            if (port->id == VIRTIO_CONSOLE_BAD_ID) {
957 958 959
                error_setg(errp, "virtio-serial-bus: Maximum port limit for "
                                 "this device reached");
                return;
960 961 962 963
            }
        }
    }

964
    max_nr_ports = port->vser->serial.max_virtserial_ports;
965
    if (port->id >= max_nr_ports) {
966 967 968
        error_setg(errp, "virtio-serial-bus: Out-of-range port id specified, "
                         "max. allowed: %u", max_nr_ports - 1);
        return;
969 970
    }

971 972 973 974
    vsc->realize(dev, &err);
    if (err != NULL) {
        error_propagate(errp, err);
        return;
975 976
    }

977
    port->elem = NULL;
978 979 980 981 982 983
}

static void virtser_port_device_plug(HotplugHandler *hotplug_dev,
                                     DeviceState *dev, Error **errp)
{
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
984

985 986 987 988
    QTAILQ_INSERT_TAIL(&port->vser->ports, port, next);
    port->ivq = port->vser->ivqs[port->id];
    port->ovq = port->vser->ovqs[port->id];

989 990
    add_port(port->vser, port->id);

991
    /* Send an update to the guest about this new port added */
992
    virtio_notify_config(VIRTIO_DEVICE(hotplug_dev));
993 994
}

995
static void virtser_port_device_unrealize(DeviceState *dev, Error **errp)
996
{
997 998
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
    VirtIOSerialPortClass *vsc = VIRTIO_SERIAL_PORT_GET_CLASS(dev);
999 1000
    VirtIOSerial *vser = port->vser;

1001
    qemu_bh_delete(port->bh);
1002
    remove_port(port->vser, port->id);
1003

1004 1005
    QTAILQ_REMOVE(&vser->ports, port, next);

1006 1007
    if (vsc->unrealize) {
        vsc->unrealize(dev, errp);
1008
    }
1009 1010
}

1011
static void virtio_serial_device_realize(DeviceState *dev, Error **errp)
1012
{
1013
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
1014
    VirtIOSerial *vser = VIRTIO_SERIAL(dev);
1015
    uint32_t i, max_supported_ports;
1016
    size_t config_size = sizeof(struct virtio_console_config);
1017

1018
    if (!vser->serial.max_virtserial_ports) {
1019 1020
        error_setg(errp, "Maximum number of serial ports not specified");
        return;
1021
    }
1022

1023
    /* Each port takes 2 queues, and one pair is for the control queue */
1024
    max_supported_ports = VIRTIO_QUEUE_MAX / 2 - 1;
1025

1026
    if (vser->serial.max_virtserial_ports > max_supported_ports) {
1027 1028
        error_setg(errp, "maximum ports supported: %u", max_supported_ports);
        return;
1029 1030
    }

1031 1032 1033 1034
    if (!virtio_has_feature(vser->host_features,
                            VIRTIO_CONSOLE_F_EMERG_WRITE)) {
        config_size = offsetof(struct virtio_console_config, emerg_wr);
    }
1035
    virtio_init(vdev, "virtio-serial", VIRTIO_ID_CONSOLE,
1036
                config_size);
1037 1038

    /* Spawn a new virtio-serial bus on which the ports will ride as devices */
1039
    qbus_create_inplace(&vser->bus, sizeof(vser->bus), TYPE_VIRTIO_SERIAL_BUS,
1040
                        dev, vdev->bus_name);
1041
    qbus_set_hotplug_handler(BUS(&vser->bus), DEVICE(vser), errp);
1042
    vser->bus.vser = vser;
1043 1044
    QTAILQ_INIT(&vser->ports);

1045 1046 1047 1048 1049
    vser->bus.max_nr_ports = vser->serial.max_virtserial_ports;
    vser->ivqs = g_malloc(vser->serial.max_virtserial_ports
                          * sizeof(VirtQueue *));
    vser->ovqs = g_malloc(vser->serial.max_virtserial_ports
                          * sizeof(VirtQueue *));
1050 1051 1052 1053 1054 1055

    /* Add a queue for host to guest transfers for port 0 (backward compat) */
    vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);
    /* Add a queue for guest to host transfers for port 0 (backward compat) */
    vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);

1056 1057 1058 1059 1060 1061
    /* TODO: host to guest notifications can get dropped
     * if the queue fills up. Implement queueing in host,
     * this might also make it possible to reduce the control
     * queue size: as guest preposts buffers there,
     * this will save 4Kbyte of guest memory per entry. */

1062
    /* control queue: host to guest */
1063
    vser->c_ivq = virtio_add_queue(vdev, 32, control_in);
1064
    /* control queue: guest to host */
1065
    vser->c_ovq = virtio_add_queue(vdev, 32, control_out);
1066

1067
    for (i = 1; i < vser->bus.max_nr_ports; i++) {
1068 1069 1070 1071 1072 1073
        /* Add a per-port queue for host to guest transfers */
        vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);
        /* Add a per-per queue for guest to host transfers */
        vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);
    }

1074
    vser->ports_map = g_malloc0(((vser->serial.max_virtserial_ports + 31) / 32)
1075
        * sizeof(vser->ports_map[0]));
1076 1077 1078 1079
    /*
     * Reserve location 0 for a console port for backward compat
     * (old kernel, new qemu)
     */
1080
    mark_port_added(vser, 0);
1081

1082 1083
    vser->post_load = NULL;

1084
    QLIST_INSERT_HEAD(&vserdevices.devices, vser, next);
1085
}
1086

1087 1088 1089
static void virtio_serial_port_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *k = DEVICE_CLASS(klass);
1090

1091
    set_bit(DEVICE_CATEGORY_INPUT, k->categories);
1092
    k->bus_type = TYPE_VIRTIO_SERIAL_BUS;
1093 1094
    k->realize = virtser_port_device_realize;
    k->unrealize = virtser_port_device_unrealize;
1095
    k->props = virtser_props;
1096 1097
}

1098
static const TypeInfo virtio_serial_port_type_info = {
1099 1100 1101 1102 1103
    .name = TYPE_VIRTIO_SERIAL_PORT,
    .parent = TYPE_DEVICE,
    .instance_size = sizeof(VirtIOSerialPort),
    .abstract = true,
    .class_size = sizeof(VirtIOSerialPortClass),
1104
    .class_init = virtio_serial_port_class_init,
1105 1106
};

1107
static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
1108
{
1109 1110
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOSerial *vser = VIRTIO_SERIAL(dev);
1111

1112 1113
    QLIST_REMOVE(vser, next);

1114 1115 1116 1117 1118
    g_free(vser->ivqs);
    g_free(vser->ovqs);
    g_free(vser->ports_map);
    if (vser->post_load) {
        g_free(vser->post_load->connected);
1119 1120
        timer_del(vser->post_load->timer);
        timer_free(vser->post_load->timer);
1121 1122
        g_free(vser->post_load);
    }
1123
    virtio_cleanup(vdev);
1124 1125
}

1126
/* Note: 'console' is used for backwards compatibility */
1127 1128 1129 1130 1131 1132 1133 1134 1135
static const VMStateDescription vmstate_virtio_console = {
    .name = "virtio-console",
    .minimum_version_id = 3,
    .version_id = 3,
    .fields = (VMStateField[]) {
        VMSTATE_VIRTIO_DEVICE,
        VMSTATE_END_OF_LIST()
    },
};
1136

1137
static Property virtio_serial_properties[] = {
1138 1139
    DEFINE_PROP_UINT32("max_ports", VirtIOSerial, serial.max_virtserial_ports,
                                                  31),
1140 1141
    DEFINE_PROP_BIT64("emergency-write", VirtIOSerial, host_features,
                      VIRTIO_CONSOLE_F_EMERG_WRITE, true),
1142 1143 1144 1145 1146 1147 1148
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_serial_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
1149
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
1150

1151 1152
    QLIST_INIT(&vserdevices.devices);

1153
    dc->props = virtio_serial_properties;
1154
    dc->vmsd = &vmstate_virtio_console;
1155
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1156
    vdc->realize = virtio_serial_device_realize;
1157
    vdc->unrealize = virtio_serial_device_unrealize;
1158 1159
    vdc->get_features = get_features;
    vdc->get_config = get_config;
1160
    vdc->set_config = set_config;
1161 1162
    vdc->set_status = set_status;
    vdc->reset = vser_reset;
1163 1164
    vdc->save = virtio_serial_save_device;
    vdc->load = virtio_serial_load_device;
1165 1166
    hc->plug = virtser_port_device_plug;
    hc->unplug = qdev_simple_device_unplug_cb;
1167 1168 1169 1170 1171 1172 1173
}

static const TypeInfo virtio_device_info = {
    .name = TYPE_VIRTIO_SERIAL,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VirtIOSerial),
    .class_init = virtio_serial_class_init,
1174 1175 1176 1177
    .interfaces = (InterfaceInfo[]) {
        { TYPE_HOTPLUG_HANDLER },
        { }
    }
1178 1179
};

A
Andreas Färber 已提交
1180
static void virtio_serial_register_types(void)
1181
{
1182
    type_register_static(&virtser_bus_info);
1183
    type_register_static(&virtio_serial_port_type_info);
1184
    type_register_static(&virtio_device_info);
1185 1186
}

A
Andreas Färber 已提交
1187
type_init(virtio_serial_register_types)