virtio-pci.c 61.0 KB
Newer Older
P
Paul Brook 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Virtio PCI Bindings
 *
 * Copyright IBM, Corp. 2007
 * Copyright (c) 2009 CodeSourcery
 *
 * Authors:
 *  Anthony Liguori   <aliguori@us.ibm.com>
 *  Paul Brook        <paul@codesourcery.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.  See
 * the COPYING file in the top-level directory.
 *
14 15
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
P
Paul Brook 已提交
16 17 18 19
 */

#include <inttypes.h>

20
#include "standard-headers/linux/virtio_pci.h"
P
Paolo Bonzini 已提交
21 22 23 24 25 26
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-blk.h"
#include "hw/virtio/virtio-net.h"
#include "hw/virtio/virtio-serial.h"
#include "hw/virtio/virtio-scsi.h"
#include "hw/virtio/virtio-balloon.h"
27
#include "hw/pci/pci.h"
28
#include "qemu/error-report.h"
29 30 31
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "hw/loader.h"
32
#include "sysemu/kvm.h"
33
#include "sysemu/block-backend.h"
34
#include "virtio-pci.h"
35
#include "qemu/range.h"
P
Paolo Bonzini 已提交
36
#include "hw/virtio/virtio-bus.h"
37
#include "qapi/visitor.h"
P
Paul Brook 已提交
38

39
#define VIRTIO_PCI_REGION_SIZE(dev)     VIRTIO_PCI_CONFIG_OFF(msix_present(dev))
40

41 42
#undef VIRTIO_PCI_CONFIG

43 44
/* The remaining space is defined by each driver as the per-driver
 * configuration space */
45
#define VIRTIO_PCI_CONFIG_SIZE(dev)     VIRTIO_PCI_CONFIG_OFF(msix_enabled(dev))
P
Paul Brook 已提交
46

47 48
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
                               VirtIOPCIProxy *dev);
49

P
Paul Brook 已提交
50
/* virtio device */
51 52 53 54 55
/* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */
static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d)
{
    return container_of(d, VirtIOPCIProxy, pci_dev.qdev);
}
P
Paul Brook 已提交
56

57 58 59 60
/* DeviceState to VirtIOPCIProxy. Note: used on datapath,
 * be careful and test performance if you change this.
 */
static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d)
P
Paul Brook 已提交
61
{
62 63 64 65 66 67
    return container_of(d, VirtIOPCIProxy, pci_dev.qdev);
}

static void virtio_pci_notify(DeviceState *d, uint16_t vector)
{
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
P
Paolo Bonzini 已提交
68

69 70
    if (msix_enabled(&proxy->pci_dev))
        msix_notify(&proxy->pci_dev, vector);
P
Paolo Bonzini 已提交
71 72 73 74
    else {
        VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
        pci_set_irq(&proxy->pci_dev, vdev->isr & 1);
    }
P
Paul Brook 已提交
75 76
}

77
static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
78
{
79
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
80 81
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

82 83 84
    pci_device_save(&proxy->pci_dev, f);
    msix_save(&proxy->pci_dev, f);
    if (msix_present(&proxy->pci_dev))
P
Paolo Bonzini 已提交
85
        qemu_put_be16(f, vdev->config_vector);
86 87
}

88
static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
89
{
90
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
91 92
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

93
    if (msix_present(&proxy->pci_dev))
P
Paolo Bonzini 已提交
94
        qemu_put_be16(f, virtio_queue_vector(vdev, n));
95 96
}

97
static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
98
{
99
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
100 101
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

102 103
    int ret;
    ret = pci_device_load(&proxy->pci_dev, f);
104
    if (ret) {
105
        return ret;
106
    }
107
    msix_unuse_all_vectors(&proxy->pci_dev);
108
    msix_load(&proxy->pci_dev, f);
109
    if (msix_present(&proxy->pci_dev)) {
P
Paolo Bonzini 已提交
110
        qemu_get_be16s(f, &vdev->config_vector);
111
    } else {
P
Paolo Bonzini 已提交
112
        vdev->config_vector = VIRTIO_NO_VECTOR;
113
    }
P
Paolo Bonzini 已提交
114 115
    if (vdev->config_vector != VIRTIO_NO_VECTOR) {
        return msix_vector_use(&proxy->pci_dev, vdev->config_vector);
116
    }
117 118 119
    return 0;
}

120
static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
121
{
122
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
123 124
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

125
    uint16_t vector;
126 127 128 129 130
    if (msix_present(&proxy->pci_dev)) {
        qemu_get_be16s(f, &vector);
    } else {
        vector = VIRTIO_NO_VECTOR;
    }
P
Paolo Bonzini 已提交
131
    virtio_queue_set_vector(vdev, n, vector);
132 133 134
    if (vector != VIRTIO_NO_VECTOR) {
        return msix_vector_use(&proxy->pci_dev, vector);
    }
135 136 137
    return 0;
}

138
static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
P
Paolo Bonzini 已提交
139
                                                 int n, bool assign, bool set_handler)
140
{
P
Paolo Bonzini 已提交
141 142
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtQueue *vq = virtio_get_queue(vdev, n);
143
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
A
Avi Kivity 已提交
144 145
    int r = 0;

146 147 148
    if (assign) {
        r = event_notifier_init(notifier, 1);
        if (r < 0) {
149 150
            error_report("%s: unable to init event notifier: %d",
                         __func__, r);
151 152
            return r;
        }
P
Paolo Bonzini 已提交
153
        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
A
Avi Kivity 已提交
154
        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
155
                                  true, n, notifier);
156
    } else {
A
Avi Kivity 已提交
157
        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
158
                                  true, n, notifier);
P
Paolo Bonzini 已提交
159
        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
160 161 162 163 164
        event_notifier_cleanup(notifier);
    }
    return r;
}

165
static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
166
{
P
Paolo Bonzini 已提交
167
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
168 169 170 171 172
    int n, r;

    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
        proxy->ioeventfd_disabled ||
        proxy->ioeventfd_started) {
173
        return;
174 175
    }

176
    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
P
Paolo Bonzini 已提交
177
        if (!virtio_queue_get_num(vdev, n)) {
178 179 180
            continue;
        }

P
Paolo Bonzini 已提交
181
        r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
182 183 184 185 186
        if (r < 0) {
            goto assign_error;
        }
    }
    proxy->ioeventfd_started = true;
187
    return;
188 189 190

assign_error:
    while (--n >= 0) {
P
Paolo Bonzini 已提交
191
        if (!virtio_queue_get_num(vdev, n)) {
192 193 194
            continue;
        }

P
Paolo Bonzini 已提交
195
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
196
        assert(r >= 0);
197 198
    }
    proxy->ioeventfd_started = false;
199
    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
200 201
}

202
static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
203
{
P
Paolo Bonzini 已提交
204
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
205
    int r;
206 207 208
    int n;

    if (!proxy->ioeventfd_started) {
209
        return;
210 211
    }

212
    for (n = 0; n < VIRTIO_QUEUE_MAX; n++) {
P
Paolo Bonzini 已提交
213
        if (!virtio_queue_get_num(vdev, n)) {
214 215 216
            continue;
        }

P
Paolo Bonzini 已提交
217
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
218
        assert(r >= 0);
219 220 221 222
    }
    proxy->ioeventfd_started = false;
}

P
Paul Brook 已提交
223 224 225
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
    VirtIOPCIProxy *proxy = opaque;
P
Paolo Bonzini 已提交
226
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
A
Avi Kivity 已提交
227
    hwaddr pa;
