virtio-pci.c 50.7 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>

P
Paolo Bonzini 已提交
20 21 22 23 24 25
#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"
26
#include "hw/pci/pci.h"
27
#include "qemu/error-report.h"
28 29 30
#include "hw/pci/msi.h"
#include "hw/pci/msix.h"
#include "hw/loader.h"
31
#include "sysemu/kvm.h"
32
#include "sysemu/block-backend.h"
33
#include "virtio-pci.h"
34
#include "qemu/range.h"
P
Paolo Bonzini 已提交
35
#include "hw/virtio/virtio-bus.h"
36
#include "qapi/visitor.h"
P
Paul Brook 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

/* from Linux's linux/virtio_pci.h */

/* A 32-bit r/o bitmask of the features supported by the host */
#define VIRTIO_PCI_HOST_FEATURES        0

/* A 32-bit r/w bitmask of features activated by the guest */
#define VIRTIO_PCI_GUEST_FEATURES       4

/* A 32-bit r/w PFN for the currently selected queue */
#define VIRTIO_PCI_QUEUE_PFN            8

/* A 16-bit r/o queue size for the currently selected queue */
#define VIRTIO_PCI_QUEUE_NUM            12

/* A 16-bit r/w queue selector */
#define VIRTIO_PCI_QUEUE_SEL            14

/* A 16-bit r/w queue notifier */
#define VIRTIO_PCI_QUEUE_NOTIFY         16

/* An 8-bit device status register.  */
#define VIRTIO_PCI_STATUS               18

/* An 8-bit r/o interrupt status register.  Reading the value will return the
 * current contents of the ISR and will also clear it.  This is effectively
 * a read-and-acknowledge. */
#define VIRTIO_PCI_ISR                  19

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
/* MSI-X registers: only enabled if MSI-X is enabled. */
/* A 16-bit vector for configuration changes. */
#define VIRTIO_MSI_CONFIG_VECTOR        20
/* A 16-bit vector for selected queue notifications. */
#define VIRTIO_MSI_QUEUE_VECTOR         22

/* Config space size */
#define VIRTIO_PCI_CONFIG_NOMSI         20
#define VIRTIO_PCI_CONFIG_MSI           24
#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
                                         VIRTIO_PCI_CONFIG_MSI : \
                                         VIRTIO_PCI_CONFIG_NOMSI)

/* The remaining space is defined by each driver as the per-driver
 * configuration space */
#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
                                         VIRTIO_PCI_CONFIG_MSI : \
                                         VIRTIO_PCI_CONFIG_NOMSI)
P
Paul Brook 已提交
84 85 86 87 88

/* How many bits to shift physical queue address written to QUEUE_PFN.
 * 12 is historical, and due to x86 page size. */
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12

89 90 91
/* Flags track per-device state like workarounds for quirks in older guests. */
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)

92 93
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
                               VirtIOPCIProxy *dev);
94

