Statistics
| Branch: | Revision:

root / hw / virtio-pci.c @ 5f8ae8e2

History | View | Annotate | Download (32.1 kB)

1 53c25cea Paul Brook
/*
2 53c25cea Paul Brook
 * Virtio PCI Bindings
3 53c25cea Paul Brook
 *
4 53c25cea Paul Brook
 * Copyright IBM, Corp. 2007
5 53c25cea Paul Brook
 * Copyright (c) 2009 CodeSourcery
6 53c25cea Paul Brook
 *
7 53c25cea Paul Brook
 * Authors:
8 53c25cea Paul Brook
 *  Anthony Liguori   <aliguori@us.ibm.com>
9 53c25cea Paul Brook
 *  Paul Brook        <paul@codesourcery.com>
10 53c25cea Paul Brook
 *
11 53c25cea Paul Brook
 * This work is licensed under the terms of the GNU GPL, version 2.  See
12 53c25cea Paul Brook
 * the COPYING file in the top-level directory.
13 53c25cea Paul Brook
 *
14 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
15 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
16 53c25cea Paul Brook
 */
17 53c25cea Paul Brook
18 53c25cea Paul Brook
#include <inttypes.h>
19 53c25cea Paul Brook
20 53c25cea Paul Brook
#include "virtio.h"
21 8172539d Michael S. Tsirkin
#include "virtio-blk.h"
22 8172539d Michael S. Tsirkin
#include "virtio-net.h"
23 6b331efb Amit Shah
#include "virtio-serial.h"
24 973abc7f Stefan Hajnoczi
#include "virtio-scsi.h"
25 53c25cea Paul Brook
#include "pci.h"
26 2f792016 Markus Armbruster
#include "qemu-error.h"
27 7d37d351 Jan Kiszka
#include "msi.h"
28 aba800a3 Michael S. Tsirkin
#include "msix.h"
29 a1e0fea5 Gerd Hoffmann
#include "net.h"
30 97b15621 Gerd Hoffmann
#include "loader.h"
31 ade80dc8 Michael S. Tsirkin
#include "kvm.h"
32 2446333c Blue Swirl
#include "blockdev.h"
33 9fe1ebeb Aneesh Kumar K.V
#include "virtio-pci.h"
34 1129714f Michael S. Tsirkin
#include "range.h"
35 53c25cea Paul Brook
36 53c25cea Paul Brook
/* from Linux's linux/virtio_pci.h */
37 53c25cea Paul Brook
38 53c25cea Paul Brook
/* A 32-bit r/o bitmask of the features supported by the host */
39 53c25cea Paul Brook
#define VIRTIO_PCI_HOST_FEATURES        0
40 53c25cea Paul Brook
41 53c25cea Paul Brook
/* A 32-bit r/w bitmask of features activated by the guest */
42 53c25cea Paul Brook
#define VIRTIO_PCI_GUEST_FEATURES       4
43 53c25cea Paul Brook
44 53c25cea Paul Brook
/* A 32-bit r/w PFN for the currently selected queue */
45 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_PFN            8
46 53c25cea Paul Brook
47 53c25cea Paul Brook
/* A 16-bit r/o queue size for the currently selected queue */
48 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NUM            12
49 53c25cea Paul Brook
50 53c25cea Paul Brook
/* A 16-bit r/w queue selector */
51 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_SEL            14
52 53c25cea Paul Brook
53 53c25cea Paul Brook
/* A 16-bit r/w queue notifier */
54 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NOTIFY         16
55 53c25cea Paul Brook
56 53c25cea Paul Brook
/* An 8-bit device status register.  */
57 53c25cea Paul Brook
#define VIRTIO_PCI_STATUS               18
58 53c25cea Paul Brook
59 53c25cea Paul Brook
/* An 8-bit r/o interrupt status register.  Reading the value will return the
60 53c25cea Paul Brook
 * current contents of the ISR and will also clear it.  This is effectively
61 53c25cea Paul Brook
 * a read-and-acknowledge. */
62 53c25cea Paul Brook
#define VIRTIO_PCI_ISR                  19
63 53c25cea Paul Brook
64 aba800a3 Michael S. Tsirkin
/* MSI-X registers: only enabled if MSI-X is enabled. */
65 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for configuration changes. */
66 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_CONFIG_VECTOR        20
67 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for selected queue notifications. */
68 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_QUEUE_VECTOR         22
69 aba800a3 Michael S. Tsirkin
70 aba800a3 Michael S. Tsirkin
/* Config space size */
71 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_NOMSI         20
72 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_MSI           24
73 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
74 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
75 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
76 aba800a3 Michael S. Tsirkin
77 aba800a3 Michael S. Tsirkin
/* The remaining space is defined by each driver as the per-driver
78 aba800a3 Michael S. Tsirkin
 * configuration space */
79 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
80 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
81 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
82 53c25cea Paul Brook
83 53c25cea Paul Brook
/* How many bits to shift physical queue address written to QUEUE_PFN.
84 53c25cea Paul Brook
 * 12 is historical, and due to x86 page size. */
85 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
86 53c25cea Paul Brook
87 3dbca8e6 Stefan Hajnoczi
/* Flags track per-device state like workarounds for quirks in older guests. */
88 3dbca8e6 Stefan Hajnoczi
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
89 c81131db Alexander Graf
90 53c25cea Paul Brook
/* QEMU doesn't strictly need write barriers since everything runs in
91 53c25cea Paul Brook
 * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
92 53c25cea Paul Brook
 * KVM or if kqemu gets SMP support.
93 53c25cea Paul Brook
 */
94 53c25cea Paul Brook
#define wmb() do { } while (0)
95 53c25cea Paul Brook
96 82afa586 Benjamin Herrenschmidt
/* HACK for virtio to determine if it's running a big endian guest */
97 82afa586 Benjamin Herrenschmidt
bool virtio_is_big_endian(void);
98 82afa586 Benjamin Herrenschmidt
99 53c25cea Paul Brook
/* virtio device */
100 53c25cea Paul Brook
101 7055e687 Michael S. Tsirkin
static void virtio_pci_notify(void *opaque, uint16_t vector)
102 53c25cea Paul Brook
{
103 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
104 aba800a3 Michael S. Tsirkin
    if (msix_enabled(&proxy->pci_dev))
105 aba800a3 Michael S. Tsirkin
        msix_notify(&proxy->pci_dev, vector);
106 aba800a3 Michael S. Tsirkin
    else
107 aba800a3 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
108 53c25cea Paul Brook
}
109 53c25cea Paul Brook
110 ff24bd58 Michael S. Tsirkin
static void virtio_pci_save_config(void * opaque, QEMUFile *f)
111 ff24bd58 Michael S. Tsirkin
{
112 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
113 ff24bd58 Michael S. Tsirkin
    pci_device_save(&proxy->pci_dev, f);
114 ff24bd58 Michael S. Tsirkin
    msix_save(&proxy->pci_dev, f);
115 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
116 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, proxy->vdev->config_vector);
117 ff24bd58 Michael S. Tsirkin
}
118 ff24bd58 Michael S. Tsirkin
119 ff24bd58 Michael S. Tsirkin
static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
120 ff24bd58 Michael S. Tsirkin
{
121 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
122 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
123 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
124 ff24bd58 Michael S. Tsirkin
}
125 ff24bd58 Michael S. Tsirkin
126 ff24bd58 Michael S. Tsirkin
static int virtio_pci_load_config(void * opaque, QEMUFile *f)
127 ff24bd58 Michael S. Tsirkin
{
128 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
129 ff24bd58 Michael S. Tsirkin
    int ret;
130 ff24bd58 Michael S. Tsirkin
    ret = pci_device_load(&proxy->pci_dev, f);
131 e6da7680 Michael S. Tsirkin
    if (ret) {
132 ff24bd58 Michael S. Tsirkin
        return ret;
133 e6da7680 Michael S. Tsirkin
    }
134 3cac001e Michael S. Tsirkin
    msix_unuse_all_vectors(&proxy->pci_dev);
135 ff24bd58 Michael S. Tsirkin
    msix_load(&proxy->pci_dev, f);
136 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
137 ff24bd58 Michael S. Tsirkin
        qemu_get_be16s(f, &proxy->vdev->config_vector);
138 e6da7680 Michael S. Tsirkin
    } else {
139 e6da7680 Michael S. Tsirkin
        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
140 e6da7680 Michael S. Tsirkin
    }