P
Paul Brook 已提交
228 229 230

    switch (addr) {
    case VIRTIO_PCI_GUEST_FEATURES:
231 232 233 234
        /* Guest does not negotiate properly?  We have to assume nothing. */
        if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
            val = virtio_bus_get_vdev_bad_features(&proxy->bus);
        }
235
        virtio_set_features(vdev, val);
P
Paul Brook 已提交
236 237
        break;
    case VIRTIO_PCI_QUEUE_PFN:
A
Avi Kivity 已提交
238
        pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
239
        if (pa == 0) {
240
            virtio_pci_stop_ioeventfd(proxy);
P
Paolo Bonzini 已提交
241
            virtio_reset(vdev);
242 243
            msix_unuse_all_vectors(&proxy->pci_dev);
        }
244 245
        else
            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
P
Paul Brook 已提交
246 247
        break;
    case VIRTIO_PCI_QUEUE_SEL:
248
        if (val < VIRTIO_QUEUE_MAX)
P
Paul Brook 已提交
249 250 251
            vdev->queue_sel = val;
        break;
    case VIRTIO_PCI_QUEUE_NOTIFY:
252
        if (val < VIRTIO_QUEUE_MAX) {
253 254
            virtio_queue_notify(vdev, val);
        }
P
Paul Brook 已提交
255 256
        break;
    case VIRTIO_PCI_STATUS:
257 258 259 260
        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
            virtio_pci_stop_ioeventfd(proxy);
        }

261
        virtio_set_status(vdev, val & 0xFF);
262 263 264 265 266

        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
            virtio_pci_start_ioeventfd(proxy);
        }

267
        if (vdev->status == 0) {
P
Paolo Bonzini 已提交
268
            virtio_reset(vdev);
269 270
            msix_unuse_all_vectors(&proxy->pci_dev);
        }
271

272 273 274 275 276 277 278 279 280
        /* Linux before 2.6.34 drives the device without enabling
           the PCI device bus master bit. Enable it automatically
           for the guest. This is a PCI spec violation but so is
           initiating DMA with bus master bit clear. */
        if (val == (VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER)) {
            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
                                     proxy->pci_dev.config[PCI_COMMAND] |
                                     PCI_COMMAND_MASTER, 1);
        }
P
Paul Brook 已提交
281
        break;
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
    case VIRTIO_MSI_CONFIG_VECTOR:
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
        /* Make it possible for guest to discover an error took place. */
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
            val = VIRTIO_NO_VECTOR;
        vdev->config_vector = val;
        break;
    case VIRTIO_MSI_QUEUE_VECTOR:
        msix_vector_unuse(&proxy->pci_dev,
                          virtio_queue_vector(vdev, vdev->queue_sel));
        /* Make it possible for guest to discover an error took place. */
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
            val = VIRTIO_NO_VECTOR;
        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
        break;
    default:
298 299
        error_report("%s: unexpected address 0x%x value 0x%x",
                     __func__, addr, val);
300
        break;
P
Paul Brook 已提交
301 302 303
    }
}

304
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
P
Paul Brook 已提交
305
{
P
Paolo Bonzini 已提交
306
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
P
Paul Brook 已提交
307 308 309 310
    uint32_t ret = 0xFFFFFFFF;

    switch (addr) {
    case VIRTIO_PCI_HOST_FEATURES:
C
Cornelia Huck 已提交
311
        ret = vdev->host_features;
P
Paul Brook 已提交
312 313
        break;
    case VIRTIO_PCI_GUEST_FEATURES:
314
        ret = vdev->guest_features;
P
Paul Brook 已提交
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
        break;
    case VIRTIO_PCI_QUEUE_PFN:
        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
        break;
    case VIRTIO_PCI_QUEUE_NUM:
        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
        break;
    case VIRTIO_PCI_QUEUE_SEL:
        ret = vdev->queue_sel;
        break;
    case VIRTIO_PCI_STATUS:
        ret = vdev->status;
        break;
    case VIRTIO_PCI_ISR:
        /* reading from the ISR also clears it. */
        ret = vdev->isr;
        vdev->isr = 0;
333
        pci_irq_deassert(&proxy->pci_dev);
P
Paul Brook 已提交
334
        break;
335 336 337 338 339 340
    case VIRTIO_MSI_CONFIG_VECTOR:
        ret = vdev->config_vector;
        break;
    case VIRTIO_MSI_QUEUE_VECTOR:
        ret = virtio_queue_vector(vdev, vdev->queue_sel);
        break;
P
Paul Brook 已提交
341 342 343 344 345 346 347
    default:
        break;
    }

    return ret;
}

348 349
static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
                                       unsigned size)
P
Paul Brook 已提交
350 351
{
    VirtIOPCIProxy *proxy = opaque;
P
Paolo Bonzini 已提交
352
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
353
    uint32_t config = VIRTIO_PCI_CONFIG_SIZE(&proxy->pci_dev);
354
    uint64_t val = 0;
355
    if (addr < config) {
356
        return virtio_ioport_read(proxy, addr);
357 358
    }
    addr -= config;
P
Paul Brook 已提交
359

360 361
    switch (size) {
    case 1:
P
Paolo Bonzini 已提交
362
        val = virtio_config_readb(vdev, addr);
363 364
        break;
    case 2:
P
Paolo Bonzini 已提交
365
        val = virtio_config_readw(vdev, addr);
366
        if (virtio_is_big_endian(vdev)) {
367 368
            val = bswap16(val);
        }
369 370
        break;
    case 4:
P
Paolo Bonzini 已提交
371
        val = virtio_config_readl(vdev, addr);
372
        if (virtio_is_big_endian(vdev)) {
373 374
            val = bswap32(val);
        }
375
        break;
376
    }
377
    return val;
P
Paul Brook 已提交
378 379
}

380 381
static void virtio_pci_config_write(void *opaque, hwaddr addr,
                                    uint64_t val, unsigned size)
P
Paul Brook 已提交
382 383
{
    VirtIOPCIProxy *proxy = opaque;
384
    uint32_t config = VIRTIO_PCI_CONFIG_SIZE(&proxy->pci_dev);
P
Paolo Bonzini 已提交
385
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
386 387 388 389 390
    if (addr < config) {
        virtio_ioport_write(proxy, addr, val);
        return;
    }
    addr -= config;
391 392 393 394 395 396
    /*
     * Virtio-PCI is odd. Ioports are LE but config space is target native
     * endian.
     */
    switch (size) {
    case 1:
P
Paolo Bonzini 已提交
397
        virtio_config_writeb(vdev, addr, val);
398 399
        break;
    case 2:
400
        if (virtio_is_big_endian(vdev)) {
401 402
            val = bswap16(val);
        }
P
Paolo Bonzini 已提交
403
        virtio_config_writew(vdev, addr, val);
404 405
        break;
    case 4:
406
        if (virtio_is_big_endian(vdev)) {
407 408
            val = bswap32(val);
        }
P
Paolo Bonzini 已提交
409
        virtio_config_writel(vdev, addr, val);
410
        break;
411
    }
P
Paul Brook 已提交
412 413
}

A
Avi Kivity 已提交
414
static const MemoryRegionOps virtio_pci_config_ops = {
415 416 417 418 419 420
    .read = virtio_pci_config_read,
    .write = virtio_pci_config_write,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
421
    .endianness = DEVICE_LITTLE_ENDIAN,
A
Avi Kivity 已提交
422
};
423 424 425 426