P
Paul Brook 已提交
95
/* virtio device */
96 97 98 99 100
/* 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 已提交
101

102 103 104 105
/* 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 已提交
106
{
107 108 109 110 111 112
    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 已提交
113

114 115
    if (msix_enabled(&proxy->pci_dev))
        msix_notify(&proxy->pci_dev, vector);
P
Paolo Bonzini 已提交
116 117 118 119
    else {
        VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
        pci_set_irq(&proxy->pci_dev, vdev->isr & 1);
    }
P
Paul Brook 已提交
120 121
}

122
static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
123
{
124
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
125 126
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

127 128 129
    pci_device_save(&proxy->pci_dev, f);
    msix_save(&proxy->pci_dev, f);
    if (msix_present(&proxy->pci_dev))
P
Paolo Bonzini 已提交
130
        qemu_put_be16(f, vdev->config_vector);
131 132
}

133
static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
134
{
135
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
136 137
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

138
    if (msix_present(&proxy->pci_dev))
P
Paolo Bonzini 已提交
139
        qemu_put_be16(f, virtio_queue_vector(vdev, n));
140 141
}

142
static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
143
{
144
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
145 146
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

147 148
    int ret;
    ret = pci_device_load(&proxy->pci_dev, f);
149
    if (ret) {
150
        return ret;
151
    }
152
    msix_unuse_all_vectors(&proxy->pci_dev);
153
    msix_load(&proxy->pci_dev, f);
154
    if (msix_present(&proxy->pci_dev)) {
P
Paolo Bonzini 已提交
155
        qemu_get_be16s(f, &vdev->config_vector);
156
    } else {
P
Paolo Bonzini 已提交
157
        vdev->config_vector = VIRTIO_NO_VECTOR;
158
    }
P
Paolo Bonzini 已提交
159 160
    if (vdev->config_vector != VIRTIO_NO_VECTOR) {
        return msix_vector_use(&proxy->pci_dev, vdev->config_vector);
161
    }
162 163 164
    return 0;
}

165
static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
166
{
167
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
168 169
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

170
    uint16_t vector;
171 172 173 174 175
    if (msix_present(&proxy->pci_dev)) {
        qemu_get_be16s(f, &vector);
    } else {
        vector = VIRTIO_NO_VECTOR;
    }
P
Paolo Bonzini 已提交
176
    virtio_queue_set_vector(vdev, n, vector);
177 178 179
    if (vector != VIRTIO_NO_VECTOR) {
        return msix_vector_use(&proxy->pci_dev, vector);
    }
180 181 182
    return 0;
}

183
static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
P
Paolo Bonzini 已提交
184
                                                 int n, bool assign, bool set_handler)
185
{
P
Paolo Bonzini 已提交
186 187
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtQueue *vq = virtio_get_queue(vdev, n);
188
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
A
Avi Kivity 已提交
189 190
    int r = 0;

191 192 193
    if (assign) {
        r = event_notifier_init(notifier, 1);
        if (r < 0) {
194 195
            error_report("%s: unable to init event notifier: %d",
                         __func__, r);
196 197
            return r;
        }
P
Paolo Bonzini 已提交
198
        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
A
Avi Kivity 已提交
199
        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
200
                                  true, n, notifier);
201
    } else {
A
Avi Kivity 已提交
202
        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
203
                                  true, n, notifier);
P
Paolo Bonzini 已提交
204
        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
205 206 207 208 209
        event_notifier_cleanup(notifier);
    }
    return r;
}

210
static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
211
{
P
Paolo Bonzini 已提交
212
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
213 214 215 216 217
    int n, r;

    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
        proxy->ioeventfd_disabled ||
        proxy->ioeventfd_started) {
218
        return;
219 220 221
    }

    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
P
Paolo Bonzini 已提交
222
        if (!virtio_queue_get_num(vdev, n)) {
223 224 225
            continue;
        }

P
Paolo Bonzini 已提交
226
        r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
227 228 229 230 231
        if (r < 0) {
            goto assign_error;
        }
    }
    proxy->ioeventfd_started = true;
232
    return;
233 234 235

assign_error:
    while (--n >= 0) {
P
Paolo Bonzini 已提交
236
        if (!virtio_queue_get_num(vdev, n)) {
237 238 239
            continue;
        }

P
Paolo Bonzini 已提交
240
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
241
        assert(r >= 0);
242 243
    }
    proxy->ioeventfd_started = false;
244
    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
245 246
}

247
static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
248
{
P
Paolo Bonzini 已提交
249
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
250
    int r;
251 252 253
    int n;

    if (!proxy->ioeventfd_started) {
254
        return;
255 256 257
    }

    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
P
Paolo Bonzini 已提交
258
        if (!virtio_queue_get_num(vdev, n)) {
259 260 261
            continue;
        }

P
Paolo Bonzini 已提交
262
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
263
        assert(r >= 0);
264 265 266 267
    }
    proxy->ioeventfd_started = false;
}

P
Paul Brook 已提交
268 269 270
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
{
    VirtIOPCIProxy *proxy = opaque;
P
Paolo Bonzini 已提交
271
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
A
Avi Kivity 已提交
272
    hwaddr pa;
P
Paul Brook 已提交
273 274 275

    switch (addr) {
    case VIRTIO_PCI_GUEST_FEATURES:
276 277 278 279
        /* 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);
        }
280
        virtio_set_features(vdev, val);
P
Paul Brook 已提交
281 282
        break;
    case VIRTIO_PCI_QUEUE_PFN:
A
Avi Kivity 已提交
283
        pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
284
        if (pa == 0) {
285
            virtio_pci_stop_ioeventfd(proxy);
P
Paolo Bonzini 已提交
286
            virtio_reset(vdev);
287 288
            msix_unuse_all_vectors(&proxy->pci_dev);
        }
289 290
        else
            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
P
Paul Brook 已提交
291 292 293 294 295 296
        break;
    case VIRTIO_PCI_QUEUE_SEL:
        if (val < VIRTIO_PCI_QUEUE_MAX)
            vdev->queue_sel = val;
        break;
    case VIRTIO_PCI_QUEUE_NOTIFY:
297 298 299
        if (val < VIRTIO_PCI_QUEUE_MAX) {
            virtio_queue_notify(vdev, val);
        }
P
Paul Brook 已提交
300 301
        break;
    case VIRTIO_PCI_STATUS:
302 303 304 305
        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
            virtio_pci_stop_ioeventfd(proxy);
        }

306
        virtio_set_status(vdev, val & 0xFF);
307 308 309 310 311

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

312
        if (vdev->status == 0) {
P
Paolo Bonzini 已提交
313
            virtio_reset(vdev);
314 315
            msix_unuse_all_vectors(&proxy->pci_dev);
        }
316

317 318 319 320 321 322 323 324 325
        /* 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);
        }
326 327 328 329 330 331 332 333

        /* Linux before 2.6.34 sets the device as OK without enabling
           the PCI device bus master bit. In this case we need to disable
           some safety checks. */
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
        }