141 e6da7680 Michael S. Tsirkin
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
142 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
143 e6da7680 Michael S. Tsirkin
    }
144 ff24bd58 Michael S. Tsirkin
    return 0;
145 ff24bd58 Michael S. Tsirkin
}
146 ff24bd58 Michael S. Tsirkin
147 ff24bd58 Michael S. Tsirkin
static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
148 ff24bd58 Michael S. Tsirkin
{
149 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
150 ff24bd58 Michael S. Tsirkin
    uint16_t vector;
151 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
152 e6da7680 Michael S. Tsirkin
        qemu_get_be16s(f, &vector);
153 e6da7680 Michael S. Tsirkin
    } else {
154 e6da7680 Michael S. Tsirkin
        vector = VIRTIO_NO_VECTOR;
155 e6da7680 Michael S. Tsirkin
    }
156 ff24bd58 Michael S. Tsirkin
    virtio_queue_set_vector(proxy->vdev, n, vector);
157 e6da7680 Michael S. Tsirkin
    if (vector != VIRTIO_NO_VECTOR) {
158 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, vector);
159 e6da7680 Michael S. Tsirkin
    }
160 ff24bd58 Michael S. Tsirkin
    return 0;
161 ff24bd58 Michael S. Tsirkin
}
162 ff24bd58 Michael S. Tsirkin
163 25db9ebe Stefan Hajnoczi
static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
164 26b9b5fe Paolo Bonzini
                                                 int n, bool assign, bool set_handler)
165 25db9ebe Stefan Hajnoczi
{
166 25db9ebe Stefan Hajnoczi
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
167 25db9ebe Stefan Hajnoczi
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
168 da146d0a Avi Kivity
    int r = 0;
169 da146d0a Avi Kivity
170 25db9ebe Stefan Hajnoczi
    if (assign) {
171 25db9ebe Stefan Hajnoczi
        r = event_notifier_init(notifier, 1);
172 25db9ebe Stefan Hajnoczi
        if (r < 0) {
173 b36e3914 Michael S. Tsirkin
            error_report("%s: unable to init event notifier: %d",
174 b36e3914 Michael S. Tsirkin
                         __func__, r);
175 25db9ebe Stefan Hajnoczi
            return r;
176 25db9ebe Stefan Hajnoczi
        }
177 26b9b5fe Paolo Bonzini
        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
178 da146d0a Avi Kivity
        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
179 753d5e14 Paolo Bonzini
                                  true, n, notifier);
180 25db9ebe Stefan Hajnoczi
    } else {
181 da146d0a Avi Kivity
        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
182 753d5e14 Paolo Bonzini
                                  true, n, notifier);
183 26b9b5fe Paolo Bonzini
        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
184 25db9ebe Stefan Hajnoczi
        event_notifier_cleanup(notifier);
185 25db9ebe Stefan Hajnoczi
    }
186 25db9ebe Stefan Hajnoczi
    return r;
187 25db9ebe Stefan Hajnoczi
}
188 25db9ebe Stefan Hajnoczi
189 b36e3914 Michael S. Tsirkin
static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
190 25db9ebe Stefan Hajnoczi
{
191 25db9ebe Stefan Hajnoczi
    int n, r;
192 25db9ebe Stefan Hajnoczi
193 25db9ebe Stefan Hajnoczi
    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
194 25db9ebe Stefan Hajnoczi
        proxy->ioeventfd_disabled ||
195 25db9ebe Stefan Hajnoczi
        proxy->ioeventfd_started) {
196 b36e3914 Michael S. Tsirkin
        return;
197 25db9ebe Stefan Hajnoczi
    }
198 25db9ebe Stefan Hajnoczi
199 25db9ebe Stefan Hajnoczi
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
200 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
201 25db9ebe Stefan Hajnoczi
            continue;
202 25db9ebe Stefan Hajnoczi
        }
203 25db9ebe Stefan Hajnoczi
204 26b9b5fe Paolo Bonzini
        r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
205 25db9ebe Stefan Hajnoczi
        if (r < 0) {
206 25db9ebe Stefan Hajnoczi
            goto assign_error;
207 25db9ebe Stefan Hajnoczi
        }
208 25db9ebe Stefan Hajnoczi
    }
209 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = true;
210 b36e3914 Michael S. Tsirkin
    return;
211 25db9ebe Stefan Hajnoczi
212 25db9ebe Stefan Hajnoczi
assign_error:
213 25db9ebe Stefan Hajnoczi
    while (--n >= 0) {
214 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
215 25db9ebe Stefan Hajnoczi
            continue;
216 25db9ebe Stefan Hajnoczi
        }
217 25db9ebe Stefan Hajnoczi
218 26b9b5fe Paolo Bonzini
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
219 b36e3914 Michael S. Tsirkin
        assert(r >= 0);
220 25db9ebe Stefan Hajnoczi
    }
221 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = false;
222 b36e3914 Michael S. Tsirkin
    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
223 25db9ebe Stefan Hajnoczi
}
224 25db9ebe Stefan Hajnoczi
225 b36e3914 Michael S. Tsirkin
static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
226 25db9ebe Stefan Hajnoczi
{
227 b36e3914 Michael S. Tsirkin
    int r;
228 25db9ebe Stefan Hajnoczi
    int n;
229 25db9ebe Stefan Hajnoczi
230 25db9ebe Stefan Hajnoczi
    if (!proxy->ioeventfd_started) {
231 b36e3914 Michael S. Tsirkin
        return;
232 25db9ebe Stefan Hajnoczi
    }
233 25db9ebe Stefan Hajnoczi
234 25db9ebe Stefan Hajnoczi
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
235 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
236 25db9ebe Stefan Hajnoczi
            continue;
237 25db9ebe Stefan Hajnoczi
        }
238 25db9ebe Stefan Hajnoczi
239 26b9b5fe Paolo Bonzini
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
240 b36e3914 Michael S. Tsirkin
        assert(r >= 0);
241 25db9ebe Stefan Hajnoczi
    }
242 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = false;
243 25db9ebe Stefan Hajnoczi
}
244 25db9ebe Stefan Hajnoczi
245 8798d6c9 Aneesh Kumar K.V
void virtio_pci_reset(DeviceState *d)
246 7055e687 Michael S. Tsirkin
{
247 e489030d Michael S. Tsirkin
    VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
248 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
249 7055e687 Michael S. Tsirkin
    virtio_reset(proxy->vdev);
250 3cac001e Michael S. Tsirkin
    msix_unuse_all_vectors(&proxy->pci_dev);
251 25db9ebe Stefan Hajnoczi
    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
252 7055e687 Michael S. Tsirkin
}
253 7055e687 Michael S. Tsirkin
254 53c25cea Paul Brook
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
255 53c25cea Paul Brook
{
256 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
257 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
258 a8170e5e Avi Kivity
    hwaddr pa;
259 53c25cea Paul Brook
260 53c25cea Paul Brook
    switch (addr) {
261 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
262 53c25cea Paul Brook
        /* Guest does not negotiate properly?  We have to assume nothing. */
263 53c25cea Paul Brook
        if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
264 ad0c9332 Paolo Bonzini
            val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
265 53c25cea Paul Brook
        }
266 ad0c9332 Paolo Bonzini
        virtio_set_features(vdev, val);
267 53c25cea Paul Brook
        break;
268 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
269 a8170e5e Avi Kivity
        pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
270 1b8e9b27 Michael S. Tsirkin
        if (pa == 0) {
271 25db9ebe Stefan Hajnoczi
            virtio_pci_stop_ioeventfd(proxy);
272 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
273 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
274 1b8e9b27 Michael S. Tsirkin
        }
275 7055e687 Michael S. Tsirkin
        else
276 7055e687 Michael S. Tsirkin
            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
277 53c25cea Paul Brook
        break;
278 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
279 53c25cea Paul Brook
        if (val < VIRTIO_PCI_QUEUE_MAX)
280 53c25cea Paul Brook
            vdev->queue_sel = val;
281 53c25cea Paul Brook
        break;
282 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NOTIFY:
283 7157e2e2 Stefan Hajnoczi
        if (val < VIRTIO_PCI_QUEUE_MAX) {
284 7157e2e2 Stefan Hajnoczi
            virtio_queue_notify(vdev, val);
285 7157e2e2 Stefan Hajnoczi
        }
286 53c25cea Paul Brook
        break;
287 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
288 25db9ebe Stefan Hajnoczi
        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
289 25db9ebe Stefan Hajnoczi
            virtio_pci_stop_ioeventfd(proxy);
290 25db9ebe Stefan Hajnoczi
        }