static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
                                uint32_t val, int len)
{
427
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
P
Paolo Bonzini 已提交
428
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
429

430 431 432
    pci_default_write_config(pci_dev, address, val, len);

    if (range_covers_byte(address, len, PCI_COMMAND) &&
433
        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
434
        virtio_pci_stop_ioeventfd(proxy);
435
        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
436
    }
P
Paul Brook 已提交
437 438
}

439 440 441 442 443 444
static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
                                        unsigned int queue_no,
                                        unsigned int vector,
                                        MSIMessage msg)
{
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
445
    int ret;
446 447 448 449 450 451 452 453 454 455 456 457 458 459

    if (irqfd->users == 0) {
        ret = kvm_irqchip_add_msi_route(kvm_state, msg);
        if (ret < 0) {
            return ret;
        }
        irqfd->virq = ret;
    }
    irqfd->users++;
    return 0;
}

static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
                                             unsigned int vector)
460 461 462 463 464 465 466
{
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
    if (--irqfd->users == 0) {
        kvm_irqchip_release_virq(kvm_state, irqfd->virq);
    }
}

467 468 469 470 471
static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
                                 unsigned int queue_no,
                                 unsigned int vector)
{
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
P
Paolo Bonzini 已提交
472 473
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
474 475
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
    int ret;
476
    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq);
477 478 479 480 481 482
    return ret;
}

static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
                                      unsigned int queue_no,
                                      unsigned int vector)
483
{
P
Paolo Bonzini 已提交
484 485
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
486
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
487
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
488
    int ret;
489

J
Jan Kiszka 已提交
490
    ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq);
491
    assert(ret == 0);
492
}
493

494 495 496
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
{
    PCIDevice *dev = &proxy->pci_dev;
P
Paolo Bonzini 已提交
497
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
498
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
    unsigned int vector;
    int ret, queue_no;
    MSIMessage msg;

    for (queue_no = 0; queue_no < nvqs; queue_no++) {
        if (!virtio_queue_get_num(vdev, queue_no)) {
            break;
        }
        vector = virtio_queue_vector(vdev, queue_no);
        if (vector >= msix_nr_vectors_allocated(dev)) {
            continue;
        }
        msg = msix_get_message(dev, vector);
        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
        if (ret < 0) {
            goto undo;
515
        }
516 517 518
        /* If guest supports masking, set up irqfd now.
         * Otherwise, delay until unmasked in the frontend.
         */
519
        if (k->guest_notifier_mask) {
520 521 522 523 524 525
            ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
            if (ret < 0) {
                kvm_virtio_pci_vq_vector_release(proxy, vector);
                goto undo;
            }
        }
526 527
    }
    return 0;
528 529 530 531 532 533 534

undo:
    while (--queue_no >= 0) {
        vector = virtio_queue_vector(vdev, queue_no);
        if (vector >= msix_nr_vectors_allocated(dev)) {
            continue;
        }
535
        if (k->guest_notifier_mask) {
536
            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
537
        }
538 539 540
        kvm_virtio_pci_vq_vector_release(proxy, vector);
    }
    return ret;
541 542
}

543 544 545
static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
{
    PCIDevice *dev = &proxy->pci_dev;
P
Paolo Bonzini 已提交
546
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
547 548
    unsigned int vector;
    int queue_no;
549
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
550 551 552 553 554 555 556 557 558

    for (queue_no = 0; queue_no < nvqs; queue_no++) {
        if (!virtio_queue_get_num(vdev, queue_no)) {
            break;
        }
        vector = virtio_queue_vector(vdev, queue_no);
        if (vector >= msix_nr_vectors_allocated(dev)) {
            continue;
        }
559 560 561
        /* If guest supports masking, clean up irqfd now.
         * Otherwise, it was cleaned when masked in the frontend.
         */
562
        if (k->guest_notifier_mask) {
563
            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
564
        }
565 566 567 568
        kvm_virtio_pci_vq_vector_release(proxy, vector);
    }
}

569 570 571 572
static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
                                       unsigned int queue_no,
                                       unsigned int vector,
                                       MSIMessage msg)
573
{
P
Paolo Bonzini 已提交
574 575 576
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
577
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
578
    VirtIOIRQFD *irqfd;
579
    int ret = 0;
580

581 582 583 584 585 586 587
    if (proxy->vector_irqfd) {
        irqfd = &proxy->vector_irqfd[vector];
        if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
            ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
            if (ret < 0) {
                return ret;
            }
588 589 590
        }
    }

591 592 593
    /* If guest supports masking, irqfd is already setup, unmask it.
     * Otherwise, set it up now.
     */
594
    if (k->guest_notifier_mask) {
P
Paolo Bonzini 已提交
595
        k->guest_notifier_mask(vdev, queue_no, false);
596
        /* Test after unmasking to avoid losing events. */
597
        if (k->guest_notifier_pending &&
P
Paolo Bonzini 已提交
598
            k->guest_notifier_pending(vdev, queue_no)) {
599 600 601 602
            event_notifier_set(n);
        }
    } else {
        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
603
    }
604
    return ret;
605 606
}

607
static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
608 609 610
                                             unsigned int queue_no,
                                             unsigned int vector)
{
P
Paolo Bonzini 已提交
611 612
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
613

614 615 616
    /* If guest supports masking, keep irqfd but mask it.
     * Otherwise, clean it up now.
     */ 
617
    if (k->guest_notifier_mask) {
P
Paolo Bonzini 已提交
618
        k->guest_notifier_mask(vdev, queue_no, true);
619
    } else {
620
        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
621
    }
622 623
}

624 625
static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
                                    MSIMessage msg)
626 627
{
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
P
Paolo Bonzini 已提交
628
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
629 630
    VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
    int ret, index, unmasked = 0;
631

632 633 634
    while (vq) {
        index = virtio_get_queue_index(vq);
        if (!virtio_queue_get_num(vdev, index)) {
635 636
            break;
        }
637 638 639 640 641 642
        if (index < proxy->nvqs_with_notifiers) {
            ret = virtio_pci_vq_vector_unmask(proxy, index, vector, msg);
            if (ret < 0) {
                goto undo;
            }
            ++unmasked;
643
        }
644
        vq = virtio_vector_next_queue(vq);
645
    }
646

647 648 649
    return 0;

undo:
650
    vq = virtio_vector_first_queue(vdev, vector);
651
    while (vq && unmasked >= 0) {
652
        index = virtio_get_queue_index(vq);
653 654 655 656
        if (index < proxy->nvqs_with_notifiers) {
            virtio_pci_vq_vector_mask(proxy, index, vector);
            --unmasked;
        }
657
        vq = virtio_vector_next_queue(vq);
658 659 660 661
    }
    return ret;
}

662
static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
663 664
{
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
P
Paolo Bonzini 已提交
665
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
666 667
    VirtQueue *vq = virtio_vector_first_queue(vdev, vector);
    int index;
668

669 670 671
    while (vq) {
        index = virtio_get_queue_index(vq);
        if (!virtio_queue_get_num(vdev, index)) {
672 673
            break;
        }
674 675 676
        if (index < proxy->nvqs_with_notifiers) {
            virtio_pci_vq_vector_mask(proxy, index, vector);
        }
677
        vq = virtio_vector_next_queue(vq);
678 679 680
    }
}

681 682 683
static void virtio_pci_vector_poll(PCIDevice *dev,
                                   unsigned int vector_start,
                                   unsigned int vector_end)