P
Paul Brook 已提交
334
        break;
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
    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:
351 352
        error_report("%s: unexpected address 0x%x value 0x%x",
                     __func__, addr, val);
353
        break;
P
Paul Brook 已提交
354 355 356
    }
}

357
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
P
Paul Brook 已提交
358
{
P
Paolo Bonzini 已提交
359
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
P
Paul Brook 已提交
360 361 362 363
    uint32_t ret = 0xFFFFFFFF;

    switch (addr) {
    case VIRTIO_PCI_HOST_FEATURES:
364
        ret = proxy->host_features;
P
Paul Brook 已提交
365 366
        break;
    case VIRTIO_PCI_GUEST_FEATURES:
367
        ret = vdev->guest_features;
P
Paul Brook 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
        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;
386
        pci_irq_deassert(&proxy->pci_dev);
P
Paul Brook 已提交
387
        break;
388 389 390 391 392 393
    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 已提交
394 395 396 397 398 399 400
    default:
        break;
    }

    return ret;
}

401 402
static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
                                       unsigned size)
P
Paul Brook 已提交
403 404
{
    VirtIOPCIProxy *proxy = opaque;
P
Paolo Bonzini 已提交
405
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
406
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
407
    uint64_t val = 0;
408
    if (addr < config) {
409
        return virtio_ioport_read(proxy, addr);
410 411
    }
    addr -= config;
P
Paul Brook 已提交
412

413 414
    switch (size) {
    case 1:
P
Paolo Bonzini 已提交
415
        val = virtio_config_readb(vdev, addr);
416 417
        break;
    case 2:
P
Paolo Bonzini 已提交
418
        val = virtio_config_readw(vdev, addr);
419
        if (virtio_is_big_endian(vdev)) {
420 421
            val = bswap16(val);
        }
422 423
        break;
    case 4:
P
Paolo Bonzini 已提交
424
        val = virtio_config_readl(vdev, addr);
425
        if (virtio_is_big_endian(vdev)) {
426 427
            val = bswap32(val);
        }
428
        break;
429
    }
430
    return val;
P
Paul Brook 已提交
431 432
}

433 434
static void virtio_pci_config_write(void *opaque, hwaddr addr,
                                    uint64_t val, unsigned size)
P
Paul Brook 已提交
435 436
{
    VirtIOPCIProxy *proxy = opaque;
437
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
P
Paolo Bonzini 已提交
438
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
439 440 441 442 443
    if (addr < config) {
        virtio_ioport_write(proxy, addr, val);
        return;
    }
    addr -= config;
444 445 446 447 448 449
    /*
     * Virtio-PCI is odd. Ioports are LE but config space is target native
     * endian.
     */
    switch (size) {
    case 1:
P
Paolo Bonzini 已提交
450
        virtio_config_writeb(vdev, addr, val);
451 452
        break;
    case 2:
453
        if (virtio_is_big_endian(vdev)) {
454 455
            val = bswap16(val);
        }
P
Paolo Bonzini 已提交
456
        virtio_config_writew(vdev, addr, val);
457 458
        break;
    case 4:
459
        if (virtio_is_big_endian(vdev)) {
460 461
            val = bswap32(val);
        }
P
Paolo Bonzini 已提交
462
        virtio_config_writel(vdev, addr, val);
463
        break;
464
    }
P
Paul Brook 已提交
465 466
}