291 25db9ebe Stefan Hajnoczi
292 3e607cb5 Michael S. Tsirkin
        virtio_set_status(vdev, val & 0xFF);
293 25db9ebe Stefan Hajnoczi
294 25db9ebe Stefan Hajnoczi
        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
295 25db9ebe Stefan Hajnoczi
            virtio_pci_start_ioeventfd(proxy);
296 25db9ebe Stefan Hajnoczi
        }
297 25db9ebe Stefan Hajnoczi
298 1b8e9b27 Michael S. Tsirkin
        if (vdev->status == 0) {
299 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
300 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
301 1b8e9b27 Michael S. Tsirkin
        }
302 c81131db Alexander Graf
303 c81131db Alexander Graf
        /* Linux before 2.6.34 sets the device as OK without enabling
304 c81131db Alexander Graf
           the PCI device bus master bit. In this case we need to disable
305 c81131db Alexander Graf
           some safety checks. */
306 c81131db Alexander Graf
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
307 c81131db Alexander Graf
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
308 3dbca8e6 Stefan Hajnoczi
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
309 c81131db Alexander Graf
        }
310 53c25cea Paul Brook
        break;
311 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
312 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
313 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
314 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
315 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
316 aba800a3 Michael S. Tsirkin
        vdev->config_vector = val;
317 aba800a3 Michael S. Tsirkin
        break;
318 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
319 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev,
320 aba800a3 Michael S. Tsirkin
                          virtio_queue_vector(vdev, vdev->queue_sel));
321 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
322 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
323 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
324 aba800a3 Michael S. Tsirkin
        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
325 aba800a3 Michael S. Tsirkin
        break;
326 aba800a3 Michael S. Tsirkin
    default:
327 4e02d460 Stefan Hajnoczi
        error_report("%s: unexpected address 0x%x value 0x%x",
328 4e02d460 Stefan Hajnoczi
                     __func__, addr, val);
329 aba800a3 Michael S. Tsirkin
        break;
330 53c25cea Paul Brook
    }
331 53c25cea Paul Brook
}
332 53c25cea Paul Brook
333 aba800a3 Michael S. Tsirkin
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
334 53c25cea Paul Brook
{
335 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
336 53c25cea Paul Brook
    uint32_t ret = 0xFFFFFFFF;
337 53c25cea Paul Brook
338 53c25cea Paul Brook
    switch (addr) {
339 53c25cea Paul Brook
    case VIRTIO_PCI_HOST_FEATURES:
340 8172539d Michael S. Tsirkin
        ret = proxy->host_features;
341 53c25cea Paul Brook
        break;
342 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
343 704a76fc Michael S. Tsirkin
        ret = vdev->guest_features;
344 53c25cea Paul Brook
        break;
345 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
346 53c25cea Paul Brook
        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
347 53c25cea Paul Brook
              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
348 53c25cea Paul Brook
        break;
349 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NUM:
350 53c25cea Paul Brook
        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
351 53c25cea Paul Brook
        break;
352 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
353 53c25cea Paul Brook
        ret = vdev->queue_sel;
354 53c25cea Paul Brook
        break;
355 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
356 53c25cea Paul Brook
        ret = vdev->status;
357 53c25cea Paul Brook
        break;
358 53c25cea Paul Brook
    case VIRTIO_PCI_ISR:
359 53c25cea Paul Brook
        /* reading from the ISR also clears it. */
360 53c25cea Paul Brook
        ret = vdev->isr;
361 53c25cea Paul Brook
        vdev->isr = 0;
362 7055e687 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], 0);
363 53c25cea Paul Brook
        break;
364 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
365 aba800a3 Michael S. Tsirkin
        ret = vdev->config_vector;
366 aba800a3 Michael S. Tsirkin
        break;
367 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
368 aba800a3 Michael S. Tsirkin
        ret = virtio_queue_vector(vdev, vdev->queue_sel);
369 aba800a3 Michael S. Tsirkin
        break;
370 53c25cea Paul Brook
    default:
371 53c25cea Paul Brook
        break;
372 53c25cea Paul Brook
    }
373 53c25cea Paul Brook
374 53c25cea Paul Brook
    return ret;
375 53c25cea Paul Brook
}
376 53c25cea Paul Brook
377 df6db5b3 Alexander Graf
static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
378 df6db5b3 Alexander Graf
                                       unsigned size)
379 53c25cea Paul Brook
{
380 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
381 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
382 df6db5b3 Alexander Graf
    uint64_t val = 0;
383 aba800a3 Michael S. Tsirkin
    if (addr < config) {
384 df6db5b3 Alexander Graf
        return virtio_ioport_read(proxy, addr);
385 aba800a3 Michael S. Tsirkin
    }
386 aba800a3 Michael S. Tsirkin
    addr -= config;
387 53c25cea Paul Brook
388 df6db5b3 Alexander Graf
    switch (size) {
389 df6db5b3 Alexander Graf
    case 1:
390 df6db5b3 Alexander Graf
        val = virtio_config_readb(proxy->vdev, addr);
391 df6db5b3 Alexander Graf
        break;
392 df6db5b3 Alexander Graf
    case 2:
393 df6db5b3 Alexander Graf
        val = virtio_config_readw(proxy->vdev, addr);
394 df6db5b3 Alexander Graf
        if (virtio_is_big_endian()) {
395 df6db5b3 Alexander Graf
            val = bswap16(val);
396 df6db5b3 Alexander Graf
        }
397 df6db5b3 Alexander Graf
        break;
398 df6db5b3 Alexander Graf
    case 4:
399 df6db5b3 Alexander Graf
        val = virtio_config_readl(proxy->vdev, addr);
400 df6db5b3 Alexander Graf
        if (virtio_is_big_endian()) {
401 df6db5b3 Alexander Graf
            val = bswap32(val);
402 df6db5b3 Alexander Graf
        }
403 df6db5b3 Alexander Graf
        break;
404 82afa586 Benjamin Herrenschmidt
    }
405 df6db5b3 Alexander Graf
    return val;
406 53c25cea Paul Brook
}
407 53c25cea Paul Brook
408 df6db5b3 Alexander Graf
static void virtio_pci_config_write(void *opaque, hwaddr addr,
409 df6db5b3 Alexander Graf
                                    uint64_t val, unsigned size)