684 685
{
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
P
Paolo Bonzini 已提交
686
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
687
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
688 689 690 691 692
    int queue_no;
    unsigned int vector;
    EventNotifier *notifier;
    VirtQueue *vq;

693
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
694 695 696 697 698 699 700 701 702 703
        if (!virtio_queue_get_num(vdev, queue_no)) {
            break;
        }
        vector = virtio_queue_vector(vdev, queue_no);
        if (vector < vector_start || vector >= vector_end ||
            !msix_is_masked(dev, vector)) {
            continue;
        }
        vq = virtio_get_queue(vdev, queue_no);
        notifier = virtio_queue_get_guest_notifier(vq);
704 705
        if (k->guest_notifier_pending) {
            if (k->guest_notifier_pending(vdev, queue_no)) {
706 707 708
                msix_set_pending(dev, vector);
            }
        } else if (event_notifier_test_and_clear(notifier)) {
709 710 711 712 713 714 715
            msix_set_pending(dev, vector);
        }
    }
}

static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
                                         bool with_irqfd)
716
{
717
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
718 719 720
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
    VirtQueue *vq = virtio_get_queue(vdev, n);
721 722 723 724 725 726 727
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);

    if (assign) {
        int r = event_notifier_init(notifier, 0);
        if (r < 0) {
            return r;
        }
728
        virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
729
    } else {
730
        virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
731 732 733
        event_notifier_cleanup(notifier);
    }

734
    if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) {
P
Paolo Bonzini 已提交
735
        vdc->guest_notifier_mask(vdev, n, !assign);
736 737
    }

738 739 740
    return 0;
}

741
static bool virtio_pci_query_guest_notifiers(DeviceState *d)
742
{
743
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
744 745 746
    return msix_enabled(&proxy->pci_dev);
}

747
static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
748
{
749
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
750
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
751
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
752
    int r, n;
753 754
    bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
        kvm_msi_via_irqfd_enabled();
755

756
    nvqs = MIN(nvqs, VIRTIO_QUEUE_MAX);
757 758 759 760 761 762 763 764

    /* When deassigning, pass a consistent nvqs value
     * to avoid leaking notifiers.
     */
    assert(assign || nvqs == proxy->nvqs_with_notifiers);

    proxy->nvqs_with_notifiers = nvqs;

765
    /* Must unset vector notifier while guest notifier is still assigned */
766
    if ((proxy->vector_irqfd || k->guest_notifier_mask) && !assign) {
767
        msix_unset_vector_notifiers(&proxy->pci_dev);
768 769 770 771 772
        if (proxy->vector_irqfd) {
            kvm_virtio_pci_vector_release(proxy, nvqs);
            g_free(proxy->vector_irqfd);
            proxy->vector_irqfd = NULL;
        }
773 774
    }

775
    for (n = 0; n < nvqs; n++) {
776 777 778 779
        if (!virtio_queue_get_num(vdev, n)) {
            break;
        }

780
        r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd);
781 782 783 784 785
        if (r < 0) {
            goto assign_error;
        }
    }

786
    /* Must set vector notifier after guest notifier has been assigned */
787
    if ((with_irqfd || k->guest_notifier_mask) && assign) {
788 789 790 791 792 793 794 795
        if (with_irqfd) {
            proxy->vector_irqfd =
                g_malloc0(sizeof(*proxy->vector_irqfd) *
                          msix_nr_vectors_allocated(&proxy->pci_dev));
            r = kvm_virtio_pci_vector_use(proxy, nvqs);
            if (r < 0) {
                goto assign_error;
            }
796
        }
797
        r = msix_set_vector_notifiers(&proxy->pci_dev,
798 799 800
                                      virtio_pci_vector_unmask,
                                      virtio_pci_vector_mask,
                                      virtio_pci_vector_poll);
801
        if (r < 0) {
802
            goto notifiers_error;
803 804 805
        }
    }

806 807
    return 0;

808
notifiers_error:
809 810 811 812
    if (with_irqfd) {
        assert(assign);
        kvm_virtio_pci_vector_release(proxy, nvqs);
    }
813

814 815
assign_error:
    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
816
    assert(assign);
817
    while (--n >= 0) {
818
        virtio_pci_set_guest_notifier(d, n, !assign, with_irqfd);
819 820 821 822
    }
    return r;
}

823
static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
824
{
825
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
826 827 828 829 830

    /* Stop using ioeventfd for virtqueue kick if the device starts using host
     * notifiers.  This makes it easy to avoid stepping on each others' toes.
     */
    proxy->ioeventfd_disabled = assign;
831
    if (assign) {
832 833 834 835 836 837
        virtio_pci_stop_ioeventfd(proxy);
    }
    /* We don't need to start here: it's not needed because backend
     * currently only stops on status change away from ok,
     * reset, vmstop and such. If we do add code to start here,
     * need to check vmstate, device state etc. */
P
Paolo Bonzini 已提交
838
    return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
839 840
}

841
static void virtio_pci_vmstate_change(DeviceState *d, bool running)
842
{
843
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
844
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
845 846

    if (running) {
847 848 849 850 851
        /* Old QEMU versions did not set bus master enable on status write.
         * Detect DRIVER set and enable it.
         */
        if ((proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION) &&
            (vdev->status & VIRTIO_CONFIG_S_DRIVER) &&
852
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
853 854 855
            pci_default_write_config(&proxy->pci_dev, PCI_COMMAND,
                                     proxy->pci_dev.config[PCI_COMMAND] |
                                     PCI_COMMAND_MASTER, 1);
856
        }
857
        virtio_pci_start_ioeventfd(proxy);
858
    } else {
859
        virtio_pci_stop_ioeventfd(proxy);
860 861 862
    }
}

863
#ifdef CONFIG_VIRTFS
864
static void virtio_9p_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
865
{
866 867
    V9fsPCIState *dev = VIRTIO_9P_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
868

869
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
870
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
871 872
}

873 874 875
static Property virtio_9p_pci_properties[] = {
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
876 877 878 879
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
    DEFINE_PROP_END_OF_LIST(),
};

880
static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
881 882
{
    DeviceClass *dc = DEVICE_CLASS(klass);
883 884
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
885

886
    k->realize = virtio_9p_pci_realize;
887 888 889 890
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_9P;
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
    pcidev_k->class_id = 0x2;
891
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
892
    dc->props = virtio_9p_pci_properties;
893 894
}

895 896 897
static void virtio_9p_pci_instance_init(Object *obj)
{
    V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
898 899 900

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_9P);
901 902 903 904 905 906 907 908
}

static const TypeInfo virtio_9p_pci_info = {
    .name          = TYPE_VIRTIO_9P_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(V9fsPCIState),
    .instance_init = virtio_9p_pci_instance_init,
    .class_init    = virtio_9p_pci_class_init,
909
};
910
#endif /* CONFIG_VIRTFS */
911

912 913 914 915
/*
 * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
 */

916 917 918 919 920 921 922
static int virtio_pci_query_nvectors(DeviceState *d)
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);

    return proxy->nvectors;
}

923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
static void virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
                                   struct virtio_pci_cap *cap)
{
    PCIDevice *dev = &proxy->pci_dev;
    int offset;

    cap->bar = 2;

    offset = pci_add_capability(dev, PCI_CAP_ID_VNDR, 0, cap->cap_len);
    assert(offset > 0);

    assert(cap->cap_len >= sizeof *cap);
    memcpy(dev->config + offset + PCI_CAP_FLAGS, &cap->cap_len,
           cap->cap_len - PCI_CAP_FLAGS);
}

#define QEMU_VIRTIO_PCI_QUEUE_MEM_MULT 0x10000