A
Avi Kivity 已提交
467
static const MemoryRegionOps virtio_pci_config_ops = {
468 469 470 471 472 473
    .read = virtio_pci_config_read,
    .write = virtio_pci_config_write,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 4,
    },
474
    .endianness = DEVICE_LITTLE_ENDIAN,
A
Avi Kivity 已提交
475
};
476 477 478 479

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

483 484 485 486
    pci_default_write_config(pci_dev, address, val, len);

    if (range_covers_byte(address, len, PCI_COMMAND) &&
        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
487
        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
488
        virtio_pci_stop_ioeventfd(proxy);
489
        virtio_set_status(vdev, vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
490
    }
P
Paul Brook 已提交
491 492
}

493
static unsigned virtio_pci_get_features(DeviceState *d)
494
{
495
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
496
    return proxy->host_features;
497 498
}

499 500 501 502 503 504
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];
505
    int ret;
506 507 508 509 510 511 512 513 514 515 516 517 518 519

    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)
520 521 522 523 524 525 526
{
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
    if (--irqfd->users == 0) {
        kvm_irqchip_release_virq(kvm_state, irqfd->virq);
    }
}

527 528 529 530 531
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 已提交
532 533
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
534 535
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
    int ret;
536
    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, NULL, irqfd->virq);
537 538 539 540 541 542
    return ret;
}

static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
                                      unsigned int queue_no,
                                      unsigned int vector)
543
{
P
Paolo Bonzini 已提交
544 545
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
546
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
547
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
548
    int ret;
549

J
Jan Kiszka 已提交
550
    ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq);
551
    assert(ret == 0);
552
}
553

554 555 556
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
{
    PCIDevice *dev = &proxy->pci_dev;
P
Paolo Bonzini 已提交
557
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
558
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
    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;
575
        }
576 577 578
        /* If guest supports masking, set up irqfd now.
         * Otherwise, delay until unmasked in the frontend.
         */
579
        if (k->guest_notifier_mask) {
580 581 582 583 584 585
            ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
            if (ret < 0) {
                kvm_virtio_pci_vq_vector_release(proxy, vector);
                goto undo;
            }
        }
586 587
    }
    return 0;
588 589 590 591 592 593 594

undo:
    while (--queue_no >= 0) {
        vector = virtio_queue_vector(vdev, queue_no);
        if (vector >= msix_nr_vectors_allocated(dev)) {
            continue;
        }
595
        if (k->guest_notifier_mask) {
596
            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
597
        }
598 599 600
        kvm_virtio_pci_vq_vector_release(proxy, vector);
    }
    return ret;
601 602
}

603 604 605
static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
{
    PCIDevice *dev = &proxy->pci_dev;
P
Paolo Bonzini 已提交
606
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
607 608
    unsigned int vector;
    int queue_no;
609
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
610 611 612 613 614 615 616 617 618

    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;
        }
619 620 621
        /* If guest supports masking, clean up irqfd now.
         * Otherwise, it was cleaned when masked in the frontend.
         */
622
        if (k->guest_notifier_mask) {
623
            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
624
        }
625 626 627 628
        kvm_virtio_pci_vq_vector_release(proxy, vector);
    }
}

629 630 631 632
static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
                                       unsigned int queue_no,
                                       unsigned int vector,
                                       MSIMessage msg)
633
{
P
Paolo Bonzini 已提交
634 635 636
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
    VirtQueue *vq = virtio_get_queue(vdev, queue_no);
637
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
638
    VirtIOIRQFD *irqfd;
639
    int ret = 0;
640

641 642 643 644 645 646 647
    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;
            }
648 649 650
        }
    }

651 652 653
    /* If guest supports masking, irqfd is already setup, unmask it.
     * Otherwise, set it up now.
     */
654
    if (k->guest_notifier_mask) {
P
Paolo Bonzini 已提交
655
        k->guest_notifier_mask(vdev, queue_no, false);
656
        /* Test after unmasking to avoid losing events. */
657
        if (k->guest_notifier_pending &&
P
Paolo Bonzini 已提交
658
            k->guest_notifier_pending(vdev, queue_no)) {
659 660 661 662
            event_notifier_set(n);
        }
    } else {
        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
663
    }