410 53c25cea Paul Brook
{
411 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
412 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
413 aba800a3 Michael S. Tsirkin
    if (addr < config) {
414 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
415 aba800a3 Michael S. Tsirkin
        return;
416 aba800a3 Michael S. Tsirkin
    }
417 aba800a3 Michael S. Tsirkin
    addr -= config;
418 df6db5b3 Alexander Graf
    /*
419 df6db5b3 Alexander Graf
     * Virtio-PCI is odd. Ioports are LE but config space is target native
420 df6db5b3 Alexander Graf
     * endian.
421 df6db5b3 Alexander Graf
     */
422 df6db5b3 Alexander Graf
    switch (size) {
423 df6db5b3 Alexander Graf
    case 1:
424 df6db5b3 Alexander Graf
        virtio_config_writeb(proxy->vdev, addr, val);
425 df6db5b3 Alexander Graf
        break;
426 df6db5b3 Alexander Graf
    case 2:
427 df6db5b3 Alexander Graf
        if (virtio_is_big_endian()) {
428 df6db5b3 Alexander Graf
            val = bswap16(val);
429 df6db5b3 Alexander Graf
        }
430 df6db5b3 Alexander Graf
        virtio_config_writew(proxy->vdev, addr, val);
431 df6db5b3 Alexander Graf
        break;
432 df6db5b3 Alexander Graf
    case 4:
433 df6db5b3 Alexander Graf
        if (virtio_is_big_endian()) {
434 df6db5b3 Alexander Graf
            val = bswap32(val);
435 df6db5b3 Alexander Graf
        }
436 df6db5b3 Alexander Graf
        virtio_config_writel(proxy->vdev, addr, val);
437 df6db5b3 Alexander Graf
        break;
438 82afa586 Benjamin Herrenschmidt
    }
439 53c25cea Paul Brook
}
440 53c25cea Paul Brook
441 da146d0a Avi Kivity
static const MemoryRegionOps virtio_pci_config_ops = {
442 df6db5b3 Alexander Graf
    .read = virtio_pci_config_read,
443 df6db5b3 Alexander Graf
    .write = virtio_pci_config_write,
444 df6db5b3 Alexander Graf
    .impl = {
445 df6db5b3 Alexander Graf
        .min_access_size = 1,
446 df6db5b3 Alexander Graf
        .max_access_size = 4,
447 df6db5b3 Alexander Graf
    },
448 da146d0a Avi Kivity
    .endianness = DEVICE_LITTLE_ENDIAN,
449 da146d0a Avi Kivity
};
450 aba800a3 Michael S. Tsirkin
451 aba800a3 Michael S. Tsirkin
static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
452 aba800a3 Michael S. Tsirkin
                                uint32_t val, int len)
453 aba800a3 Michael S. Tsirkin
{
454 ed757e14 Yan Vugenfirer
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
455 ed757e14 Yan Vugenfirer
456 1129714f Michael S. Tsirkin
    pci_default_write_config(pci_dev, address, val, len);
457 1129714f Michael S. Tsirkin
458 1129714f Michael S. Tsirkin
    if (range_covers_byte(address, len, PCI_COMMAND) &&
459 1129714f Michael S. Tsirkin
        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
460 1129714f Michael S. Tsirkin
        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
461 1129714f Michael S. Tsirkin
        virtio_pci_stop_ioeventfd(proxy);
462 1129714f Michael S. Tsirkin
        virtio_set_status(proxy->vdev,
463 1129714f Michael S. Tsirkin
                          proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
464 ed757e14 Yan Vugenfirer
    }
465 53c25cea Paul Brook
}
466 53c25cea Paul Brook
467 6d74ca5a Michael S. Tsirkin
static unsigned virtio_pci_get_features(void *opaque)
468 6d74ca5a Michael S. Tsirkin
{
469 8172539d Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
470 8172539d Michael S. Tsirkin
    return proxy->host_features;
471 6d74ca5a Michael S. Tsirkin
}
472 6d74ca5a Michael S. Tsirkin
473 7d37d351 Jan Kiszka
static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
474 7d37d351 Jan Kiszka
                                        unsigned int queue_no,
475 7d37d351 Jan Kiszka
                                        unsigned int vector,
476 7d37d351 Jan Kiszka
                                        MSIMessage msg)
477 7d37d351 Jan Kiszka
{
478 7d37d351 Jan Kiszka
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
479 15b2bd18 Paolo Bonzini
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
480 7d37d351 Jan Kiszka
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
481 15b2bd18 Paolo Bonzini
    int ret;
482 7d37d351 Jan Kiszka
483 7d37d351 Jan Kiszka
    if (irqfd->users == 0) {
484 7d37d351 Jan Kiszka
        ret = kvm_irqchip_add_msi_route(kvm_state, msg);
485 7d37d351 Jan Kiszka
        if (ret < 0) {
486 7d37d351 Jan Kiszka
            return ret;
487 7d37d351 Jan Kiszka
        }
488 7d37d351 Jan Kiszka
        irqfd->virq = ret;
489 7d37d351 Jan Kiszka
    }
490 7d37d351 Jan Kiszka
    irqfd->users++;
491 7d37d351 Jan Kiszka
492 b131c74a Jan Kiszka
    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq);
493 7d37d351 Jan Kiszka
    if (ret < 0) {
494 7d37d351 Jan Kiszka
        if (--irqfd->users == 0) {
495 7d37d351 Jan Kiszka
            kvm_irqchip_release_virq(kvm_state, irqfd->virq);
496 7d37d351 Jan Kiszka
        }
497 7d37d351 Jan Kiszka
        return ret;
498 7d37d351 Jan Kiszka
    }
499 7d37d351 Jan Kiszka
500 15b2bd18 Paolo Bonzini
    virtio_queue_set_guest_notifier_fd_handler(vq, true, true);
501 7d37d351 Jan Kiszka
    return 0;
502 7d37d351 Jan Kiszka
}
503 7d37d351 Jan Kiszka
504 7d37d351 Jan Kiszka
static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
505 7d37d351 Jan Kiszka
                                             unsigned int queue_no,
506 7d37d351 Jan Kiszka
                                             unsigned int vector)
507 7d37d351 Jan Kiszka
{
508 7d37d351 Jan Kiszka
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
509 15b2bd18 Paolo Bonzini
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
510 7d37d351 Jan Kiszka
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
511 15b2bd18 Paolo Bonzini
    int ret;
512 7d37d351 Jan Kiszka
513 b131c74a Jan Kiszka
    ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq);
514 7d37d351 Jan Kiszka
    assert(ret == 0);
515 7d37d351 Jan Kiszka
516 7d37d351 Jan Kiszka
    if (--irqfd->users == 0) {
517 7d37d351 Jan Kiszka
        kvm_irqchip_release_virq(kvm_state, irqfd->virq);
518 7d37d351 Jan Kiszka
    }
519 7d37d351 Jan Kiszka
520 15b2bd18 Paolo Bonzini
    virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
521 7d37d351 Jan Kiszka
}
522 7d37d351 Jan Kiszka
523 7d37d351 Jan Kiszka
static int kvm_virtio_pci_vector_use(PCIDevice *dev, unsigned vector,
524 7d37d351 Jan Kiszka
                                     MSIMessage msg)
525 7d37d351 Jan Kiszka
{
526 7d37d351 Jan Kiszka
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
527 7d37d351 Jan Kiszka
    VirtIODevice *vdev = proxy->vdev;
528 7d37d351 Jan Kiszka
    int ret, queue_no;
529 7d37d351 Jan Kiszka
530 7d37d351 Jan Kiszka
    for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
531 7d37d351 Jan Kiszka
        if (!virtio_queue_get_num(vdev, queue_no)) {
532 7d37d351 Jan Kiszka
            break;
533 7d37d351 Jan Kiszka
        }
534 7d37d351 Jan Kiszka
        if (virtio_queue_vector(vdev, queue_no) != vector) {
535 7d37d351 Jan Kiszka
            continue;
536 7d37d351 Jan Kiszka
        }
537 7d37d351 Jan Kiszka
        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
538 7d37d351 Jan Kiszka
        if (ret < 0) {
539 7d37d351 Jan Kiszka
            goto undo;
540 7d37d351 Jan Kiszka
        }
541 7d37d351 Jan Kiszka
    }
542 7d37d351 Jan Kiszka
    return 0;