static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
                                       unsigned size)
{
    VirtIOPCIProxy *proxy = opaque;
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    uint32_t val = 0;
    int i;

    switch (addr) {
    case VIRTIO_PCI_COMMON_DFSELECT:
        val = proxy->dfselect;
        break;
    case VIRTIO_PCI_COMMON_DF:
        if (proxy->dfselect <= 1) {
            val = vdev->host_features >> (32 * proxy->dfselect);
        }
        break;
    case VIRTIO_PCI_COMMON_GFSELECT:
        val = proxy->gfselect;
        break;
    case VIRTIO_PCI_COMMON_GF:
        if (proxy->gfselect <= ARRAY_SIZE(proxy->guest_features)) {
            val = proxy->guest_features[proxy->gfselect];
        }
        break;
    case VIRTIO_PCI_COMMON_MSIX:
        val = vdev->config_vector;
        break;
    case VIRTIO_PCI_COMMON_NUMQ:
        for (i = 0; i < VIRTIO_QUEUE_MAX; ++i) {
            if (virtio_queue_get_num(vdev, i)) {
                val = i + 1;
            }
        }
        break;
    case VIRTIO_PCI_COMMON_STATUS:
        val = vdev->status;
        break;
    case VIRTIO_PCI_COMMON_CFGGENERATION:
980
        val = vdev->generation;
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
        break;
    case VIRTIO_PCI_COMMON_Q_SELECT:
        val = vdev->queue_sel;
        break;
    case VIRTIO_PCI_COMMON_Q_SIZE:
        val = virtio_queue_get_num(vdev, vdev->queue_sel);
        break;
    case VIRTIO_PCI_COMMON_Q_MSIX:
        val = virtio_queue_vector(vdev, vdev->queue_sel);
        break;
    case VIRTIO_PCI_COMMON_Q_ENABLE:
        val = proxy->vqs[vdev->queue_sel].enabled;
        break;
    case VIRTIO_PCI_COMMON_Q_NOFF:
        /* Simply map queues in order */
        val = vdev->queue_sel;
        break;
    case VIRTIO_PCI_COMMON_Q_DESCLO:
        val = proxy->vqs[vdev->queue_sel].desc[0];
        break;
    case VIRTIO_PCI_COMMON_Q_DESCHI:
        val = proxy->vqs[vdev->queue_sel].desc[1];
        break;
    case VIRTIO_PCI_COMMON_Q_AVAILLO:
        val = proxy->vqs[vdev->queue_sel].avail[0];
        break;
    case VIRTIO_PCI_COMMON_Q_AVAILHI:
        val = proxy->vqs[vdev->queue_sel].avail[1];
        break;
    case VIRTIO_PCI_COMMON_Q_USEDLO:
        val = proxy->vqs[vdev->queue_sel].used[0];
        break;
    case VIRTIO_PCI_COMMON_Q_USEDHI:
        val = proxy->vqs[vdev->queue_sel].used[1];
        break;
    default:
        val = 0;
    }

    return val;
}

static void virtio_pci_common_write(void *opaque, hwaddr addr,
                                    uint64_t val, unsigned size)
{
    VirtIOPCIProxy *proxy = opaque;
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

    switch (addr) {
    case VIRTIO_PCI_COMMON_DFSELECT:
        proxy->dfselect = val;
        break;
    case VIRTIO_PCI_COMMON_GFSELECT:
        proxy->gfselect = val;
        break;
    case VIRTIO_PCI_COMMON_GF:
        if (proxy->gfselect <= ARRAY_SIZE(proxy->guest_features)) {
            proxy->guest_features[proxy->gfselect] = val;
            virtio_set_features(vdev,
                                (((uint64_t)proxy->guest_features[1]) << 32) |
                                proxy->guest_features[0]);
        }
        break;
    case VIRTIO_PCI_COMMON_MSIX:
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
        /* Make it possible for guest to discover an error took place. */
        if (msix_vector_use(&proxy->pci_dev, val) < 0) {
            val = VIRTIO_NO_VECTOR;
        }
        vdev->config_vector = val;
        break;
    case VIRTIO_PCI_COMMON_STATUS:
        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
            virtio_pci_stop_ioeventfd(proxy);
        }

        virtio_set_status(vdev, val & 0xFF);

        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
            virtio_pci_start_ioeventfd(proxy);
        }

        if (vdev->status == 0) {
            virtio_reset(vdev);
            msix_unuse_all_vectors(&proxy->pci_dev);
        }

        break;
    case VIRTIO_PCI_COMMON_Q_SELECT:
        if (val < VIRTIO_QUEUE_MAX) {
            vdev->queue_sel = val;
        }
        break;
    case VIRTIO_PCI_COMMON_Q_SIZE:
        proxy->vqs[vdev->queue_sel].num = val;
        break;
    case VIRTIO_PCI_COMMON_Q_MSIX:
        msix_vector_unuse(&proxy->pci_dev,
                          virtio_queue_vector(vdev, vdev->queue_sel));
        /* Make it possible for guest to discover an error took place. */
        if (msix_vector_use(&proxy->pci_dev, val) < 0) {
            val = VIRTIO_NO_VECTOR;
        }
        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
        break;
    case VIRTIO_PCI_COMMON_Q_ENABLE:
        /* TODO: need a way to put num back on reset. */
        virtio_queue_set_num(vdev, vdev->queue_sel,
                             proxy->vqs[vdev->queue_sel].num);
        virtio_queue_set_rings(vdev, vdev->queue_sel,
                       ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 |
                       proxy->vqs[vdev->queue_sel].desc[0],
                       ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 |
                       proxy->vqs[vdev->queue_sel].avail[0],
                       ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |
                       proxy->vqs[vdev->queue_sel].used[0]);
        break;
    case VIRTIO_PCI_COMMON_Q_DESCLO:
        proxy->vqs[vdev->queue_sel].desc[0] = val;
        break;
    case VIRTIO_PCI_COMMON_Q_DESCHI:
        proxy->vqs[vdev->queue_sel].desc[1] = val;
        break;
    case VIRTIO_PCI_COMMON_Q_AVAILLO:
        proxy->vqs[vdev->queue_sel].avail[0] = val;
        break;
    case VIRTIO_PCI_COMMON_Q_AVAILHI:
        proxy->vqs[vdev->queue_sel].avail[1] = val;
        break;
    case VIRTIO_PCI_COMMON_Q_USEDLO:
        proxy->vqs[vdev->queue_sel].used[0] = val;
        break;
    case VIRTIO_PCI_COMMON_Q_USEDHI:
        proxy->vqs[vdev->queue_sel].used[1] = val;
        break;
    default:
        break;
    }
}


static uint64_t virtio_pci_notify_read(void *opaque, hwaddr addr,
                                       unsigned size)
{
    return 0;
}

static void virtio_pci_notify_write(void *opaque, hwaddr addr,
                                    uint64_t val, unsigned size)
{
    VirtIODevice *vdev = opaque;
    unsigned queue = addr / QEMU_VIRTIO_PCI_QUEUE_MEM_MULT;

    if (queue < VIRTIO_QUEUE_MAX) {
        virtio_queue_notify(vdev, queue);
    }
}

static uint64_t virtio_pci_isr_read(void *opaque, hwaddr addr,
                                    unsigned size)
{
    VirtIOPCIProxy *proxy = opaque;
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    uint64_t val = vdev->isr;

    vdev->isr = 0;
    pci_irq_deassert(&proxy->pci_dev);

    return val;
}

static void virtio_pci_isr_write(void *opaque, hwaddr addr,
                                 uint64_t val, unsigned size)
{
}