664
    return ret;
665 666
}

667
static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
668 669 670
                                             unsigned int queue_no,
                                             unsigned int vector)
{
P
Paolo Bonzini 已提交
671 672
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
673

674 675 676
    /* If guest supports masking, keep irqfd but mask it.
     * Otherwise, clean it up now.
     */ 
677
    if (k->guest_notifier_mask) {
P
Paolo Bonzini 已提交
678
        k->guest_notifier_mask(vdev, queue_no, true);
679
    } else {
680
        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
681
    }
682 683
}

684 685
static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
                                    MSIMessage msg)
686 687
{
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
P
Paolo Bonzini 已提交
688
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
689 690
    int ret, queue_no;

691
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
692 693 694 695 696 697
        if (!virtio_queue_get_num(vdev, queue_no)) {
            break;
        }
        if (virtio_queue_vector(vdev, queue_no) != vector) {
            continue;
        }
698
        ret = virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg);
699 700 701 702 703 704 705 706 707 708 709
        if (ret < 0) {
            goto undo;
        }
    }
    return 0;

undo:
    while (--queue_no >= 0) {
        if (virtio_queue_vector(vdev, queue_no) != vector) {
            continue;
        }
710
        virtio_pci_vq_vector_mask(proxy, queue_no, vector);
711 712 713 714
    }
    return ret;
}

715
static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
716 717
{
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
P
Paolo Bonzini 已提交
718
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
719 720
    int queue_no;

721
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
722 723 724 725 726 727
        if (!virtio_queue_get_num(vdev, queue_no)) {
            break;
        }
        if (virtio_queue_vector(vdev, queue_no) != vector) {
            continue;
        }
728
        virtio_pci_vq_vector_mask(proxy, queue_no, vector);
729 730 731
    }
}

732 733 734
static void virtio_pci_vector_poll(PCIDevice *dev,
                                   unsigned int vector_start,
                                   unsigned int vector_end)
735 736
{
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
P
Paolo Bonzini 已提交
737
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
738
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
739 740 741 742 743
    int queue_no;
    unsigned int vector;
    EventNotifier *notifier;
    VirtQueue *vq;

744
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
745 746 747 748 749 750 751 752 753 754
        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);
755 756
        if (k->guest_notifier_pending) {
            if (k->guest_notifier_pending(vdev, queue_no)) {
757 758 759
                msix_set_pending(dev, vector);
            }
        } else if (event_notifier_test_and_clear(notifier)) {
760 761 762 763 764 765 766
            msix_set_pending(dev, vector);
        }
    }
}

static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
                                         bool with_irqfd)
767
{
768
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
769 770 771
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);
    VirtQueue *vq = virtio_get_queue(vdev, n);
772 773 774 775 776 777 778
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);

    if (assign) {
        int r = event_notifier_init(notifier, 0);
        if (r < 0) {
            return r;
        }
779
        virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
780
    } else {
781
        virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
782 783 784
        event_notifier_cleanup(notifier);
    }

785
    if (!msix_enabled(&proxy->pci_dev) && vdc->guest_notifier_mask) {
P
Paolo Bonzini 已提交
786
        vdc->guest_notifier_mask(vdev, n, !assign);
787 788
    }

789 790 791
    return 0;
}

792
static bool virtio_pci_query_guest_notifiers(DeviceState *d)
793
{
794
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
795 796 797
    return msix_enabled(&proxy->pci_dev);
}

798
static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
799
{
800
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
801
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
802
    VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev);
803
    int r, n;
804 805
    bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
        kvm_msi_via_irqfd_enabled();
806

807 808 809 810 811 812 813 814 815
    nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX);

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

    proxy->nvqs_with_notifiers = nvqs;

816
    /* Must unset vector notifier while guest notifier is still assigned */
817
    if ((proxy->vector_irqfd || k->guest_notifier_mask) && !assign) {
818
        msix_unset_vector_notifiers(&proxy->pci_dev);
819 820 821 822 823
        if (proxy->vector_irqfd) {
            kvm_virtio_pci_vector_release(proxy, nvqs);
            g_free(proxy->vector_irqfd);
            proxy->vector_irqfd = NULL;
        }
824 825
    }

826
    for (n = 0; n < nvqs; n++) {
827 828 829 830
        if (!virtio_queue_get_num(vdev, n)) {
            break;
        }

831
        r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd);