543 7d37d351 Jan Kiszka
544 7d37d351 Jan Kiszka
undo:
545 7d37d351 Jan Kiszka
    while (--queue_no >= 0) {
546 7d37d351 Jan Kiszka
        if (virtio_queue_vector(vdev, queue_no) != vector) {
547 7d37d351 Jan Kiszka
            continue;
548 7d37d351 Jan Kiszka
        }
549 7d37d351 Jan Kiszka
        kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
550 7d37d351 Jan Kiszka
    }
551 7d37d351 Jan Kiszka
    return ret;
552 7d37d351 Jan Kiszka
}
553 7d37d351 Jan Kiszka
554 7d37d351 Jan Kiszka
static void kvm_virtio_pci_vector_release(PCIDevice *dev, unsigned vector)
555 7d37d351 Jan Kiszka
{
556 7d37d351 Jan Kiszka
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
557 7d37d351 Jan Kiszka
    VirtIODevice *vdev = proxy->vdev;
558 7d37d351 Jan Kiszka
    int queue_no;
559 7d37d351 Jan Kiszka
560 7d37d351 Jan Kiszka
    for (queue_no = 0; queue_no < VIRTIO_PCI_QUEUE_MAX; queue_no++) {
561 7d37d351 Jan Kiszka
        if (!virtio_queue_get_num(vdev, queue_no)) {
562 7d37d351 Jan Kiszka
            break;
563 7d37d351 Jan Kiszka
        }
564 7d37d351 Jan Kiszka
        if (virtio_queue_vector(vdev, queue_no) != vector) {
565 7d37d351 Jan Kiszka
            continue;
566 7d37d351 Jan Kiszka
        }
567 7d37d351 Jan Kiszka
        kvm_virtio_pci_vq_vector_release(proxy, queue_no, vector);
568 7d37d351 Jan Kiszka
    }
569 7d37d351 Jan Kiszka
}
570 7d37d351 Jan Kiszka
571 ade80dc8 Michael S. Tsirkin
static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
572 ade80dc8 Michael S. Tsirkin
{
573 ade80dc8 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
574 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
575 ade80dc8 Michael S. Tsirkin
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
576 ade80dc8 Michael S. Tsirkin
577 ade80dc8 Michael S. Tsirkin
    if (assign) {
578 ade80dc8 Michael S. Tsirkin
        int r = event_notifier_init(notifier, 0);
579 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
580 ade80dc8 Michael S. Tsirkin
            return r;
581 ade80dc8 Michael S. Tsirkin
        }
582 15b2bd18 Paolo Bonzini
        virtio_queue_set_guest_notifier_fd_handler(vq, true, false);
583 ade80dc8 Michael S. Tsirkin
    } else {
584 15b2bd18 Paolo Bonzini
        virtio_queue_set_guest_notifier_fd_handler(vq, false, false);
585 ade80dc8 Michael S. Tsirkin
        event_notifier_cleanup(notifier);
586 ade80dc8 Michael S. Tsirkin
    }
587 ade80dc8 Michael S. Tsirkin
588 ade80dc8 Michael S. Tsirkin
    return 0;
589 ade80dc8 Michael S. Tsirkin
}
590 ade80dc8 Michael S. Tsirkin
591 5430a28f mst@redhat.com
static bool virtio_pci_query_guest_notifiers(void *opaque)
592 5430a28f mst@redhat.com
{
593 5430a28f mst@redhat.com
    VirtIOPCIProxy *proxy = opaque;
594 5430a28f mst@redhat.com
    return msix_enabled(&proxy->pci_dev);
595 5430a28f mst@redhat.com
}
596 5430a28f mst@redhat.com
597 54dd9321 Michael S. Tsirkin
static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
598 54dd9321 Michael S. Tsirkin
{
599 54dd9321 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
600 54dd9321 Michael S. Tsirkin
    VirtIODevice *vdev = proxy->vdev;
601 54dd9321 Michael S. Tsirkin
    int r, n;
602 54dd9321 Michael S. Tsirkin
603 7d37d351 Jan Kiszka
    /* Must unset vector notifier while guest notifier is still assigned */
604 614e41bc Peter Maydell
    if (kvm_msi_via_irqfd_enabled() && !assign) {
605 7d37d351 Jan Kiszka
        msix_unset_vector_notifiers(&proxy->pci_dev);
606 7d37d351 Jan Kiszka
        g_free(proxy->vector_irqfd);
607 7d37d351 Jan Kiszka
        proxy->vector_irqfd = NULL;
608 7d37d351 Jan Kiszka
    }
609 7d37d351 Jan Kiszka
610 54dd9321 Michael S. Tsirkin
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
611 54dd9321 Michael S. Tsirkin
        if (!virtio_queue_get_num(vdev, n)) {
612 54dd9321 Michael S. Tsirkin
            break;
613 54dd9321 Michael S. Tsirkin
        }
614 54dd9321 Michael S. Tsirkin
615 54dd9321 Michael S. Tsirkin
        r = virtio_pci_set_guest_notifier(opaque, n, assign);
616 54dd9321 Michael S. Tsirkin
        if (r < 0) {
617 54dd9321 Michael S. Tsirkin
            goto assign_error;
618 54dd9321 Michael S. Tsirkin
        }
619 54dd9321 Michael S. Tsirkin
    }
620 54dd9321 Michael S. Tsirkin
621 7d37d351 Jan Kiszka
    /* Must set vector notifier after guest notifier has been assigned */
622 614e41bc Peter Maydell
    if (kvm_msi_via_irqfd_enabled() && assign) {
623 7d37d351 Jan Kiszka
        proxy->vector_irqfd =
624 7d37d351 Jan Kiszka
            g_malloc0(sizeof(*proxy->vector_irqfd) *
625 7d37d351 Jan Kiszka
                      msix_nr_vectors_allocated(&proxy->pci_dev));
626 7d37d351 Jan Kiszka
        r = msix_set_vector_notifiers(&proxy->pci_dev,
627 7d37d351 Jan Kiszka
                                      kvm_virtio_pci_vector_use,
628 7d37d351 Jan Kiszka
                                      kvm_virtio_pci_vector_release);
629 7d37d351 Jan Kiszka
        if (r < 0) {
630 7d37d351 Jan Kiszka
            goto assign_error;
631 7d37d351 Jan Kiszka
        }
632 7d37d351 Jan Kiszka
    }
633 7d37d351 Jan Kiszka
634 54dd9321 Michael S. Tsirkin
    return 0;
635 54dd9321 Michael S. Tsirkin
636 54dd9321 Michael S. Tsirkin
assign_error:
637 54dd9321 Michael S. Tsirkin
    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
638 7d37d351 Jan Kiszka
    assert(assign);
639 54dd9321 Michael S. Tsirkin
    while (--n >= 0) {
640 54dd9321 Michael S. Tsirkin
        virtio_pci_set_guest_notifier(opaque, n, !assign);
641 54dd9321 Michael S. Tsirkin
    }
642 54dd9321 Michael S. Tsirkin
    return r;