static uint64_t virtio_pci_device_read(void *opaque, hwaddr addr,
                                       unsigned size)
{
    VirtIODevice *vdev = opaque;
    uint64_t val = 0;

    switch (size) {
    case 1:
1165
        val = virtio_config_modern_readb(vdev, addr);
1166 1167
        break;
    case 2:
1168
        val = virtio_config_modern_readw(vdev, addr);
1169 1170
        break;
    case 4:
1171
        val = virtio_config_modern_readl(vdev, addr);
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
        break;
    }
    return val;
}

static void virtio_pci_device_write(void *opaque, hwaddr addr,
                                    uint64_t val, unsigned size)
{
    VirtIODevice *vdev = opaque;
    switch (size) {
    case 1:
1183
        virtio_config_modern_writeb(vdev, addr, val);
1184 1185
        break;
    case 2:
1186
        virtio_config_modern_writew(vdev, addr, val);
1187 1188
        break;
    case 4:
1189
        virtio_config_modern_writel(vdev, addr, val);
1190 1191 1192 1193 1194
        break;
    }
}


1195
/* This is called by virtio-bus just after the device is plugged. */
J
Jason Wang 已提交
1196
static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
1197 1198 1199
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
    VirtioBusState *bus = &proxy->bus;
1200 1201
    bool legacy = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_LEGACY);
    bool modern = !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN);
1202 1203
    uint8_t *config;
    uint32_t size;
C
Cornelia Huck 已提交
1204
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
1205 1206 1207 1208 1209

    config = proxy->pci_dev.config;
    if (proxy->class_code) {
        pci_config_set_class(config, proxy->class_code);
    }
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223

    if (legacy) {
        /* legacy and transitional */
        pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
                     pci_get_word(config + PCI_VENDOR_ID));
        pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
    } else {
        /* pure virtio-1.0 */
        pci_set_word(config + PCI_VENDOR_ID,
                     PCI_VENDOR_ID_REDHAT_QUMRANET);
        pci_set_word(config + PCI_DEVICE_ID,
                     0x1040 + virtio_bus_get_vdev_id(bus));
        pci_config_set_revision(config, 1);
    }
1224 1225
    config[PCI_INTERRUPT_PIN] = 1;

1226

1227
    if (modern) {
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
        struct virtio_pci_cap common = {
            .cfg_type = VIRTIO_PCI_CAP_COMMON_CFG,
            .cap_len = sizeof common,
            .offset = cpu_to_le32(0x0),
            .length = cpu_to_le32(0x1000),
        };
        struct virtio_pci_cap isr = {
            .cfg_type = VIRTIO_PCI_CAP_ISR_CFG,
            .cap_len = sizeof isr,
            .offset = cpu_to_le32(0x1000),
            .length = cpu_to_le32(0x1000),
        };
        struct virtio_pci_cap device = {
            .cfg_type = VIRTIO_PCI_CAP_DEVICE_CFG,
            .cap_len = sizeof device,
            .offset = cpu_to_le32(0x2000),
            .length = cpu_to_le32(0x1000),
        };
        struct virtio_pci_notify_cap notify = {
            .cap.cfg_type = VIRTIO_PCI_CAP_NOTIFY_CFG,
            .cap.cap_len = sizeof notify,
            .cap.offset = cpu_to_le32(0x3000),
            .cap.length = cpu_to_le32(QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
                                      VIRTIO_QUEUE_MAX),
            .notify_off_multiplier =
                cpu_to_le32(QEMU_VIRTIO_PCI_QUEUE_MEM_MULT),
        };

        static const MemoryRegionOps common_ops = {
            .read = virtio_pci_common_read,
            .write = virtio_pci_common_write,
            .impl = {
                .min_access_size = 1,
                .max_access_size = 4,
            },
            .endianness = DEVICE_LITTLE_ENDIAN,
        };

        static const MemoryRegionOps isr_ops = {
            .read = virtio_pci_isr_read,
            .write = virtio_pci_isr_write,
            .impl = {
                .min_access_size = 1,
                .max_access_size = 4,
            },
            .endianness = DEVICE_LITTLE_ENDIAN,
        };

        static const MemoryRegionOps device_ops = {
            .read = virtio_pci_device_read,
            .write = virtio_pci_device_write,
            .impl = {
                .min_access_size = 1,
                .max_access_size = 4,
            },
            .endianness = DEVICE_LITTLE_ENDIAN,
        };

        static const MemoryRegionOps notify_ops = {
            .read = virtio_pci_notify_read,
            .write = virtio_pci_notify_write,
            .impl = {
                .min_access_size = 1,
                .max_access_size = 4,
            },
            .endianness = DEVICE_LITTLE_ENDIAN,
        };

        /* TODO: add io access for speed */
        virtio_pci_add_mem_cap(proxy, &common);
        virtio_pci_add_mem_cap(proxy, &isr);
        virtio_pci_add_mem_cap(proxy, &device);
        virtio_pci_add_mem_cap(proxy, &notify.cap);

        virtio_add_feature(&vdev->host_features, VIRTIO_F_VERSION_1);
        memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci",
                           2 * QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
                           VIRTIO_QUEUE_MAX);
        memory_region_init_io(&proxy->common, OBJECT(proxy),
                              &common_ops,
                              proxy,
                              "virtio-pci-common", 0x1000);
        memory_region_add_subregion(&proxy->modern_bar, 0, &proxy->common);
        memory_region_init_io(&proxy->isr, OBJECT(proxy),
                              &isr_ops,
                              proxy,
                              "virtio-pci-isr", 0x1000);
        memory_region_add_subregion(&proxy->modern_bar, 0x1000, &proxy->isr);
        memory_region_init_io(&proxy->device, OBJECT(proxy),
                              &device_ops,
                              virtio_bus_get_device(&proxy->bus),
                              "virtio-pci-device", 0x1000);
        memory_region_add_subregion(&proxy->modern_bar, 0x2000, &proxy->device);
        memory_region_init_io(&proxy->notify, OBJECT(proxy),
                              &notify_ops,
                              virtio_bus_get_device(&proxy->bus),
                              "virtio-pci-notify",
                              QEMU_VIRTIO_PCI_QUEUE_MEM_MULT *
                              VIRTIO_QUEUE_MAX);
        memory_region_add_subregion(&proxy->modern_bar, 0x3000, &proxy->notify);
        pci_register_bar(&proxy->pci_dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY,
                         &proxy->modern_bar);
    }

1332 1333
    if (proxy->nvectors &&
        msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors, 1)) {
1334 1335
        error_report("unable to init msix vectors to %" PRIu32,
                     proxy->nvectors);
1336 1337 1338 1339 1340
        proxy->nvectors = 0;
    }

    proxy->pci_dev.config_write = virtio_write_config;

1341 1342 1343 1344 1345 1346
    if (legacy) {
        size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev)
            + virtio_bus_get_vdev_config_len(bus);
        if (size & (size - 1)) {
            size = 1 << qemu_fls(size);
        }
1347

1348 1349 1350
        memory_region_init_io(&proxy->bar, OBJECT(proxy),
                              &virtio_pci_config_ops,
                              proxy, "virtio-pci", size);
1351

1352 1353 1354
        pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
                         &proxy->bar);
    }
1355 1356 1357 1358 1359

    if (!kvm_has_many_ioeventfds()) {
        proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
    }

C
Cornelia Huck 已提交
1360
    virtio_add_feature(&vdev->host_features, VIRTIO_F_BAD_FEATURE);
1361 1362
}

1363 1364 1365 1366 1367 1368 1369
static void virtio_pci_device_unplugged(DeviceState *d)
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);

    virtio_pci_stop_ioeventfd(proxy);
}