832 833 834 835 836
        if (r < 0) {
            goto assign_error;
        }
    }

837
    /* Must set vector notifier after guest notifier has been assigned */
838
    if ((with_irqfd || k->guest_notifier_mask) && assign) {
839 840 841 842 843 844 845 846
        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;
            }
847
        }
848
        r = msix_set_vector_notifiers(&proxy->pci_dev,
849 850 851
                                      virtio_pci_vector_unmask,
                                      virtio_pci_vector_mask,
                                      virtio_pci_vector_poll);
852
        if (r < 0) {
853
            goto notifiers_error;
854 855 856
        }
    }

857 858
    return 0;

859
notifiers_error:
860 861 862 863
    if (with_irqfd) {
        assert(assign);
        kvm_virtio_pci_vector_release(proxy, nvqs);
    }
864

865 866
assign_error:
    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
867
    assert(assign);
868
    while (--n >= 0) {
869
        virtio_pci_set_guest_notifier(d, n, !assign, with_irqfd);
870 871 872 873
    }
    return r;
}

874
static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
875
{
876
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
877 878 879 880 881

    /* 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;
882
    if (assign) {
883 884 885 886 887 888
        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 已提交
889
    return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
890 891
}

892
static void virtio_pci_vmstate_change(DeviceState *d, bool running)
893
{
894
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
P
Paolo Bonzini 已提交
895
    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
896 897

    if (running) {
898 899 900 901 902
        /* Try to find out if the guest has bus master disabled, but is
           in ready state. Then we have a buggy guest OS. */
        if ((vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
903
        }
904
        virtio_pci_start_ioeventfd(proxy);
905
    } else {
906
        virtio_pci_stop_ioeventfd(proxy);
907 908 909
    }
}

910
#ifdef CONFIG_VIRTFS
911
static int virtio_9p_init_pci(VirtIOPCIProxy *vpci_dev)
912
{
913 914
    V9fsPCIState *dev = VIRTIO_9P_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
915

916 917 918 919
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
920 921 922
    return 0;
}

923 924 925
static Property virtio_9p_pci_properties[] = {
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
926 927 928 929
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
    DEFINE_PROP_END_OF_LIST(),
};

930
static void virtio_9p_pci_class_init(ObjectClass *klass, void *data)
931 932
{
    DeviceClass *dc = DEVICE_CLASS(klass);
933 934
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
935 936

    k->init = virtio_9p_init_pci;
937 938 939 940
    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;
941
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
942
    dc->props = virtio_9p_pci_properties;
943 944
}

945 946 947
static void virtio_9p_pci_instance_init(Object *obj)
{
    V9fsPCIState *dev = VIRTIO_9P_PCI(obj);
948 949 950

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_9P);
951 952 953 954 955 956 957 958
}

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,
959
};
960
#endif /* CONFIG_VIRTFS */
961

962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
/*
 * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
 */

/* This is called by virtio-bus just after the device is plugged. */
static void virtio_pci_device_plugged(DeviceState *d)
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
    VirtioBusState *bus = &proxy->bus;
    uint8_t *config;
    uint32_t size;

    config = proxy->pci_dev.config;
    if (proxy->class_code) {
        pci_config_set_class(config, proxy->class_code);
    }
    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));
    config[PCI_INTERRUPT_PIN] = 1;

    if (proxy->nvectors &&
        msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors, 1)) {
985 986
        error_report("unable to init msix vectors to %" PRIu32,
                     proxy->nvectors);
987 988 989 990 991 992 993 994 995 996 997
        proxy->nvectors = 0;
    }

    proxy->pci_dev.config_write = virtio_write_config;

    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev)
         + virtio_bus_get_vdev_config_len(bus);
    if (size & (size - 1)) {
        size = 1 << qemu_fls(size);
    }

998 999
    memory_region_init_io(&proxy->bar, OBJECT(proxy), &virtio_pci_config_ops,
                          proxy, "virtio-pci", size);
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
                     &proxy->bar);

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

    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
    proxy->host_features = virtio_bus_get_vdev_features(bus,
                                                      proxy->host_features);
}

1013 1014 1015 1016 1017 1018 1019
static void virtio_pci_device_unplugged(DeviceState *d)
{
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);

    virtio_pci_stop_ioeventfd(proxy);
}