643 54dd9321 Michael S. Tsirkin
}
644 54dd9321 Michael S. Tsirkin
645 ade80dc8 Michael S. Tsirkin
static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
646 ade80dc8 Michael S. Tsirkin
{
647 ade80dc8 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
648 25db9ebe Stefan Hajnoczi
649 25db9ebe Stefan Hajnoczi
    /* Stop using ioeventfd for virtqueue kick if the device starts using host
650 25db9ebe Stefan Hajnoczi
     * notifiers.  This makes it easy to avoid stepping on each others' toes.
651 25db9ebe Stefan Hajnoczi
     */
652 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_disabled = assign;
653 ade80dc8 Michael S. Tsirkin
    if (assign) {
654 25db9ebe Stefan Hajnoczi
        virtio_pci_stop_ioeventfd(proxy);
655 25db9ebe Stefan Hajnoczi
    }
656 25db9ebe Stefan Hajnoczi
    /* We don't need to start here: it's not needed because backend
657 25db9ebe Stefan Hajnoczi
     * currently only stops on status change away from ok,
658 25db9ebe Stefan Hajnoczi
     * reset, vmstop and such. If we do add code to start here,
659 25db9ebe Stefan Hajnoczi
     * need to check vmstate, device state etc. */
660 26b9b5fe Paolo Bonzini
    return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
661 25db9ebe Stefan Hajnoczi
}
662 25db9ebe Stefan Hajnoczi
663 25db9ebe Stefan Hajnoczi
static void virtio_pci_vmstate_change(void *opaque, bool running)
664 25db9ebe Stefan Hajnoczi
{
665 25db9ebe Stefan Hajnoczi
    VirtIOPCIProxy *proxy = opaque;
666 25db9ebe Stefan Hajnoczi
667 25db9ebe Stefan Hajnoczi
    if (running) {
668 89c473fd Michael S. Tsirkin
        /* Try to find out if the guest has bus master disabled, but is
669 89c473fd Michael S. Tsirkin
           in ready state. Then we have a buggy guest OS. */
670 89c473fd Michael S. Tsirkin
        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
671 89c473fd Michael S. Tsirkin
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
672 89c473fd Michael S. Tsirkin
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
673 89c473fd Michael S. Tsirkin
        }
674 25db9ebe Stefan Hajnoczi
        virtio_pci_start_ioeventfd(proxy);
675 ade80dc8 Michael S. Tsirkin
    } else {
676 25db9ebe Stefan Hajnoczi
        virtio_pci_stop_ioeventfd(proxy);
677 ade80dc8 Michael S. Tsirkin
    }
678 ade80dc8 Michael S. Tsirkin
}
679 ade80dc8 Michael S. Tsirkin
680 53c25cea Paul Brook
static const VirtIOBindings virtio_pci_bindings = {
681 ff24bd58 Michael S. Tsirkin
    .notify = virtio_pci_notify,
682 ff24bd58 Michael S. Tsirkin
    .save_config = virtio_pci_save_config,
683 ff24bd58 Michael S. Tsirkin
    .load_config = virtio_pci_load_config,
684 ff24bd58 Michael S. Tsirkin
    .save_queue = virtio_pci_save_queue,
685 ff24bd58 Michael S. Tsirkin
    .load_queue = virtio_pci_load_queue,
686 6d74ca5a Michael S. Tsirkin
    .get_features = virtio_pci_get_features,
687 5430a28f mst@redhat.com
    .query_guest_notifiers = virtio_pci_query_guest_notifiers,
688 ade80dc8 Michael S. Tsirkin
    .set_host_notifier = virtio_pci_set_host_notifier,
689 54dd9321 Michael S. Tsirkin
    .set_guest_notifiers = virtio_pci_set_guest_notifiers,
690 25db9ebe Stefan Hajnoczi
    .vmstate_change = virtio_pci_vmstate_change,
691 53c25cea Paul Brook
};
692 53c25cea Paul Brook
693 befeac45 Michael S. Tsirkin
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
694 53c25cea Paul Brook
{
695 53c25cea Paul Brook
    uint8_t *config;
696 53c25cea Paul Brook
    uint32_t size;
697 53c25cea Paul Brook
698 53c25cea Paul Brook
    proxy->vdev = vdev;
699 53c25cea Paul Brook
700 53c25cea Paul Brook
    config = proxy->pci_dev.config;
701 53c25cea Paul Brook
702 e75ccf2c Isaku Yamahata
    if (proxy->class_code) {
703 e75ccf2c Isaku Yamahata
        pci_config_set_class(config, proxy->class_code);
704 e75ccf2c Isaku Yamahata
    }
705 ad3d11e6 Hui Kai Ran
    pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
706 ad3d11e6 Hui Kai Ran
                 pci_get_word(config + PCI_VENDOR_ID));
707 ad3d11e6 Hui Kai Ran
    pci_set_word(config + PCI_SUBSYSTEM_ID, vdev->device_id);
708 ad3d11e6 Hui Kai Ran
    config[PCI_INTERRUPT_PIN] = 1;
709 53c25cea Paul Brook
710 b2357c48 Alex Williamson
    if (vdev->nvectors &&
711 b2357c48 Alex Williamson
        msix_init_exclusive_bar(&proxy->pci_dev, vdev->nvectors, 1)) {
712 aba800a3 Michael S. Tsirkin
        vdev->nvectors = 0;
713 b2357c48 Alex Williamson
    }
714 aba800a3 Michael S. Tsirkin
715 ed757e14 Yan Vugenfirer
    proxy->pci_dev.config_write = virtio_write_config;
716 ed757e14 Yan Vugenfirer
717 aba800a3 Michael S. Tsirkin
    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
718 53c25cea Paul Brook
    if (size & (size-1))
719 53c25cea Paul Brook
        size = 1 << qemu_fls(size);
720 53c25cea Paul Brook
721 da146d0a Avi Kivity
    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
722 da146d0a Avi Kivity
                          "virtio-pci", size);
723 e824b2cc Avi Kivity
    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
724 e824b2cc Avi Kivity
                     &proxy->bar);
725 53c25cea Paul Brook
726 25db9ebe Stefan Hajnoczi
    if (!kvm_has_many_ioeventfds()) {
727 25db9ebe Stefan Hajnoczi
        proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
728 25db9ebe Stefan Hajnoczi
    }
729 25db9ebe Stefan Hajnoczi
730 53c25cea Paul Brook
    virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
731 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
732 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
733 8172539d Michael S. Tsirkin
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
734 53c25cea Paul Brook
}
735 53c25cea Paul Brook
736 81a322d4 Gerd Hoffmann
static int virtio_blk_init_pci(PCIDevice *pci_dev)
737 53c25cea Paul Brook
{
738 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
739 53c25cea Paul Brook
    VirtIODevice *vdev;
740 53c25cea Paul Brook
741 ab73ff29 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
742 ab73ff29 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_STORAGE_OTHER)
743 ab73ff29 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_STORAGE_SCSI;
744 53c25cea Paul Brook
745 12c5674b Paolo Bonzini
    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->blk);
746 ac0c14d7 Markus Armbruster
    if (!vdev) {
747 ac0c14d7 Markus Armbruster
        return -1;
748 ac0c14d7 Markus Armbruster
    }
749 177539e0 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
750 e75ccf2c Isaku Yamahata
    virtio_init_pci(proxy, vdev);
751 177539e0 Gerd Hoffmann
    /* make the actual value visible */
752 177539e0 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
753 81a322d4 Gerd Hoffmann
    return 0;