1370
static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
1371 1372 1373
{
    VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
    VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
1374

1375
    virtio_pci_bus_new(&dev->bus, sizeof(dev->bus), dev);
1376 1377
    if (k->realize) {
        k->realize(dev, errp);
1378 1379 1380 1381 1382
    }
}

static void virtio_pci_exit(PCIDevice *pci_dev)
{
1383
    msix_uninit_exclusive_bar(pci_dev);
1384 1385
}

1386
static void virtio_pci_reset(DeviceState *qdev)
1387 1388 1389 1390 1391 1392 1393 1394
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
    VirtioBusState *bus = VIRTIO_BUS(&proxy->bus);
    virtio_pci_stop_ioeventfd(proxy);
    virtio_bus_reset(bus);
    msix_unuse_all_vectors(&proxy->pci_dev);
}

1395
static Property virtio_pci_properties[] = {
1396 1397
    DEFINE_PROP_BIT("virtio-pci-bus-master-bug-migration", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false),
1398 1399 1400 1401
    DEFINE_PROP_BIT("disable-legacy", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_DISABLE_LEGACY_BIT, false),
    DEFINE_PROP_BIT("disable-modern", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_DISABLE_MODERN_BIT, true),
1402 1403 1404
    DEFINE_PROP_END_OF_LIST(),
};

1405 1406 1407 1408 1409
static void virtio_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

1410
    dc->props = virtio_pci_properties;
1411
    k->realize = virtio_pci_realize;
1412 1413 1414 1415
    k->exit = virtio_pci_exit;
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    k->revision = VIRTIO_PCI_ABI_VERSION;
    k->class_id = PCI_CLASS_OTHERS;
1416
    dc->reset = virtio_pci_reset;
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427
}

static const TypeInfo virtio_pci_info = {
    .name          = TYPE_VIRTIO_PCI,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(VirtIOPCIProxy),
    .class_init    = virtio_pci_class_init,
    .class_size    = sizeof(VirtioPCIClass),
    .abstract      = true,
};

1428 1429 1430
/* virtio-blk-pci */

static Property virtio_blk_pci_properties[] = {
1431
    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
1432 1433 1434 1435 1436 1437
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
    DEFINE_PROP_END_OF_LIST(),
};

1438
static void virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1439 1440 1441
{
    VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
1442

1443
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1444
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
1445 1446 1447 1448 1449 1450 1451 1452
}

static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);

1453
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1454
    dc->props = virtio_blk_pci_properties;
1455
    k->realize = virtio_blk_pci_realize;
1456 1457 1458 1459 1460 1461 1462 1463 1464
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
    pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
}

static void virtio_blk_pci_instance_init(Object *obj)
{
    VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj);
1465 1466 1467

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_BLK);
1468 1469
    object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
                              &error_abort);
1470 1471
    object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
                              "bootindex", &error_abort);
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
}

static const TypeInfo virtio_blk_pci_info = {
    .name          = TYPE_VIRTIO_BLK_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VirtIOBlkPCI),
    .instance_init = virtio_blk_pci_instance_init,
    .class_init    = virtio_blk_pci_class_init,
};

1482 1483 1484 1485 1486 1487 1488 1489 1490 1491
/* virtio-scsi-pci */

static Property virtio_scsi_pci_properties[] = {
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
                       DEV_NVECTORS_UNSPECIFIED),
    DEFINE_PROP_END_OF_LIST(),
};

1492
static void virtio_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1493 1494 1495
{
    VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
1496
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
1497 1498
    DeviceState *proxy = DEVICE(vpci_dev);
    char *bus_name;
1499 1500

    if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
1501
        vpci_dev->nvectors = vs->conf.num_queues + 3;
1502 1503
    }

1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
    /*
     * For command line compatibility, this sets the virtio-scsi-device bus
     * name as before.
     */
    if (proxy->id) {
        bus_name = g_strdup_printf("%s.0", proxy->id);
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
        g_free(bus_name);
    }

1514
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1515
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
1516 1517 1518 1519 1520 1521 1522
}

static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1523 1524

    k->realize = virtio_scsi_pci_realize;
1525
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535
    dc->props = virtio_scsi_pci_properties;
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
    pcidev_k->revision = 0x00;
    pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
}

static void virtio_scsi_pci_instance_init(Object *obj)
{
    VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
1536 1537 1538

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_SCSI);
1539 1540
    object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev), "iothread",
                              &error_abort);
1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
}

static const TypeInfo virtio_scsi_pci_info = {
    .name          = TYPE_VIRTIO_SCSI_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VirtIOSCSIPCI),
    .instance_init = virtio_scsi_pci_instance_init,
    .class_init    = virtio_scsi_pci_class_init,
};

1551 1552 1553 1554 1555 1556 1557 1558 1559
/* vhost-scsi-pci */

#ifdef CONFIG_VHOST_SCSI
static Property vhost_scsi_pci_properties[] = {
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
                       DEV_NVECTORS_UNSPECIFIED),
    DEFINE_PROP_END_OF_LIST(),
};

1560
static void vhost_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1561 1562 1563 1564 1565 1566 1567 1568 1569 1570
{
    VHostSCSIPCI *dev = VHOST_SCSI_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);

    if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
        vpci_dev->nvectors = vs->conf.num_queues + 3;
    }

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1571
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
1572 1573 1574 1575 1576 1577 1578
}

static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1579
    k->realize = vhost_scsi_pci_realize;
1580
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1581 1582 1583 1584 1585 1586 1587 1588 1589 1590
    dc->props = vhost_scsi_pci_properties;
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
    pcidev_k->revision = 0x00;
    pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
}

static void vhost_scsi_pci_instance_init(Object *obj)
{
    VHostSCSIPCI *dev = VHOST_SCSI_PCI(obj);
1591 1592 1593

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VHOST_SCSI);
G
Gonglei 已提交
1594 1595
    object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
                              "bootindex", &error_abort);
1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606
}

static const TypeInfo vhost_scsi_pci_info = {
    .name          = TYPE_VHOST_SCSI_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VHostSCSIPCI),
    .instance_init = vhost_scsi_pci_instance_init,
    .class_init    = vhost_scsi_pci_class_init,
};
#endif

1607 1608 1609
/* virtio-balloon-pci */

static Property virtio_balloon_pci_properties[] = {
1610
    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
1611 1612 1613
    DEFINE_PROP_END_OF_LIST(),
};

1614
static void virtio_balloon_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1615 1616 1617 1618 1619 1620 1621 1622 1623 1624
{
    VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);

    if (vpci_dev->class_code != PCI_CLASS_OTHERS &&
        vpci_dev->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */
        vpci_dev->class_code = PCI_CLASS_OTHERS;
    }

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1625
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
1626 1627 1628 1629 1630 1631 1632
}

static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1633
    k->realize = virtio_balloon_pci_realize;
1634
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
    dc->props = virtio_balloon_pci_properties;
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
    pcidev_k->class_id = PCI_CLASS_OTHERS;
}

static void virtio_balloon_pci_instance_init(Object *obj)
{
    VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
1645

1646 1647
    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_BALLOON);
1648 1649 1650 1651 1652
    object_property_add_alias(obj, "guest-stats", OBJECT(&dev->vdev),
                                  "guest-stats", &error_abort);
    object_property_add_alias(obj, "guest-stats-polling-interval",
                              OBJECT(&dev->vdev),
                              "guest-stats-polling-interval", &error_abort);
1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
}