1020 1021 1022 1023
static int virtio_pci_init(PCIDevice *pci_dev)
{
    VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
    VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
1024
    virtio_pci_bus_new(&dev->bus, sizeof(dev->bus), dev);
1025 1026 1027 1028 1029 1030 1031 1032
    if (k->init != NULL) {
        return k->init(dev);
    }
    return 0;
}

static void virtio_pci_exit(PCIDevice *pci_dev)
{
1033
    msix_uninit_exclusive_bar(pci_dev);
1034 1035
}

1036
static void virtio_pci_reset(DeviceState *qdev)
1037 1038 1039 1040 1041 1042
{
    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);
1043
    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
1044 1045
}

1046 1047 1048 1049 1050
static Property virtio_pci_properties[] = {
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

1051 1052 1053 1054 1055
static void virtio_pci_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

1056
    dc->props = virtio_pci_properties;
1057 1058 1059 1060 1061
    k->init = virtio_pci_init;
    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;
1062
    dc->reset = virtio_pci_reset;
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
}

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,
};

1074 1075 1076
/* virtio-blk-pci */

static Property virtio_blk_pci_properties[] = {
1077
    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100
    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(),
};

static int virtio_blk_pci_init(VirtIOPCIProxy *vpci_dev)
{
    VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
    return 0;
}

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);

1101
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112
    dc->props = virtio_blk_pci_properties;
    k->init = virtio_blk_pci_init;
    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);
1113 1114 1115

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_BLK);
1116 1117
    object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev),"iothread",
                              &error_abort);
1118 1119
    object_property_add_alias(obj, "bootindex", OBJECT(&dev->vdev),
                              "bootindex", &error_abort);
1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
}

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,
};

1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
/* 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_VIRTIO_SCSI_FEATURES(VirtIOPCIProxy, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

static int virtio_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev)
{
    VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
1145
    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev);
1146 1147
    DeviceState *proxy = DEVICE(vpci_dev);
    char *bus_name;
1148 1149

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

1153 1154 1155 1156 1157 1158 1159 1160 1161 1162
    /*
     * 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);
    }

1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
    return 0;
}

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);
    k->init = virtio_scsi_pci_init_pci;
1176
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1177 1178 1179 1180 1181 1182 1183 1184 1185 1186
    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);
1187 1188 1189

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_SCSI);
1190 1191
    object_property_add_alias(obj, "iothread", OBJECT(&dev->vdev), "iothread",
                              &error_abort);
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201
}

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,
};

1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
/* 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(),
};

static int vhost_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev)
{
    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));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
    return 0;
}

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);
    k->init = vhost_scsi_pci_init_pci;
1234
    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244
    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);
1245 1246 1247

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VHOST_SCSI);
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
}

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

1259 1260
/* virtio-balloon-pci */

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
static void balloon_pci_stats_get_all(Object *obj, struct Visitor *v,
                                      void *opaque, const char *name,
                                      Error **errp)
{
    VirtIOBalloonPCI *dev = opaque;
    object_property_get(OBJECT(&dev->vdev), v, "guest-stats", errp);
}

static void balloon_pci_stats_get_poll_interval(Object *obj, struct Visitor *v,
                                                void *opaque, const char *name,
                                                Error **errp)
{
    VirtIOBalloonPCI *dev = opaque;
    object_property_get(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
                        errp);
}

static void balloon_pci_stats_set_poll_interval(Object *obj, struct Visitor *v,
                                                void *opaque, const char *name,
                                                Error **errp)
{
    VirtIOBalloonPCI *dev = opaque;
    object_property_set(OBJECT(&dev->vdev), v, "guest-stats-polling-interval",
                        errp);
}

1287
static Property virtio_balloon_pci_properties[] = {
1288
    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
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
    DEFINE_PROP_END_OF_LIST(),
};

static int virtio_balloon_pci_init(VirtIOPCIProxy *vpci_dev)
{
    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));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
    return 0;
}

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);
    k->init = virtio_balloon_pci_init;
1315
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325
    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);
1326
    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_BALLOON);
1327
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
1328
    object_unref(OBJECT(&dev->vdev));
1329 1330 1331 1332 1333 1334 1335 1336
    object_property_add(obj, "guest-stats", "guest statistics",
                        balloon_pci_stats_get_all, NULL, NULL, dev,
                        NULL);

    object_property_add(obj, "guest-stats-polling-interval", "int",
                        balloon_pci_stats_get_poll_interval,
                        balloon_pci_stats_set_poll_interval,
                        NULL, dev, NULL);