754 21d58b57 Mark McLoughlin
}
755 21d58b57 Mark McLoughlin
756 f90c2bcd Alex Williamson
static void virtio_exit_pci(PCIDevice *pci_dev)
757 0f457d91 Michael S. Tsirkin
{
758 da146d0a Avi Kivity
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
759 da146d0a Avi Kivity
760 da146d0a Avi Kivity
    memory_region_destroy(&proxy->bar);
761 b2357c48 Alex Williamson
    msix_uninit_exclusive_bar(pci_dev);
762 0f457d91 Michael S. Tsirkin
}
763 0f457d91 Michael S. Tsirkin
764 f90c2bcd Alex Williamson
static void virtio_blk_exit_pci(PCIDevice *pci_dev)
765 56a14938 Gerd Hoffmann
{
766 56a14938 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
767 56a14938 Gerd Hoffmann
768 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
769 9d0d3138 Alex Williamson
    virtio_blk_exit(proxy->vdev);
770 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
771 56a14938 Gerd Hoffmann
}
772 56a14938 Gerd Hoffmann
773 98b19252 Amit Shah
static int virtio_serial_init_pci(PCIDevice *pci_dev)
774 21d58b57 Mark McLoughlin
{
775 d6beee99 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
776 85c2c735 Mark McLoughlin
    VirtIODevice *vdev;
777 85c2c735 Mark McLoughlin
778 d6beee99 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
779 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
780 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
781 d6beee99 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
782 d6beee99 Gerd Hoffmann
783 6b331efb Amit Shah
    vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
784 25fe3654 Amit Shah
    if (!vdev) {
785 25fe3654 Amit Shah
        return -1;
786 25fe3654 Amit Shah
    }
787 573fb60c Amit Shah
    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
788 6b331efb Amit Shah
                                        ? proxy->serial.max_virtserial_ports + 1
789 573fb60c Amit Shah
                                        : proxy->nvectors;
790 e75ccf2c Isaku Yamahata
    virtio_init_pci(proxy, vdev);
791 a1829205 Amit Shah
    proxy->nvectors = vdev->nvectors;
792 81a322d4 Gerd Hoffmann
    return 0;
793 53c25cea Paul Brook
}
794 53c25cea Paul Brook
795 f90c2bcd Alex Williamson
static void virtio_serial_exit_pci(PCIDevice *pci_dev)
796 8b53a865 Amit Shah
{
797 8b53a865 Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
798 8b53a865 Amit Shah
799 32059220 Amit Shah
    virtio_pci_stop_ioeventfd(proxy);
800 8b53a865 Amit Shah
    virtio_serial_exit(proxy->vdev);
801 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
802 8b53a865 Amit Shah
}
803 8b53a865 Amit Shah
804 81a322d4 Gerd Hoffmann
static int virtio_net_init_pci(PCIDevice *pci_dev)
805 53c25cea Paul Brook
{
806 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
807 53c25cea Paul Brook
    VirtIODevice *vdev;
808 53c25cea Paul Brook
809 f0c07c7c Alex Williamson
    vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
810 a1e0fea5 Gerd Hoffmann
811 97b15621 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
812 e75ccf2c Isaku Yamahata
    virtio_init_pci(proxy, vdev);
813 a1e0fea5 Gerd Hoffmann
814 a1e0fea5 Gerd Hoffmann
    /* make the actual value visible */
815 a1e0fea5 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
816 81a322d4 Gerd Hoffmann
    return 0;
817 53c25cea Paul Brook
}
818 53c25cea Paul Brook
819 f90c2bcd Alex Williamson
static void virtio_net_exit_pci(PCIDevice *pci_dev)
820 97b15621 Gerd Hoffmann
{
821 97b15621 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
822 97b15621 Gerd Hoffmann
823 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
824 97b15621 Gerd Hoffmann
    virtio_net_exit(proxy->vdev);
825 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
826 97b15621 Gerd Hoffmann
}
827 97b15621 Gerd Hoffmann
828 81a322d4 Gerd Hoffmann
static int virtio_balloon_init_pci(PCIDevice *pci_dev)
829 53c25cea Paul Brook
{
830 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
831 53c25cea Paul Brook
    VirtIODevice *vdev;
832 53c25cea Paul Brook
833 2ba1d381 David Gibson
    if (proxy->class_code != PCI_CLASS_OTHERS &&
834 2ba1d381 David Gibson
        proxy->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */
835 2ba1d381 David Gibson
        proxy->class_code = PCI_CLASS_OTHERS;
836 2ba1d381 David Gibson
    }
837 2ba1d381 David Gibson
838 53c25cea Paul Brook
    vdev = virtio_balloon_init(&pci_dev->qdev);
839 f76f6655 Amit Shah
    if (!vdev) {
840 f76f6655 Amit Shah
        return -1;
841 f76f6655 Amit Shah
    }
842 e75ccf2c Isaku Yamahata
    virtio_init_pci(proxy, vdev);
843 81a322d4 Gerd Hoffmann
    return 0;
844 53c25cea Paul Brook
}
845 53c25cea Paul Brook
846 f90c2bcd Alex Williamson
static void virtio_balloon_exit_pci(PCIDevice *pci_dev)
847 855d7e25 Amit Shah
{
848 855d7e25 Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
849 855d7e25 Amit Shah
850 855d7e25 Amit Shah
    virtio_pci_stop_ioeventfd(proxy);
851 855d7e25 Amit Shah
    virtio_balloon_exit(proxy->vdev);
852 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
853 855d7e25 Amit Shah
}
854 855d7e25 Amit Shah
855 40021f08 Anthony Liguori
static Property virtio_blk_properties[] = {
856 40021f08 Anthony Liguori
    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
857 12c5674b Paolo Bonzini
    DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, blk.conf),
858 e63e7fde Markus Armbruster
    DEFINE_BLOCK_CHS_PROPERTIES(VirtIOPCIProxy, blk.conf),
859 12c5674b Paolo Bonzini
    DEFINE_PROP_STRING("serial", VirtIOPCIProxy, blk.serial),
860 a6c5c84a Paolo Bonzini
#ifdef __linux__
861 a6c5c84a Paolo Bonzini
    DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true),
862 a6c5c84a Paolo Bonzini
#endif
863 eec7f96c Stefan Hajnoczi
    DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true),
864 40021f08 Anthony Liguori
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
865 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
866 40021f08 Anthony Liguori
    DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
867 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
868 e855761c Anthony Liguori
};
869 e855761c Anthony Liguori
870 40021f08 Anthony Liguori
static void virtio_blk_class_init(ObjectClass *klass, void *data)
871 40021f08 Anthony Liguori
{
872 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
873 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
874 40021f08 Anthony Liguori
875 40021f08 Anthony Liguori
    k->init = virtio_blk_init_pci;
876 40021f08 Anthony Liguori
    k->exit = virtio_blk_exit_pci;
877 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
878 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
879 40021f08 Anthony Liguori
    k->revision = VIRTIO_PCI_ABI_VERSION;
880 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_STORAGE_SCSI;
881 39bffca2 Anthony Liguori
    dc->reset = virtio_pci_reset;
882 39bffca2 Anthony Liguori
    dc->props = virtio_blk_properties;
883 40021f08 Anthony Liguori
}
884 40021f08 Anthony Liguori
885 39bffca2 Anthony Liguori
static TypeInfo virtio_blk_info = {
886 39bffca2 Anthony Liguori
    .name          = "virtio-blk-pci",
887 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
888 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOPCIProxy),
889 39bffca2 Anthony Liguori
    .class_init    = virtio_blk_class_init,
890 40021f08 Anthony Liguori
};
891 40021f08 Anthony Liguori
892 40021f08 Anthony Liguori
static Property virtio_net_properties[] = {
893 40021f08 Anthony Liguori
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
894 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
895 40021f08 Anthony Liguori
    DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
896 40021f08 Anthony Liguori
    DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
897 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
898 40021f08 Anthony Liguori
    DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
899 40021f08 Anthony Liguori
    DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
900 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
901 40021f08 Anthony Liguori
};
902 40021f08 Anthony Liguori
903 40021f08 Anthony Liguori
static void virtio_net_class_init(ObjectClass *klass, void *data)
904 40021f08 Anthony Liguori
{
905 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
906 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
907 40021f08 Anthony Liguori
908 40021f08 Anthony Liguori
    k->init = virtio_net_init_pci;
909 40021f08 Anthony Liguori
    k->exit = virtio_net_exit_pci;
910 40021f08 Anthony Liguori
    k->romfile = "pxe-virtio.rom";
911 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
912 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
913 40021f08 Anthony Liguori
    k->revision = VIRTIO_PCI_ABI_VERSION;
914 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
915 39bffca2 Anthony Liguori
    dc->reset = virtio_pci_reset;
916 39bffca2 Anthony Liguori
    dc->props = virtio_net_properties;
917 40021f08 Anthony Liguori
}
918 40021f08 Anthony Liguori
919 39bffca2 Anthony Liguori
static TypeInfo virtio_net_info = {
920 39bffca2 Anthony Liguori
    .name          = "virtio-net-pci",
921 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
922 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOPCIProxy),
923 39bffca2 Anthony Liguori
    .class_init    = virtio_net_class_init,