static const TypeInfo virtio_balloon_pci_info = {
    .name          = TYPE_VIRTIO_BALLOON_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VirtIOBalloonPCI),
    .instance_init = virtio_balloon_pci_instance_init,
    .class_init    = virtio_balloon_pci_class_init,
};

1663 1664
/* virtio-serial-pci */

1665
static void virtio_serial_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1666 1667 1668
{
    VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
1669 1670
    DeviceState *proxy = DEVICE(vpci_dev);
    char *bus_name;
1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683

    if (vpci_dev->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
        vpci_dev->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
        vpci_dev->class_code != PCI_CLASS_OTHERS) {        /* qemu-kvm  */
            vpci_dev->class_code = PCI_CLASS_COMMUNICATION_OTHER;
    }

    /* backwards-compatibility with machines that were created with
       DEV_NVECTORS_UNSPECIFIED */
    if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
        vpci_dev->nvectors = dev->vdev.serial.max_virtserial_ports + 1;
    }

1684 1685 1686 1687 1688 1689 1690 1691 1692 1693
    /*
     * For command line compatibility, this sets the virtio-serial-device bus
     * name as before.
     */
    if (proxy->id) {
        bus_name = g_strdup_printf("%s.0", proxy->id);
        virtio_device_set_child_bus_name(VIRTIO_DEVICE(vdev), bus_name);
        g_free(bus_name);
    }

1694
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1695
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
1696 1697 1698 1699 1700 1701
}

static Property virtio_serial_pci_properties[] = {
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
1702
    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
1703 1704 1705 1706 1707 1708 1709 1710
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_serial_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1711
    k->realize = virtio_serial_pci_realize;
1712
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1713 1714 1715 1716 1717 1718 1719 1720 1721 1722
    dc->props = virtio_serial_pci_properties;
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
    pcidev_k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
}

static void virtio_serial_pci_instance_init(Object *obj)
{
    VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(obj);
1723 1724 1725

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_SERIAL);
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735
}

static const TypeInfo virtio_serial_pci_info = {
    .name          = TYPE_VIRTIO_SERIAL_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VirtIOSerialPCI),
    .instance_init = virtio_serial_pci_instance_init,
    .class_init    = virtio_serial_pci_class_init,
};

1736 1737 1738 1739 1740 1741 1742 1743 1744
/* virtio-net-pci */

static Property virtio_net_properties[] = {
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
    DEFINE_PROP_END_OF_LIST(),
};

1745
static void virtio_net_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1746
{
1747
    DeviceState *qdev = DEVICE(vpci_dev);
1748 1749 1750
    VirtIONetPCI *dev = VIRTIO_NET_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);

1751 1752
    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
                                  object_get_typename(OBJECT(qdev)));
1753
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1754
    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767
}

static void virtio_net_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
    VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass);

    k->romfile = "efi-virtio.rom";
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
    k->revision = VIRTIO_PCI_ABI_VERSION;
    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
1768
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
1769
    dc->props = virtio_net_properties;
1770
    vpciklass->realize = virtio_net_pci_realize;
1771 1772 1773 1774 1775
}

static void virtio_net_pci_instance_init(Object *obj)
{
    VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
1776 1777 1778

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_NET);
1779 1780
    object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
                              "bootindex", &error_abort);
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790
}

static const TypeInfo virtio_net_pci_info = {
    .name          = TYPE_VIRTIO_NET_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VirtIONetPCI),
    .instance_init = virtio_net_pci_instance_init,
    .class_init    = virtio_net_pci_class_init,
};

1791 1792 1793 1794 1795 1796
/* virtio-rng-pci */

static Property virtio_rng_pci_properties[] = {
    DEFINE_PROP_END_OF_LIST(),
};

1797
static void virtio_rng_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
1798 1799 1800
{
    VirtIORngPCI *vrng = VIRTIO_RNG_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&vrng->vdev);
1801
    Error *err = NULL;
1802 1803

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1804 1805 1806 1807
    object_property_set_bool(OBJECT(vdev), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
1808 1809 1810
    }

    object_property_set_link(OBJECT(vrng),
1811
                             OBJECT(vrng->vdev.conf.rng), "rng",
1812 1813 1814 1815 1816 1817 1818 1819 1820
                             NULL);
}

static void virtio_rng_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);

1821
    k->realize = virtio_rng_pci_realize;
1822
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833
    dc->props = virtio_rng_pci_properties;

    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_RNG;
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
    pcidev_k->class_id = PCI_CLASS_OTHERS;
}

static void virtio_rng_initfn(Object *obj)
{
    VirtIORngPCI *dev = VIRTIO_RNG_PCI(obj);
1834 1835 1836

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_RNG);
1837 1838
    object_property_add_alias(obj, "rng", OBJECT(&dev->vdev), "rng",
                              &error_abort);
1839 1840 1841 1842 1843 1844 1845 1846 1847 1848
}

static const TypeInfo virtio_rng_pci_info = {
    .name          = TYPE_VIRTIO_RNG_PCI,
    .parent        = TYPE_VIRTIO_PCI,
    .instance_size = sizeof(VirtIORngPCI),
    .instance_init = virtio_rng_initfn,
    .class_init    = virtio_rng_pci_class_init,
};

1849 1850
/* virtio-pci-bus */

1851 1852
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
                               VirtIOPCIProxy *dev)
1853 1854
{
    DeviceState *qdev = DEVICE(dev);
1855 1856
    char virtio_bus_name[] = "virtio-bus";

1857
    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
1858
                        virtio_bus_name);
1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874
}

static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
{
    BusClass *bus_class = BUS_CLASS(klass);
    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
    bus_class->max_dev = 1;
    k->notify = virtio_pci_notify;
    k->save_config = virtio_pci_save_config;
    k->load_config = virtio_pci_load_config;
    k->save_queue = virtio_pci_save_queue;
    k->load_queue = virtio_pci_load_queue;
    k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
    k->set_host_notifier = virtio_pci_set_host_notifier;
    k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
    k->vmstate_change = virtio_pci_vmstate_change;
1875
    k->device_plugged = virtio_pci_device_plugged;
1876
    k->device_unplugged = virtio_pci_device_unplugged;
1877
    k->query_nvectors = virtio_pci_query_nvectors;
1878 1879 1880 1881 1882 1883 1884 1885 1886
}

static const TypeInfo virtio_pci_bus_info = {
    .name          = TYPE_VIRTIO_PCI_BUS,
    .parent        = TYPE_VIRTIO_BUS,
    .instance_size = sizeof(VirtioPCIBusState),
    .class_init    = virtio_pci_bus_class_init,
};

A
Andreas Färber 已提交
1887
static void virtio_pci_register_types(void)
P
Paul Brook 已提交
1888
{
1889
    type_register_static(&virtio_rng_pci_info);
1890
    type_register_static(&virtio_pci_bus_info);
1891
    type_register_static(&virtio_pci_info);
1892
#ifdef CONFIG_VIRTFS
1893
    type_register_static(&virtio_9p_pci_info);
1894
#endif
1895
    type_register_static(&virtio_blk_pci_info);
1896
    type_register_static(&virtio_scsi_pci_info);
1897
    type_register_static(&virtio_balloon_pci_info);
1898
    type_register_static(&virtio_serial_pci_info);
1899
    type_register_static(&virtio_net_pci_info);
1900 1901 1902
#ifdef CONFIG_VHOST_SCSI
    type_register_static(&vhost_scsi_pci_info);
#endif
P
Paul Brook 已提交
1903 1904
}

A
Andreas Färber 已提交
1905
type_init(virtio_pci_register_types)