1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
}

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,
};

1347 1348 1349 1350 1351 1352
/* virtio-serial-pci */

static int virtio_serial_pci_init(VirtIOPCIProxy *vpci_dev)
{
    VirtIOSerialPCI *dev = VIRTIO_SERIAL_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);
1353 1354
    DeviceState *proxy = DEVICE(vpci_dev);
    char *bus_name;
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367

    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;
    }

1368 1369 1370 1371 1372 1373 1374 1375 1376 1377
    /*
     * 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);
    }

1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
    return 0;
}

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),
1389
    DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0),
1390 1391 1392 1393 1394 1395 1396 1397 1398
    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);
    k->init = virtio_serial_pci_init;
1399
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409
    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);
1410 1411 1412

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_SERIAL);
1413 1414 1415 1416 1417 1418 1419 1420 1421 1422
}

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,
};

1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
/* 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_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
    DEFINE_PROP_END_OF_LIST(),
};

static int virtio_net_pci_init(VirtIOPCIProxy *vpci_dev)
{
1435
    DeviceState *qdev = DEVICE(vpci_dev);
1436 1437 1438 1439
    VirtIONetPCI *dev = VIRTIO_NET_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&dev->vdev);

    virtio_net_set_config_size(&dev->vdev, vpci_dev->host_features);
1440 1441
    virtio_net_set_netclient_name(&dev->vdev, qdev->id,
                                  object_get_typename(OBJECT(qdev)));
1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }
    return 0;
}

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;
1460
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
1461 1462 1463 1464 1465 1466 1467
    dc->props = virtio_net_properties;
    vpciklass->init = virtio_net_pci_init;
}

static void virtio_net_pci_instance_init(Object *obj)
{
    VirtIONetPCI *dev = VIRTIO_NET_PCI(obj);
1468 1469 1470

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

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,
};

1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499
/* virtio-rng-pci */

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

static int virtio_rng_pci_init(VirtIOPCIProxy *vpci_dev)
{
    VirtIORngPCI *vrng = VIRTIO_RNG_PCI(vpci_dev);
    DeviceState *vdev = DEVICE(&vrng->vdev);

    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
    if (qdev_init(vdev) < 0) {
        return -1;
    }

    object_property_set_link(OBJECT(vrng),
1500
                             OBJECT(vrng->vdev.conf.rng), "rng",
1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512
                             NULL);

    return 0;
}

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);

    k->init = virtio_rng_pci_init;
1513
    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524
    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);
1525 1526 1527

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_RNG);
1528 1529
    object_property_add_alias(obj, "rng", OBJECT(&dev->vdev), "rng",
                              &error_abort);
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539
}

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,
};

1540 1541
/* virtio-pci-bus */

1542 1543
static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size,
                               VirtIOPCIProxy *dev)
1544 1545
{
    DeviceState *qdev = DEVICE(dev);
1546 1547
    char virtio_bus_name[] = "virtio-bus";

1548
    qbus_create_inplace(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev,
1549
                        virtio_bus_name);
1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566
}

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->get_features = virtio_pci_get_features;
    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;
1567
    k->device_plugged = virtio_pci_device_plugged;
1568
    k->device_unplugged = virtio_pci_device_unplugged;
1569 1570 1571 1572 1573 1574 1575 1576 1577
}

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 已提交
1578
static void virtio_pci_register_types(void)
P
Paul Brook 已提交
1579
{
1580
    type_register_static(&virtio_rng_pci_info);
1581
    type_register_static(&virtio_pci_bus_info);
1582
    type_register_static(&virtio_pci_info);
1583
#ifdef CONFIG_VIRTFS
1584
    type_register_static(&virtio_9p_pci_info);
1585
#endif
1586
    type_register_static(&virtio_blk_pci_info);
1587
    type_register_static(&virtio_scsi_pci_info);
1588
    type_register_static(&virtio_balloon_pci_info);
1589
    type_register_static(&virtio_serial_pci_info);
1590
    type_register_static(&virtio_net_pci_info);
1591 1592 1593
#ifdef CONFIG_VHOST_SCSI
    type_register_static(&vhost_scsi_pci_info);
#endif
P
Paul Brook 已提交
1594 1595
}

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