924 e855761c Anthony Liguori
};
925 e855761c Anthony Liguori
926 40021f08 Anthony Liguori
static Property virtio_serial_properties[] = {
927 40021f08 Anthony Liguori
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
928 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
929 40021f08 Anthony Liguori
    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
930 40021f08 Anthony Liguori
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
931 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
932 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
933 e855761c Anthony Liguori
};
934 e855761c Anthony Liguori
935 40021f08 Anthony Liguori
static void virtio_serial_class_init(ObjectClass *klass, void *data)
936 40021f08 Anthony Liguori
{
937 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
938 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
939 40021f08 Anthony Liguori
940 40021f08 Anthony Liguori
    k->init = virtio_serial_init_pci;
941 40021f08 Anthony Liguori
    k->exit = virtio_serial_exit_pci;
942 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
943 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
944 40021f08 Anthony Liguori
    k->revision = VIRTIO_PCI_ABI_VERSION;
945 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
946 39bffca2 Anthony Liguori
    dc->reset = virtio_pci_reset;
947 39bffca2 Anthony Liguori
    dc->props = virtio_serial_properties;
948 40021f08 Anthony Liguori
}
949 40021f08 Anthony Liguori
950 39bffca2 Anthony Liguori
static TypeInfo virtio_serial_info = {
951 39bffca2 Anthony Liguori
    .name          = "virtio-serial-pci",
952 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
953 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOPCIProxy),
954 39bffca2 Anthony Liguori
    .class_init    = virtio_serial_class_init,
955 40021f08 Anthony Liguori
};
956 40021f08 Anthony Liguori
957 40021f08 Anthony Liguori
static Property virtio_balloon_properties[] = {
958 40021f08 Anthony Liguori
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
959 2ba1d381 David Gibson
    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
960 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
961 40021f08 Anthony Liguori
};
962 40021f08 Anthony Liguori
963 40021f08 Anthony Liguori
static void virtio_balloon_class_init(ObjectClass *klass, void *data)
964 40021f08 Anthony Liguori
{
965 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
966 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
967 40021f08 Anthony Liguori
968 40021f08 Anthony Liguori
    k->init = virtio_balloon_init_pci;
969 40021f08 Anthony Liguori
    k->exit = virtio_balloon_exit_pci;
970 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
971 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
972 40021f08 Anthony Liguori
    k->revision = VIRTIO_PCI_ABI_VERSION;
973 2ba1d381 David Gibson
    k->class_id = PCI_CLASS_OTHERS;
974 39bffca2 Anthony Liguori
    dc->reset = virtio_pci_reset;
975 39bffca2 Anthony Liguori
    dc->props = virtio_balloon_properties;
976 40021f08 Anthony Liguori
}
977 40021f08 Anthony Liguori
978 39bffca2 Anthony Liguori
static TypeInfo virtio_balloon_info = {
979 39bffca2 Anthony Liguori
    .name          = "virtio-balloon-pci",
980 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
981 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOPCIProxy),
982 39bffca2 Anthony Liguori
    .class_init    = virtio_balloon_class_init,
983 0aab0d3a Gerd Hoffmann
};
984 0aab0d3a Gerd Hoffmann
985 973abc7f Stefan Hajnoczi
static int virtio_scsi_init_pci(PCIDevice *pci_dev)
986 973abc7f Stefan Hajnoczi
{
987 973abc7f Stefan Hajnoczi
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
988 973abc7f Stefan Hajnoczi
    VirtIODevice *vdev;
989 973abc7f Stefan Hajnoczi
990 973abc7f Stefan Hajnoczi
    vdev = virtio_scsi_init(&pci_dev->qdev, &proxy->scsi);
991 973abc7f Stefan Hajnoczi
    if (!vdev) {
992 973abc7f Stefan Hajnoczi
        return -EINVAL;
993 973abc7f Stefan Hajnoczi
    }
994 973abc7f Stefan Hajnoczi
995 4c205d0c Paolo Bonzini
    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
996 4c205d0c Paolo Bonzini
                                        ? proxy->scsi.num_queues + 3
997 4c205d0c Paolo Bonzini
                                        : proxy->nvectors;
998 973abc7f Stefan Hajnoczi
    virtio_init_pci(proxy, vdev);
999 973abc7f Stefan Hajnoczi
1000 973abc7f Stefan Hajnoczi
    /* make the actual value visible */
1001 973abc7f Stefan Hajnoczi
    proxy->nvectors = vdev->nvectors;
1002 973abc7f Stefan Hajnoczi
    return 0;
1003 973abc7f Stefan Hajnoczi
}
1004 973abc7f Stefan Hajnoczi
1005 f90c2bcd Alex Williamson
static void virtio_scsi_exit_pci(PCIDevice *pci_dev)
1006 973abc7f Stefan Hajnoczi
{
1007 973abc7f Stefan Hajnoczi
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1008 973abc7f Stefan Hajnoczi
1009 973abc7f Stefan Hajnoczi
    virtio_scsi_exit(proxy->vdev);
1010 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
1011 973abc7f Stefan Hajnoczi
}
1012 973abc7f Stefan Hajnoczi
1013 973abc7f Stefan Hajnoczi
static Property virtio_scsi_properties[] = {
1014 3f910904 Paolo Bonzini
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
1015 4c205d0c Paolo Bonzini
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, DEV_NVECTORS_UNSPECIFIED),
1016 973abc7f Stefan Hajnoczi
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOPCIProxy, host_features, scsi),
1017 973abc7f Stefan Hajnoczi
    DEFINE_PROP_END_OF_LIST(),
1018 973abc7f Stefan Hajnoczi
};
1019 973abc7f Stefan Hajnoczi
1020 973abc7f Stefan Hajnoczi
static void virtio_scsi_class_init(ObjectClass *klass, void *data)
1021 973abc7f Stefan Hajnoczi
{
1022 973abc7f Stefan Hajnoczi
    DeviceClass *dc = DEVICE_CLASS(klass);
1023 973abc7f Stefan Hajnoczi
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1024 973abc7f Stefan Hajnoczi
1025 973abc7f Stefan Hajnoczi
    k->init = virtio_scsi_init_pci;
1026 973abc7f Stefan Hajnoczi
    k->exit = virtio_scsi_exit_pci;
1027 973abc7f Stefan Hajnoczi
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1028 973abc7f Stefan Hajnoczi
    k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
1029 973abc7f Stefan Hajnoczi
    k->revision = 0x00;
1030 973abc7f Stefan Hajnoczi
    k->class_id = PCI_CLASS_STORAGE_SCSI;
1031 973abc7f Stefan Hajnoczi
    dc->reset = virtio_pci_reset;
1032 973abc7f Stefan Hajnoczi
    dc->props = virtio_scsi_properties;
1033 973abc7f Stefan Hajnoczi
}
1034 973abc7f Stefan Hajnoczi
1035 973abc7f Stefan Hajnoczi
static TypeInfo virtio_scsi_info = {
1036 973abc7f Stefan Hajnoczi
    .name          = "virtio-scsi-pci",
1037 973abc7f Stefan Hajnoczi
    .parent        = TYPE_PCI_DEVICE,
1038 973abc7f Stefan Hajnoczi
    .instance_size = sizeof(VirtIOPCIProxy),
1039 973abc7f Stefan Hajnoczi
    .class_init    = virtio_scsi_class_init,
1040 973abc7f Stefan Hajnoczi
};
1041 973abc7f Stefan Hajnoczi
1042 83f7d43a Andreas Färber
static void virtio_pci_register_types(void)
1043 53c25cea Paul Brook
{
1044 39bffca2 Anthony Liguori
    type_register_static(&virtio_blk_info);
1045 39bffca2 Anthony Liguori
    type_register_static(&virtio_net_info);
1046 39bffca2 Anthony Liguori
    type_register_static(&virtio_serial_info);
1047 39bffca2 Anthony Liguori
    type_register_static(&virtio_balloon_info);
1048 973abc7f Stefan Hajnoczi
    type_register_static(&virtio_scsi_info);
1049 53c25cea Paul Brook
}
1050 53c25cea Paul Brook
1051 83f7d43a Andreas Färber
type_init(virtio_pci_register_types)