Statistics
| Branch: | Revision:

root / hw / virtio-pci.c @ 32059220

History | View | Annotate | Download (29.6 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 53c25cea Paul Brook
 */
15 53c25cea Paul Brook
16 53c25cea Paul Brook
#include <inttypes.h>
17 53c25cea Paul Brook
18 53c25cea Paul Brook
#include "virtio.h"
19 8172539d Michael S. Tsirkin
#include "virtio-blk.h"
20 8172539d Michael S. Tsirkin
#include "virtio-net.h"
21 6b331efb Amit Shah
#include "virtio-serial.h"
22 53c25cea Paul Brook
#include "pci.h"
23 2f792016 Markus Armbruster
#include "qemu-error.h"
24 aba800a3 Michael S. Tsirkin
#include "msix.h"
25 a1e0fea5 Gerd Hoffmann
#include "net.h"
26 97b15621 Gerd Hoffmann
#include "loader.h"
27 ade80dc8 Michael S. Tsirkin
#include "kvm.h"
28 2446333c Blue Swirl
#include "blockdev.h"
29 53c25cea Paul Brook
30 53c25cea Paul Brook
/* from Linux's linux/virtio_pci.h */
31 53c25cea Paul Brook
32 53c25cea Paul Brook
/* A 32-bit r/o bitmask of the features supported by the host */
33 53c25cea Paul Brook
#define VIRTIO_PCI_HOST_FEATURES        0
34 53c25cea Paul Brook
35 53c25cea Paul Brook
/* A 32-bit r/w bitmask of features activated by the guest */
36 53c25cea Paul Brook
#define VIRTIO_PCI_GUEST_FEATURES       4
37 53c25cea Paul Brook
38 53c25cea Paul Brook
/* A 32-bit r/w PFN for the currently selected queue */
39 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_PFN            8
40 53c25cea Paul Brook
41 53c25cea Paul Brook
/* A 16-bit r/o queue size for the currently selected queue */
42 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NUM            12
43 53c25cea Paul Brook
44 53c25cea Paul Brook
/* A 16-bit r/w queue selector */
45 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_SEL            14
46 53c25cea Paul Brook
47 53c25cea Paul Brook
/* A 16-bit r/w queue notifier */
48 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NOTIFY         16
49 53c25cea Paul Brook
50 53c25cea Paul Brook
/* An 8-bit device status register.  */
51 53c25cea Paul Brook
#define VIRTIO_PCI_STATUS               18
52 53c25cea Paul Brook
53 53c25cea Paul Brook
/* An 8-bit r/o interrupt status register.  Reading the value will return the
54 53c25cea Paul Brook
 * current contents of the ISR and will also clear it.  This is effectively
55 53c25cea Paul Brook
 * a read-and-acknowledge. */
56 53c25cea Paul Brook
#define VIRTIO_PCI_ISR                  19
57 53c25cea Paul Brook
58 aba800a3 Michael S. Tsirkin
/* MSI-X registers: only enabled if MSI-X is enabled. */
59 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for configuration changes. */
60 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_CONFIG_VECTOR        20
61 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for selected queue notifications. */
62 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_QUEUE_VECTOR         22
63 aba800a3 Michael S. Tsirkin
64 aba800a3 Michael S. Tsirkin
/* Config space size */
65 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_NOMSI         20
66 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_MSI           24
67 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
68 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
69 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
70 aba800a3 Michael S. Tsirkin
71 aba800a3 Michael S. Tsirkin
/* The remaining space is defined by each driver as the per-driver
72 aba800a3 Michael S. Tsirkin
 * configuration space */
73 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
74 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
75 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
76 53c25cea Paul Brook
77 53c25cea Paul Brook
/* Virtio ABI version, if we increment this, we break the guest driver. */
78 53c25cea Paul Brook
#define VIRTIO_PCI_ABI_VERSION          0
79 53c25cea Paul Brook
80 53c25cea Paul Brook
/* How many bits to shift physical queue address written to QUEUE_PFN.
81 53c25cea Paul Brook
 * 12 is historical, and due to x86 page size. */
82 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
83 53c25cea Paul Brook
84 3dbca8e6 Stefan Hajnoczi
/* Flags track per-device state like workarounds for quirks in older guests. */
85 3dbca8e6 Stefan Hajnoczi
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
86 c81131db Alexander Graf
87 25db9ebe Stefan Hajnoczi
/* Performance improves when virtqueue kick processing is decoupled from the
88 25db9ebe Stefan Hajnoczi
 * vcpu thread using ioeventfd for some devices. */
89 25db9ebe Stefan Hajnoczi
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT 1
90 25db9ebe Stefan Hajnoczi
#define VIRTIO_PCI_FLAG_USE_IOEVENTFD   (1 << VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT)
91 25db9ebe Stefan Hajnoczi
92 53c25cea Paul Brook
/* QEMU doesn't strictly need write barriers since everything runs in
93 53c25cea Paul Brook
 * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
94 53c25cea Paul Brook
 * KVM or if kqemu gets SMP support.
95 53c25cea Paul Brook
 */
96 53c25cea Paul Brook
#define wmb() do { } while (0)
97 53c25cea Paul Brook
98 53c25cea Paul Brook
/* PCI bindings.  */
99 53c25cea Paul Brook
100 53c25cea Paul Brook
typedef struct {
101 53c25cea Paul Brook
    PCIDevice pci_dev;
102 53c25cea Paul Brook
    VirtIODevice *vdev;
103 3dbca8e6 Stefan Hajnoczi
    uint32_t flags;
104 53c25cea Paul Brook
    uint32_t addr;
105 ab73ff29 Gerd Hoffmann
    uint32_t class_code;
106 a1e0fea5 Gerd Hoffmann
    uint32_t nvectors;
107 428c149b Christoph Hellwig
    BlockConf block;
108 97b15621 Gerd Hoffmann
    NICConf nic;
109 8172539d Michael S. Tsirkin
    uint32_t host_features;
110 9f107513 Anthony Liguori
#ifdef CONFIG_LINUX
111 9f107513 Anthony Liguori
    V9fsConf fsconf;
112 9f107513 Anthony Liguori
#endif
113 6b331efb Amit Shah
    virtio_serial_conf serial;
114 f0c07c7c Alex Williamson
    virtio_net_conf net;
115 25db9ebe Stefan Hajnoczi
    bool ioeventfd_disabled;
116 25db9ebe Stefan Hajnoczi
    bool ioeventfd_started;
117 53c25cea Paul Brook
} VirtIOPCIProxy;
118 53c25cea Paul Brook
119 53c25cea Paul Brook
/* virtio device */
120 53c25cea Paul Brook
121 7055e687 Michael S. Tsirkin
static void virtio_pci_notify(void *opaque, uint16_t vector)
122 53c25cea Paul Brook
{
123 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
124 aba800a3 Michael S. Tsirkin
    if (msix_enabled(&proxy->pci_dev))
125 aba800a3 Michael S. Tsirkin
        msix_notify(&proxy->pci_dev, vector);
126 aba800a3 Michael S. Tsirkin
    else
127 aba800a3 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
128 53c25cea Paul Brook
}
129 53c25cea Paul Brook
130 ff24bd58 Michael S. Tsirkin
static void virtio_pci_save_config(void * opaque, QEMUFile *f)
131 ff24bd58 Michael S. Tsirkin
{
132 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
133 ff24bd58 Michael S. Tsirkin
    pci_device_save(&proxy->pci_dev, f);
134 ff24bd58 Michael S. Tsirkin
    msix_save(&proxy->pci_dev, f);
135 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
136 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, proxy->vdev->config_vector);
137 ff24bd58 Michael S. Tsirkin
}
138 ff24bd58 Michael S. Tsirkin
139 ff24bd58 Michael S. Tsirkin
static void virtio_pci_save_queue(void * opaque, int n, QEMUFile *f)
140 ff24bd58 Michael S. Tsirkin
{
141 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
142 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
143 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
144 ff24bd58 Michael S. Tsirkin
}
145 ff24bd58 Michael S. Tsirkin
146 ff24bd58 Michael S. Tsirkin
static int virtio_pci_load_config(void * opaque, QEMUFile *f)
147 ff24bd58 Michael S. Tsirkin
{
148 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
149 ff24bd58 Michael S. Tsirkin
    int ret;
150 ff24bd58 Michael S. Tsirkin
    ret = pci_device_load(&proxy->pci_dev, f);
151 e6da7680 Michael S. Tsirkin
    if (ret) {
152 ff24bd58 Michael S. Tsirkin
        return ret;
153 e6da7680 Michael S. Tsirkin
    }
154 ff24bd58 Michael S. Tsirkin
    msix_load(&proxy->pci_dev, f);
155 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
156 ff24bd58 Michael S. Tsirkin
        qemu_get_be16s(f, &proxy->vdev->config_vector);
157 e6da7680 Michael S. Tsirkin
    } else {
158 e6da7680 Michael S. Tsirkin
        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
159 e6da7680 Michael S. Tsirkin
    }
160 e6da7680 Michael S. Tsirkin
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
161 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
162 e6da7680 Michael S. Tsirkin
    }
163 c81131db Alexander Graf
164 c81131db Alexander Graf
    /* Try to find out if the guest has bus master disabled, but is
165 c81131db Alexander Graf
       in ready state. Then we have a buggy guest OS. */
166 8a911107 Alex Williamson
    if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
167 c81131db Alexander Graf
        !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
168 3dbca8e6 Stefan Hajnoczi
        proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
169 c81131db Alexander Graf
    }
170 ff24bd58 Michael S. Tsirkin
    return 0;
171 ff24bd58 Michael S. Tsirkin
}
172 ff24bd58 Michael S. Tsirkin
173 ff24bd58 Michael S. Tsirkin
static int virtio_pci_load_queue(void * opaque, int n, QEMUFile *f)
174 ff24bd58 Michael S. Tsirkin
{
175 ff24bd58 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
176 ff24bd58 Michael S. Tsirkin
    uint16_t vector;
177 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
178 e6da7680 Michael S. Tsirkin
        qemu_get_be16s(f, &vector);
179 e6da7680 Michael S. Tsirkin
    } else {
180 e6da7680 Michael S. Tsirkin
        vector = VIRTIO_NO_VECTOR;
181 e6da7680 Michael S. Tsirkin
    }
182 ff24bd58 Michael S. Tsirkin
    virtio_queue_set_vector(proxy->vdev, n, vector);
183 e6da7680 Michael S. Tsirkin
    if (vector != VIRTIO_NO_VECTOR) {
184 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, vector);
185 e6da7680 Michael S. Tsirkin
    }
186 ff24bd58 Michael S. Tsirkin
    return 0;
187 ff24bd58 Michael S. Tsirkin
}
188 ff24bd58 Michael S. Tsirkin
189 25db9ebe Stefan Hajnoczi
static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
190 25db9ebe Stefan Hajnoczi
                                                 int n, bool assign)
191 25db9ebe Stefan Hajnoczi
{
192 25db9ebe Stefan Hajnoczi
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
193 25db9ebe Stefan Hajnoczi
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
194 25db9ebe Stefan Hajnoczi
    int r;
195 25db9ebe Stefan Hajnoczi
    if (assign) {
196 25db9ebe Stefan Hajnoczi
        r = event_notifier_init(notifier, 1);
197 25db9ebe Stefan Hajnoczi
        if (r < 0) {
198 b36e3914 Michael S. Tsirkin
            error_report("%s: unable to init event notifier: %d",
199 b36e3914 Michael S. Tsirkin
                         __func__, r);
200 25db9ebe Stefan Hajnoczi
            return r;
201 25db9ebe Stefan Hajnoczi
        }
202 25db9ebe Stefan Hajnoczi
        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
203 25db9ebe Stefan Hajnoczi
                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
204 25db9ebe Stefan Hajnoczi
                                       n, assign);
205 25db9ebe Stefan Hajnoczi
        if (r < 0) {
206 b36e3914 Michael S. Tsirkin
            error_report("%s: unable to map ioeventfd: %d",
207 b36e3914 Michael S. Tsirkin
                         __func__, r);
208 25db9ebe Stefan Hajnoczi
            event_notifier_cleanup(notifier);
209 25db9ebe Stefan Hajnoczi
        }
210 25db9ebe Stefan Hajnoczi
    } else {
211 25db9ebe Stefan Hajnoczi
        r = kvm_set_ioeventfd_pio_word(event_notifier_get_fd(notifier),
212 25db9ebe Stefan Hajnoczi
                                       proxy->addr + VIRTIO_PCI_QUEUE_NOTIFY,
213 25db9ebe Stefan Hajnoczi
                                       n, assign);
214 25db9ebe Stefan Hajnoczi
        if (r < 0) {
215 b36e3914 Michael S. Tsirkin
            error_report("%s: unable to unmap ioeventfd: %d",
216 b36e3914 Michael S. Tsirkin
                         __func__, r);
217 25db9ebe Stefan Hajnoczi
            return r;
218 25db9ebe Stefan Hajnoczi
        }
219 25db9ebe Stefan Hajnoczi
220 25db9ebe Stefan Hajnoczi
        /* Handle the race condition where the guest kicked and we deassigned
221 25db9ebe Stefan Hajnoczi
         * before we got around to handling the kick.
222 25db9ebe Stefan Hajnoczi
         */
223 25db9ebe Stefan Hajnoczi
        if (event_notifier_test_and_clear(notifier)) {
224 25db9ebe Stefan Hajnoczi
            virtio_queue_notify_vq(vq);
225 25db9ebe Stefan Hajnoczi
        }
226 25db9ebe Stefan Hajnoczi
227 25db9ebe Stefan Hajnoczi
        event_notifier_cleanup(notifier);
228 25db9ebe Stefan Hajnoczi
    }
229 25db9ebe Stefan Hajnoczi
    return r;
230 25db9ebe Stefan Hajnoczi
}
231 25db9ebe Stefan Hajnoczi
232 25db9ebe Stefan Hajnoczi
static void virtio_pci_host_notifier_read(void *opaque)
233 25db9ebe Stefan Hajnoczi
{
234 25db9ebe Stefan Hajnoczi
    VirtQueue *vq = opaque;
235 25db9ebe Stefan Hajnoczi
    EventNotifier *n = virtio_queue_get_host_notifier(vq);
236 25db9ebe Stefan Hajnoczi
    if (event_notifier_test_and_clear(n)) {
237 25db9ebe Stefan Hajnoczi
        virtio_queue_notify_vq(vq);
238 25db9ebe Stefan Hajnoczi
    }
239 25db9ebe Stefan Hajnoczi
}
240 25db9ebe Stefan Hajnoczi
241 25db9ebe Stefan Hajnoczi
static void virtio_pci_set_host_notifier_fd_handler(VirtIOPCIProxy *proxy,
242 25db9ebe Stefan Hajnoczi
                                                    int n, bool assign)
243 25db9ebe Stefan Hajnoczi
{
244 25db9ebe Stefan Hajnoczi
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
245 25db9ebe Stefan Hajnoczi
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
246 25db9ebe Stefan Hajnoczi
    if (assign) {
247 25db9ebe Stefan Hajnoczi
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
248 25db9ebe Stefan Hajnoczi
                            virtio_pci_host_notifier_read, NULL, vq);
249 25db9ebe Stefan Hajnoczi
    } else {
250 25db9ebe Stefan Hajnoczi
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
251 25db9ebe Stefan Hajnoczi
                            NULL, NULL, NULL);
252 25db9ebe Stefan Hajnoczi
    }
253 25db9ebe Stefan Hajnoczi
}
254 25db9ebe Stefan Hajnoczi
255 b36e3914 Michael S. Tsirkin
static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
256 25db9ebe Stefan Hajnoczi
{
257 25db9ebe Stefan Hajnoczi
    int n, r;
258 25db9ebe Stefan Hajnoczi
259 25db9ebe Stefan Hajnoczi
    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
260 25db9ebe Stefan Hajnoczi
        proxy->ioeventfd_disabled ||
261 25db9ebe Stefan Hajnoczi
        proxy->ioeventfd_started) {
262 b36e3914 Michael S. Tsirkin
        return;
263 25db9ebe Stefan Hajnoczi
    }
264 25db9ebe Stefan Hajnoczi
265 25db9ebe Stefan Hajnoczi
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
266 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
267 25db9ebe Stefan Hajnoczi
            continue;
268 25db9ebe Stefan Hajnoczi
        }
269 25db9ebe Stefan Hajnoczi
270 25db9ebe Stefan Hajnoczi
        r = virtio_pci_set_host_notifier_internal(proxy, n, true);
271 25db9ebe Stefan Hajnoczi
        if (r < 0) {
272 25db9ebe Stefan Hajnoczi
            goto assign_error;
273 25db9ebe Stefan Hajnoczi
        }
274 25db9ebe Stefan Hajnoczi
275 25db9ebe Stefan Hajnoczi
        virtio_pci_set_host_notifier_fd_handler(proxy, n, true);
276 25db9ebe Stefan Hajnoczi
    }
277 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = true;
278 b36e3914 Michael S. Tsirkin
    return;
279 25db9ebe Stefan Hajnoczi
280 25db9ebe Stefan Hajnoczi
assign_error:
281 25db9ebe Stefan Hajnoczi
    while (--n >= 0) {
282 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
283 25db9ebe Stefan Hajnoczi
            continue;
284 25db9ebe Stefan Hajnoczi
        }
285 25db9ebe Stefan Hajnoczi
286 25db9ebe Stefan Hajnoczi
        virtio_pci_set_host_notifier_fd_handler(proxy, n, false);
287 b36e3914 Michael S. Tsirkin
        r = virtio_pci_set_host_notifier_internal(proxy, n, false);
288 b36e3914 Michael S. Tsirkin
        assert(r >= 0);
289 25db9ebe Stefan Hajnoczi
    }
290 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = false;
291 b36e3914 Michael S. Tsirkin
    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
292 25db9ebe Stefan Hajnoczi
}
293 25db9ebe Stefan Hajnoczi
294 b36e3914 Michael S. Tsirkin
static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
295 25db9ebe Stefan Hajnoczi
{
296 b36e3914 Michael S. Tsirkin
    int r;
297 25db9ebe Stefan Hajnoczi
    int n;
298 25db9ebe Stefan Hajnoczi
299 25db9ebe Stefan Hajnoczi
    if (!proxy->ioeventfd_started) {
300 b36e3914 Michael S. Tsirkin
        return;
301 25db9ebe Stefan Hajnoczi
    }
302 25db9ebe Stefan Hajnoczi
303 25db9ebe Stefan Hajnoczi
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
304 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
305 25db9ebe Stefan Hajnoczi
            continue;
306 25db9ebe Stefan Hajnoczi
        }
307 25db9ebe Stefan Hajnoczi
308 25db9ebe Stefan Hajnoczi
        virtio_pci_set_host_notifier_fd_handler(proxy, n, false);
309 b36e3914 Michael S. Tsirkin
        r = virtio_pci_set_host_notifier_internal(proxy, n, false);
310 b36e3914 Michael S. Tsirkin
        assert(r >= 0);
311 25db9ebe Stefan Hajnoczi
    }
312 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = false;
313 25db9ebe Stefan Hajnoczi
}
314 25db9ebe Stefan Hajnoczi
315 e489030d Michael S. Tsirkin
static void virtio_pci_reset(DeviceState *d)
316 7055e687 Michael S. Tsirkin
{
317 e489030d Michael S. Tsirkin
    VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
318 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
319 7055e687 Michael S. Tsirkin
    virtio_reset(proxy->vdev);
320 aba800a3 Michael S. Tsirkin
    msix_reset(&proxy->pci_dev);
321 25db9ebe Stefan Hajnoczi
    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
322 7055e687 Michael S. Tsirkin
}
323 7055e687 Michael S. Tsirkin
324 53c25cea Paul Brook
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
325 53c25cea Paul Brook
{
326 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
327 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
328 c227f099 Anthony Liguori
    target_phys_addr_t pa;
329 53c25cea Paul Brook
330 53c25cea Paul Brook
    switch (addr) {
331 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
332 53c25cea Paul Brook
        /* Guest does not negotiate properly?  We have to assume nothing. */
333 53c25cea Paul Brook
        if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
334 53c25cea Paul Brook
            if (vdev->bad_features)
335 8172539d Michael S. Tsirkin
                val = proxy->host_features & vdev->bad_features(vdev);
336 53c25cea Paul Brook
            else
337 53c25cea Paul Brook
                val = 0;
338 53c25cea Paul Brook
        }
339 53c25cea Paul Brook
        if (vdev->set_features)
340 53c25cea Paul Brook
            vdev->set_features(vdev, val);
341 704a76fc Michael S. Tsirkin
        vdev->guest_features = val;
342 53c25cea Paul Brook
        break;
343 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
344 c227f099 Anthony Liguori
        pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
345 1b8e9b27 Michael S. Tsirkin
        if (pa == 0) {
346 25db9ebe Stefan Hajnoczi
            virtio_pci_stop_ioeventfd(proxy);
347 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
348 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
349 1b8e9b27 Michael S. Tsirkin
        }
350 7055e687 Michael S. Tsirkin
        else
351 7055e687 Michael S. Tsirkin
            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
352 53c25cea Paul Brook
        break;
353 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
354 53c25cea Paul Brook
        if (val < VIRTIO_PCI_QUEUE_MAX)
355 53c25cea Paul Brook
            vdev->queue_sel = val;
356 53c25cea Paul Brook
        break;
357 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NOTIFY:
358 53c25cea Paul Brook
        virtio_queue_notify(vdev, val);
359 53c25cea Paul Brook
        break;
360 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
361 25db9ebe Stefan Hajnoczi
        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
362 25db9ebe Stefan Hajnoczi
            virtio_pci_stop_ioeventfd(proxy);
363 25db9ebe Stefan Hajnoczi
        }
364 25db9ebe Stefan Hajnoczi
365 3e607cb5 Michael S. Tsirkin
        virtio_set_status(vdev, val & 0xFF);
366 25db9ebe Stefan Hajnoczi
367 25db9ebe Stefan Hajnoczi
        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
368 25db9ebe Stefan Hajnoczi
            virtio_pci_start_ioeventfd(proxy);
369 25db9ebe Stefan Hajnoczi
        }
370 25db9ebe Stefan Hajnoczi
371 1b8e9b27 Michael S. Tsirkin
        if (vdev->status == 0) {
372 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
373 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
374 1b8e9b27 Michael S. Tsirkin
        }
375 c81131db Alexander Graf
376 c81131db Alexander Graf
        /* Linux before 2.6.34 sets the device as OK without enabling
377 c81131db Alexander Graf
           the PCI device bus master bit. In this case we need to disable
378 c81131db Alexander Graf
           some safety checks. */
379 c81131db Alexander Graf
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
380 c81131db Alexander Graf
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
381 3dbca8e6 Stefan Hajnoczi
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
382 c81131db Alexander Graf
        }
383 53c25cea Paul Brook
        break;
384 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
385 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
386 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
387 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
388 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
389 aba800a3 Michael S. Tsirkin
        vdev->config_vector = val;
390 aba800a3 Michael S. Tsirkin
        break;
391 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
392 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev,
393 aba800a3 Michael S. Tsirkin
                          virtio_queue_vector(vdev, vdev->queue_sel));
394 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
395 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
396 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
397 aba800a3 Michael S. Tsirkin
        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
398 aba800a3 Michael S. Tsirkin
        break;
399 aba800a3 Michael S. Tsirkin
    default:
400 4e02d460 Stefan Hajnoczi
        error_report("%s: unexpected address 0x%x value 0x%x",
401 4e02d460 Stefan Hajnoczi
                     __func__, addr, val);
402 aba800a3 Michael S. Tsirkin
        break;
403 53c25cea Paul Brook
    }
404 53c25cea Paul Brook
}
405 53c25cea Paul Brook
406 aba800a3 Michael S. Tsirkin
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
407 53c25cea Paul Brook
{
408 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
409 53c25cea Paul Brook
    uint32_t ret = 0xFFFFFFFF;
410 53c25cea Paul Brook
411 53c25cea Paul Brook
    switch (addr) {
412 53c25cea Paul Brook
    case VIRTIO_PCI_HOST_FEATURES:
413 8172539d Michael S. Tsirkin
        ret = proxy->host_features;
414 53c25cea Paul Brook
        break;
415 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
416 704a76fc Michael S. Tsirkin
        ret = vdev->guest_features;
417 53c25cea Paul Brook
        break;
418 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
419 53c25cea Paul Brook
        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
420 53c25cea Paul Brook
              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
421 53c25cea Paul Brook
        break;
422 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NUM:
423 53c25cea Paul Brook
        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
424 53c25cea Paul Brook
        break;
425 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
426 53c25cea Paul Brook
        ret = vdev->queue_sel;
427 53c25cea Paul Brook
        break;
428 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
429 53c25cea Paul Brook
        ret = vdev->status;
430 53c25cea Paul Brook
        break;
431 53c25cea Paul Brook
    case VIRTIO_PCI_ISR:
432 53c25cea Paul Brook
        /* reading from the ISR also clears it. */
433 53c25cea Paul Brook
        ret = vdev->isr;
434 53c25cea Paul Brook
        vdev->isr = 0;
435 7055e687 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], 0);
436 53c25cea Paul Brook
        break;
437 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
438 aba800a3 Michael S. Tsirkin
        ret = vdev->config_vector;
439 aba800a3 Michael S. Tsirkin
        break;
440 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
441 aba800a3 Michael S. Tsirkin
        ret = virtio_queue_vector(vdev, vdev->queue_sel);
442 aba800a3 Michael S. Tsirkin
        break;
443 53c25cea Paul Brook
    default:
444 53c25cea Paul Brook
        break;
445 53c25cea Paul Brook
    }
446 53c25cea Paul Brook
447 53c25cea Paul Brook
    return ret;
448 53c25cea Paul Brook
}
449 53c25cea Paul Brook
450 53c25cea Paul Brook
static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr)
451 53c25cea Paul Brook
{
452 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
453 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
454 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
455 aba800a3 Michael S. Tsirkin
    if (addr < config)
456 aba800a3 Michael S. Tsirkin
        return virtio_ioport_read(proxy, addr);
457 aba800a3 Michael S. Tsirkin
    addr -= config;
458 53c25cea Paul Brook
    return virtio_config_readb(proxy->vdev, addr);
459 53c25cea Paul Brook
}
460 53c25cea Paul Brook
461 53c25cea Paul Brook
static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr)
462 53c25cea Paul Brook
{
463 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
464 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
465 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
466 aba800a3 Michael S. Tsirkin
    if (addr < config)
467 aba800a3 Michael S. Tsirkin
        return virtio_ioport_read(proxy, addr);
468 aba800a3 Michael S. Tsirkin
    addr -= config;
469 53c25cea Paul Brook
    return virtio_config_readw(proxy->vdev, addr);
470 53c25cea Paul Brook
}
471 53c25cea Paul Brook
472 53c25cea Paul Brook
static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr)
473 53c25cea Paul Brook
{
474 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
475 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
476 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
477 aba800a3 Michael S. Tsirkin
    if (addr < config)
478 aba800a3 Michael S. Tsirkin
        return virtio_ioport_read(proxy, addr);
479 aba800a3 Michael S. Tsirkin
    addr -= config;
480 53c25cea Paul Brook
    return virtio_config_readl(proxy->vdev, addr);
481 53c25cea Paul Brook
}
482 53c25cea Paul Brook
483 53c25cea Paul Brook
static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
484 53c25cea Paul Brook
{
485 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
486 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
487 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
488 aba800a3 Michael S. Tsirkin
    if (addr < config) {
489 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
490 aba800a3 Michael S. Tsirkin
        return;
491 aba800a3 Michael S. Tsirkin
    }
492 aba800a3 Michael S. Tsirkin
    addr -= config;
493 53c25cea Paul Brook
    virtio_config_writeb(proxy->vdev, addr, val);
494 53c25cea Paul Brook
}
495 53c25cea Paul Brook
496 53c25cea Paul Brook
static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val)
497 53c25cea Paul Brook
{
498 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
499 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
500 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
501 aba800a3 Michael S. Tsirkin
    if (addr < config) {
502 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
503 aba800a3 Michael S. Tsirkin
        return;
504 aba800a3 Michael S. Tsirkin
    }
505 aba800a3 Michael S. Tsirkin
    addr -= config;
506 53c25cea Paul Brook
    virtio_config_writew(proxy->vdev, addr, val);
507 53c25cea Paul Brook
}
508 53c25cea Paul Brook
509 53c25cea Paul Brook
static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val)
510 53c25cea Paul Brook
{
511 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
512 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
513 aba800a3 Michael S. Tsirkin
    addr -= proxy->addr;
514 aba800a3 Michael S. Tsirkin
    if (addr < config) {
515 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
516 aba800a3 Michael S. Tsirkin
        return;
517 aba800a3 Michael S. Tsirkin
    }
518 aba800a3 Michael S. Tsirkin
    addr -= config;
519 53c25cea Paul Brook
    virtio_config_writel(proxy->vdev, addr, val);
520 53c25cea Paul Brook
}
521 53c25cea Paul Brook
522 53c25cea Paul Brook
static void virtio_map(PCIDevice *pci_dev, int region_num,
523 6e355d90 Isaku Yamahata
                       pcibus_t addr, pcibus_t size, int type)
524 53c25cea Paul Brook
{
525 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev);
526 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
527 aba800a3 Michael S. Tsirkin
    unsigned config_len = VIRTIO_PCI_REGION_SIZE(pci_dev) + vdev->config_len;
528 53c25cea Paul Brook
529 53c25cea Paul Brook
    proxy->addr = addr;
530 53c25cea Paul Brook
531 aba800a3 Michael S. Tsirkin
    register_ioport_write(addr, config_len, 1, virtio_pci_config_writeb, proxy);
532 aba800a3 Michael S. Tsirkin
    register_ioport_write(addr, config_len, 2, virtio_pci_config_writew, proxy);
533 aba800a3 Michael S. Tsirkin
    register_ioport_write(addr, config_len, 4, virtio_pci_config_writel, proxy);
534 aba800a3 Michael S. Tsirkin
    register_ioport_read(addr, config_len, 1, virtio_pci_config_readb, proxy);
535 aba800a3 Michael S. Tsirkin
    register_ioport_read(addr, config_len, 2, virtio_pci_config_readw, proxy);
536 aba800a3 Michael S. Tsirkin
    register_ioport_read(addr, config_len, 4, virtio_pci_config_readl, proxy);
537 53c25cea Paul Brook
538 aba800a3 Michael S. Tsirkin
    if (vdev->config_len)
539 53c25cea Paul Brook
        vdev->get_config(vdev, vdev->config);
540 aba800a3 Michael S. Tsirkin
}
541 aba800a3 Michael S. Tsirkin
542 aba800a3 Michael S. Tsirkin
static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
543 aba800a3 Michael S. Tsirkin
                                uint32_t val, int len)
544 aba800a3 Michael S. Tsirkin
{
545 ed757e14 Yan Vugenfirer
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
546 ed757e14 Yan Vugenfirer
547 ed757e14 Yan Vugenfirer
    if (PCI_COMMAND == address) {
548 ed757e14 Yan Vugenfirer
        if (!(val & PCI_COMMAND_MASTER)) {
549 3dbca8e6 Stefan Hajnoczi
            if (!(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
550 25db9ebe Stefan Hajnoczi
                virtio_pci_stop_ioeventfd(proxy);
551 3e607cb5 Michael S. Tsirkin
                virtio_set_status(proxy->vdev,
552 3e607cb5 Michael S. Tsirkin
                                  proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
553 c81131db Alexander Graf
            }
554 ed757e14 Yan Vugenfirer
        }
555 ed757e14 Yan Vugenfirer
    }
556 ed757e14 Yan Vugenfirer
557 aba800a3 Michael S. Tsirkin
    pci_default_write_config(pci_dev, address, val, len);
558 85352471 Michael S. Tsirkin
    msix_write_config(pci_dev, address, val, len);
559 53c25cea Paul Brook
}
560 53c25cea Paul Brook
561 6d74ca5a Michael S. Tsirkin
static unsigned virtio_pci_get_features(void *opaque)
562 6d74ca5a Michael S. Tsirkin
{
563 8172539d Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
564 8172539d Michael S. Tsirkin
    return proxy->host_features;
565 6d74ca5a Michael S. Tsirkin
}
566 6d74ca5a Michael S. Tsirkin
567 ade80dc8 Michael S. Tsirkin
static void virtio_pci_guest_notifier_read(void *opaque)
568 ade80dc8 Michael S. Tsirkin
{
569 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = opaque;
570 ade80dc8 Michael S. Tsirkin
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
571 ade80dc8 Michael S. Tsirkin
    if (event_notifier_test_and_clear(n)) {
572 ade80dc8 Michael S. Tsirkin
        virtio_irq(vq);
573 ade80dc8 Michael S. Tsirkin
    }
574 ade80dc8 Michael S. Tsirkin
}
575 ade80dc8 Michael S. Tsirkin
576 ade80dc8 Michael S. Tsirkin
static int virtio_pci_set_guest_notifier(void *opaque, int n, bool assign)
577 ade80dc8 Michael S. Tsirkin
{
578 ade80dc8 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
579 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
580 ade80dc8 Michael S. Tsirkin
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
581 ade80dc8 Michael S. Tsirkin
582 ade80dc8 Michael S. Tsirkin
    if (assign) {
583 ade80dc8 Michael S. Tsirkin
        int r = event_notifier_init(notifier, 0);
584 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
585 ade80dc8 Michael S. Tsirkin
            return r;
586 ade80dc8 Michael S. Tsirkin
        }
587 ade80dc8 Michael S. Tsirkin
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
588 ade80dc8 Michael S. Tsirkin
                            virtio_pci_guest_notifier_read, NULL, vq);
589 ade80dc8 Michael S. Tsirkin
    } else {
590 ade80dc8 Michael S. Tsirkin
        qemu_set_fd_handler(event_notifier_get_fd(notifier),
591 ade80dc8 Michael S. Tsirkin
                            NULL, NULL, NULL);
592 ade80dc8 Michael S. Tsirkin
        event_notifier_cleanup(notifier);
593 ade80dc8 Michael S. Tsirkin
    }
594 ade80dc8 Michael S. Tsirkin
595 ade80dc8 Michael S. Tsirkin
    return 0;
596 ade80dc8 Michael S. Tsirkin
}
597 ade80dc8 Michael S. Tsirkin
598 5430a28f mst@redhat.com
static bool virtio_pci_query_guest_notifiers(void *opaque)
599 5430a28f mst@redhat.com
{
600 5430a28f mst@redhat.com
    VirtIOPCIProxy *proxy = opaque;
601 5430a28f mst@redhat.com
    return msix_enabled(&proxy->pci_dev);
602 5430a28f mst@redhat.com
}
603 5430a28f mst@redhat.com
604 54dd9321 Michael S. Tsirkin
static int virtio_pci_set_guest_notifiers(void *opaque, bool assign)
605 54dd9321 Michael S. Tsirkin
{
606 54dd9321 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
607 54dd9321 Michael S. Tsirkin
    VirtIODevice *vdev = proxy->vdev;
608 54dd9321 Michael S. Tsirkin
    int r, n;
609 54dd9321 Michael S. Tsirkin
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 54dd9321 Michael S. Tsirkin
    return 0;
622 54dd9321 Michael S. Tsirkin
623 54dd9321 Michael S. Tsirkin
assign_error:
624 54dd9321 Michael S. Tsirkin
    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
625 54dd9321 Michael S. Tsirkin
    while (--n >= 0) {
626 54dd9321 Michael S. Tsirkin
        virtio_pci_set_guest_notifier(opaque, n, !assign);
627 54dd9321 Michael S. Tsirkin
    }
628 54dd9321 Michael S. Tsirkin
    return r;
629 54dd9321 Michael S. Tsirkin
}
630 54dd9321 Michael S. Tsirkin
631 ade80dc8 Michael S. Tsirkin
static int virtio_pci_set_host_notifier(void *opaque, int n, bool assign)
632 ade80dc8 Michael S. Tsirkin
{
633 ade80dc8 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = opaque;
634 25db9ebe Stefan Hajnoczi
635 25db9ebe Stefan Hajnoczi
    /* Stop using ioeventfd for virtqueue kick if the device starts using host
636 25db9ebe Stefan Hajnoczi
     * notifiers.  This makes it easy to avoid stepping on each others' toes.
637 25db9ebe Stefan Hajnoczi
     */
638 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_disabled = assign;
639 ade80dc8 Michael S. Tsirkin
    if (assign) {
640 25db9ebe Stefan Hajnoczi
        virtio_pci_stop_ioeventfd(proxy);
641 25db9ebe Stefan Hajnoczi
    }
642 25db9ebe Stefan Hajnoczi
    /* We don't need to start here: it's not needed because backend
643 25db9ebe Stefan Hajnoczi
     * currently only stops on status change away from ok,
644 25db9ebe Stefan Hajnoczi
     * reset, vmstop and such. If we do add code to start here,
645 25db9ebe Stefan Hajnoczi
     * need to check vmstate, device state etc. */
646 25db9ebe Stefan Hajnoczi
    return virtio_pci_set_host_notifier_internal(proxy, n, assign);
647 25db9ebe Stefan Hajnoczi
}
648 25db9ebe Stefan Hajnoczi
649 25db9ebe Stefan Hajnoczi
static void virtio_pci_vmstate_change(void *opaque, bool running)
650 25db9ebe Stefan Hajnoczi
{
651 25db9ebe Stefan Hajnoczi
    VirtIOPCIProxy *proxy = opaque;
652 25db9ebe Stefan Hajnoczi
653 25db9ebe Stefan Hajnoczi
    if (running) {
654 25db9ebe Stefan Hajnoczi
        virtio_pci_start_ioeventfd(proxy);
655 ade80dc8 Michael S. Tsirkin
    } else {
656 25db9ebe Stefan Hajnoczi
        virtio_pci_stop_ioeventfd(proxy);
657 ade80dc8 Michael S. Tsirkin
    }
658 ade80dc8 Michael S. Tsirkin
}
659 ade80dc8 Michael S. Tsirkin
660 53c25cea Paul Brook
static const VirtIOBindings virtio_pci_bindings = {
661 ff24bd58 Michael S. Tsirkin
    .notify = virtio_pci_notify,
662 ff24bd58 Michael S. Tsirkin
    .save_config = virtio_pci_save_config,
663 ff24bd58 Michael S. Tsirkin
    .load_config = virtio_pci_load_config,
664 ff24bd58 Michael S. Tsirkin
    .save_queue = virtio_pci_save_queue,
665 ff24bd58 Michael S. Tsirkin
    .load_queue = virtio_pci_load_queue,
666 6d74ca5a Michael S. Tsirkin
    .get_features = virtio_pci_get_features,
667 5430a28f mst@redhat.com
    .query_guest_notifiers = virtio_pci_query_guest_notifiers,
668 ade80dc8 Michael S. Tsirkin
    .set_host_notifier = virtio_pci_set_host_notifier,
669 54dd9321 Michael S. Tsirkin
    .set_guest_notifiers = virtio_pci_set_guest_notifiers,
670 25db9ebe Stefan Hajnoczi
    .vmstate_change = virtio_pci_vmstate_change,
671 53c25cea Paul Brook
};
672 53c25cea Paul Brook
673 53c25cea Paul Brook
static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev,
674 53c25cea Paul Brook
                            uint16_t vendor, uint16_t device,
675 53c25cea Paul Brook
                            uint16_t class_code, uint8_t pif)
676 53c25cea Paul Brook
{
677 53c25cea Paul Brook
    uint8_t *config;
678 53c25cea Paul Brook
    uint32_t size;
679 53c25cea Paul Brook
680 53c25cea Paul Brook
    proxy->vdev = vdev;
681 53c25cea Paul Brook
682 53c25cea Paul Brook
    config = proxy->pci_dev.config;
683 53c25cea Paul Brook
    pci_config_set_vendor_id(config, vendor);
684 53c25cea Paul Brook
    pci_config_set_device_id(config, device);
685 53c25cea Paul Brook
686 53c25cea Paul Brook
    config[0x08] = VIRTIO_PCI_ABI_VERSION;
687 53c25cea Paul Brook
688 53c25cea Paul Brook
    config[0x09] = pif;
689 53c25cea Paul Brook
    pci_config_set_class(config, class_code);
690 53c25cea Paul Brook
691 53c25cea Paul Brook
    config[0x2c] = vendor & 0xFF;
692 53c25cea Paul Brook
    config[0x2d] = (vendor >> 8) & 0xFF;
693 53c25cea Paul Brook
    config[0x2e] = vdev->device_id & 0xFF;
694 53c25cea Paul Brook
    config[0x2f] = (vdev->device_id >> 8) & 0xFF;
695 53c25cea Paul Brook
696 53c25cea Paul Brook
    config[0x3d] = 1;
697 53c25cea Paul Brook
698 5a1fc5e8 Michael S. Tsirkin
    if (vdev->nvectors && !msix_init(&proxy->pci_dev, vdev->nvectors, 1, 0)) {
699 aba800a3 Michael S. Tsirkin
        pci_register_bar(&proxy->pci_dev, 1,
700 aba800a3 Michael S. Tsirkin
                         msix_bar_size(&proxy->pci_dev),
701 0392a017 Isaku Yamahata
                         PCI_BASE_ADDRESS_SPACE_MEMORY,
702 aba800a3 Michael S. Tsirkin
                         msix_mmio_map);
703 aba800a3 Michael S. Tsirkin
    } else
704 aba800a3 Michael S. Tsirkin
        vdev->nvectors = 0;
705 aba800a3 Michael S. Tsirkin
706 ed757e14 Yan Vugenfirer
    proxy->pci_dev.config_write = virtio_write_config;
707 ed757e14 Yan Vugenfirer
708 aba800a3 Michael S. Tsirkin
    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
709 53c25cea Paul Brook
    if (size & (size-1))
710 53c25cea Paul Brook
        size = 1 << qemu_fls(size);
711 53c25cea Paul Brook
712 0392a017 Isaku Yamahata
    pci_register_bar(&proxy->pci_dev, 0, size, PCI_BASE_ADDRESS_SPACE_IO,
713 53c25cea Paul Brook
                           virtio_map);
714 53c25cea Paul Brook
715 25db9ebe Stefan Hajnoczi
    if (!kvm_has_many_ioeventfds()) {
716 25db9ebe Stefan Hajnoczi
        proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
717 25db9ebe Stefan Hajnoczi
    }
718 25db9ebe Stefan Hajnoczi
719 53c25cea Paul Brook
    virtio_bind_device(vdev, &virtio_pci_bindings, proxy);
720 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
721 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
722 8172539d Michael S. Tsirkin
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
723 53c25cea Paul Brook
}
724 53c25cea Paul Brook
725 81a322d4 Gerd Hoffmann
static int virtio_blk_init_pci(PCIDevice *pci_dev)
726 53c25cea Paul Brook
{
727 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
728 53c25cea Paul Brook
    VirtIODevice *vdev;
729 53c25cea Paul Brook
730 ab73ff29 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_STORAGE_SCSI &&
731 ab73ff29 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_STORAGE_OTHER)
732 ab73ff29 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_STORAGE_SCSI;
733 53c25cea Paul Brook
734 428c149b Christoph Hellwig
    vdev = virtio_blk_init(&pci_dev->qdev, &proxy->block);
735 ac0c14d7 Markus Armbruster
    if (!vdev) {
736 ac0c14d7 Markus Armbruster
        return -1;
737 ac0c14d7 Markus Armbruster
    }
738 177539e0 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
739 53c25cea Paul Brook
    virtio_init_pci(proxy, vdev,
740 53c25cea Paul Brook
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
741 85c2c735 Mark McLoughlin
                    PCI_DEVICE_ID_VIRTIO_BLOCK,
742 85c2c735 Mark McLoughlin
                    proxy->class_code, 0x00);
743 177539e0 Gerd Hoffmann
    /* make the actual value visible */
744 177539e0 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
745 81a322d4 Gerd Hoffmann
    return 0;
746 21d58b57 Mark McLoughlin
}
747 21d58b57 Mark McLoughlin
748 0f457d91 Michael S. Tsirkin
static int virtio_exit_pci(PCIDevice *pci_dev)
749 0f457d91 Michael S. Tsirkin
{
750 0f457d91 Michael S. Tsirkin
    return msix_uninit(pci_dev);
751 0f457d91 Michael S. Tsirkin
}
752 0f457d91 Michael S. Tsirkin
753 56a14938 Gerd Hoffmann
static int virtio_blk_exit_pci(PCIDevice *pci_dev)
754 56a14938 Gerd Hoffmann
{
755 56a14938 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
756 56a14938 Gerd Hoffmann
757 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
758 9d0d3138 Alex Williamson
    virtio_blk_exit(proxy->vdev);
759 f8b6cc00 Markus Armbruster
    blockdev_mark_auto_del(proxy->block.bs);
760 0f457d91 Michael S. Tsirkin
    return virtio_exit_pci(pci_dev);
761 56a14938 Gerd Hoffmann
}
762 56a14938 Gerd Hoffmann
763 98b19252 Amit Shah
static int virtio_serial_init_pci(PCIDevice *pci_dev)
764 21d58b57 Mark McLoughlin
{
765 d6beee99 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
766 85c2c735 Mark McLoughlin
    VirtIODevice *vdev;
767 85c2c735 Mark McLoughlin
768 d6beee99 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
769 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
770 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
771 d6beee99 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
772 d6beee99 Gerd Hoffmann
773 6b331efb Amit Shah
    vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
774 25fe3654 Amit Shah
    if (!vdev) {
775 25fe3654 Amit Shah
        return -1;
776 25fe3654 Amit Shah
    }
777 573fb60c Amit Shah
    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
778 6b331efb Amit Shah
                                        ? proxy->serial.max_virtserial_ports + 1
779 573fb60c Amit Shah
                                        : proxy->nvectors;
780 85c2c735 Mark McLoughlin
    virtio_init_pci(proxy, vdev,
781 85c2c735 Mark McLoughlin
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
782 85c2c735 Mark McLoughlin
                    PCI_DEVICE_ID_VIRTIO_CONSOLE,
783 85c2c735 Mark McLoughlin
                    proxy->class_code, 0x00);
784 a1829205 Amit Shah
    proxy->nvectors = vdev->nvectors;
785 81a322d4 Gerd Hoffmann
    return 0;
786 53c25cea Paul Brook
}
787 53c25cea Paul Brook
788 8b53a865 Amit Shah
static int virtio_serial_exit_pci(PCIDevice *pci_dev)
789 8b53a865 Amit Shah
{
790 8b53a865 Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
791 8b53a865 Amit Shah
792 32059220 Amit Shah
    virtio_pci_stop_ioeventfd(proxy);
793 8b53a865 Amit Shah
    virtio_serial_exit(proxy->vdev);
794 8b53a865 Amit Shah
    return virtio_exit_pci(pci_dev);
795 8b53a865 Amit Shah
}
796 8b53a865 Amit Shah
797 81a322d4 Gerd Hoffmann
static int virtio_net_init_pci(PCIDevice *pci_dev)
798 53c25cea Paul Brook
{
799 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
800 53c25cea Paul Brook
    VirtIODevice *vdev;
801 53c25cea Paul Brook
802 f0c07c7c Alex Williamson
    vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net);
803 a1e0fea5 Gerd Hoffmann
804 97b15621 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
805 53c25cea Paul Brook
    virtio_init_pci(proxy, vdev,
806 53c25cea Paul Brook
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
807 53c25cea Paul Brook
                    PCI_DEVICE_ID_VIRTIO_NET,
808 53c25cea Paul Brook
                    PCI_CLASS_NETWORK_ETHERNET,
809 53c25cea Paul Brook
                    0x00);
810 a1e0fea5 Gerd Hoffmann
811 a1e0fea5 Gerd Hoffmann
    /* make the actual value visible */
812 a1e0fea5 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
813 81a322d4 Gerd Hoffmann
    return 0;
814 53c25cea Paul Brook
}
815 53c25cea Paul Brook
816 97b15621 Gerd Hoffmann
static int virtio_net_exit_pci(PCIDevice *pci_dev)
817 97b15621 Gerd Hoffmann
{
818 97b15621 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
819 97b15621 Gerd Hoffmann
820 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
821 97b15621 Gerd Hoffmann
    virtio_net_exit(proxy->vdev);
822 97b15621 Gerd Hoffmann
    return virtio_exit_pci(pci_dev);
823 97b15621 Gerd Hoffmann
}
824 97b15621 Gerd Hoffmann
825 81a322d4 Gerd Hoffmann
static int virtio_balloon_init_pci(PCIDevice *pci_dev)
826 53c25cea Paul Brook
{
827 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
828 53c25cea Paul Brook
    VirtIODevice *vdev;
829 53c25cea Paul Brook
830 53c25cea Paul Brook
    vdev = virtio_balloon_init(&pci_dev->qdev);
831 53c25cea Paul Brook
    virtio_init_pci(proxy, vdev,
832 53c25cea Paul Brook
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
833 53c25cea Paul Brook
                    PCI_DEVICE_ID_VIRTIO_BALLOON,
834 53c25cea Paul Brook
                    PCI_CLASS_MEMORY_RAM,
835 53c25cea Paul Brook
                    0x00);
836 81a322d4 Gerd Hoffmann
    return 0;
837 53c25cea Paul Brook
}
838 53c25cea Paul Brook
839 758e8e38 Venkateswararao Jujjuri (JV)
#ifdef CONFIG_VIRTFS
840 9f107513 Anthony Liguori
static int virtio_9p_init_pci(PCIDevice *pci_dev)
841 9f107513 Anthony Liguori
{
842 9f107513 Anthony Liguori
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
843 9f107513 Anthony Liguori
    VirtIODevice *vdev;
844 9f107513 Anthony Liguori
845 9f107513 Anthony Liguori
    vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
846 9dbcca5a Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
847 9f107513 Anthony Liguori
    virtio_init_pci(proxy, vdev,
848 9f107513 Anthony Liguori
                    PCI_VENDOR_ID_REDHAT_QUMRANET,
849 9f107513 Anthony Liguori
                    0x1009,
850 9f107513 Anthony Liguori
                    0x2,
851 9f107513 Anthony Liguori
                    0x00);
852 9dbcca5a Gerd Hoffmann
    /* make the actual value visible */
853 9dbcca5a Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
854 9f107513 Anthony Liguori
    return 0;
855 9f107513 Anthony Liguori
}
856 9f107513 Anthony Liguori
#endif
857 9f107513 Anthony Liguori
858 0aab0d3a Gerd Hoffmann
static PCIDeviceInfo virtio_info[] = {
859 0aab0d3a Gerd Hoffmann
    {
860 0aab0d3a Gerd Hoffmann
        .qdev.name = "virtio-blk-pci",
861 779206de Gleb Natapov
        .qdev.alias = "virtio-blk",
862 0aab0d3a Gerd Hoffmann
        .qdev.size = sizeof(VirtIOPCIProxy),
863 0aab0d3a Gerd Hoffmann
        .init      = virtio_blk_init_pci,
864 56a14938 Gerd Hoffmann
        .exit      = virtio_blk_exit_pci,
865 ab73ff29 Gerd Hoffmann
        .qdev.props = (Property[]) {
866 72c61d0b Gerd Hoffmann
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
867 428c149b Christoph Hellwig
            DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
868 25db9ebe Stefan Hajnoczi
            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
869 25db9ebe Stefan Hajnoczi
                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
870 177539e0 Gerd Hoffmann
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
871 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
872 72c61d0b Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
873 ab73ff29 Gerd Hoffmann
        },
874 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
875 0aab0d3a Gerd Hoffmann
    },{
876 a1e0fea5 Gerd Hoffmann
        .qdev.name  = "virtio-net-pci",
877 a1e0fea5 Gerd Hoffmann
        .qdev.size  = sizeof(VirtIOPCIProxy),
878 a1e0fea5 Gerd Hoffmann
        .init       = virtio_net_init_pci,
879 97b15621 Gerd Hoffmann
        .exit       = virtio_net_exit_pci,
880 8c52c8f3 Gerd Hoffmann
        .romfile    = "pxe-virtio.bin",
881 a1e0fea5 Gerd Hoffmann
        .qdev.props = (Property[]) {
882 25db9ebe Stefan Hajnoczi
            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
883 25db9ebe Stefan Hajnoczi
                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
884 97b15621 Gerd Hoffmann
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
885 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
886 97b15621 Gerd Hoffmann
            DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
887 f0c07c7c Alex Williamson
            DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy,
888 f0c07c7c Alex Williamson
                               net.txtimer, TX_TIMER_INTERVAL),
889 e3f30488 Alex Williamson
            DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy,
890 e3f30488 Alex Williamson
                              net.txburst, TX_BURST),
891 a697a334 Alex Williamson
            DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
892 72c61d0b Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
893 a1e0fea5 Gerd Hoffmann
        },
894 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
895 0aab0d3a Gerd Hoffmann
    },{
896 98b19252 Amit Shah
        .qdev.name = "virtio-serial-pci",
897 98b19252 Amit Shah
        .qdev.alias = "virtio-serial",
898 0aab0d3a Gerd Hoffmann
        .qdev.size = sizeof(VirtIOPCIProxy),
899 98b19252 Amit Shah
        .init      = virtio_serial_init_pci,
900 8b53a865 Amit Shah
        .exit      = virtio_serial_exit_pci,
901 d6beee99 Gerd Hoffmann
        .qdev.props = (Property[]) {
902 32059220 Amit Shah
            DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
903 32059220 Amit Shah
                            VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
904 573fb60c Amit Shah
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
905 573fb60c Amit Shah
                               DEV_NVECTORS_UNSPECIFIED),
906 72c61d0b Gerd Hoffmann
            DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
907 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
908 6b331efb Amit Shah
            DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy,
909 6b331efb Amit Shah
                               serial.max_virtserial_ports, 31),
910 72c61d0b Gerd Hoffmann
            DEFINE_PROP_END_OF_LIST(),
911 d6beee99 Gerd Hoffmann
        },
912 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
913 0aab0d3a Gerd Hoffmann
    },{
914 0aab0d3a Gerd Hoffmann
        .qdev.name = "virtio-balloon-pci",
915 0aab0d3a Gerd Hoffmann
        .qdev.size = sizeof(VirtIOPCIProxy),
916 0aab0d3a Gerd Hoffmann
        .init      = virtio_balloon_init_pci,
917 0f457d91 Michael S. Tsirkin
        .exit      = virtio_exit_pci,
918 8172539d Michael S. Tsirkin
        .qdev.props = (Property[]) {
919 8172539d Michael S. Tsirkin
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
920 8172539d Michael S. Tsirkin
            DEFINE_PROP_END_OF_LIST(),
921 8172539d Michael S. Tsirkin
        },
922 e489030d Michael S. Tsirkin
        .qdev.reset = virtio_pci_reset,
923 0aab0d3a Gerd Hoffmann
    },{
924 758e8e38 Venkateswararao Jujjuri (JV)
#ifdef CONFIG_VIRTFS
925 9f107513 Anthony Liguori
        .qdev.name = "virtio-9p-pci",
926 9f107513 Anthony Liguori
        .qdev.size = sizeof(VirtIOPCIProxy),
927 9f107513 Anthony Liguori
        .init      = virtio_9p_init_pci,
928 9f107513 Anthony Liguori
        .qdev.props = (Property[]) {
929 9dbcca5a Gerd Hoffmann
            DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
930 9f107513 Anthony Liguori
            DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
931 9f107513 Anthony Liguori
            DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
932 9f107513 Anthony Liguori
            DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
933 9f107513 Anthony Liguori
            DEFINE_PROP_END_OF_LIST(),
934 9f107513 Anthony Liguori
        },
935 9f107513 Anthony Liguori
    }, {
936 9f107513 Anthony Liguori
#endif
937 0aab0d3a Gerd Hoffmann
        /* end of list */
938 0aab0d3a Gerd Hoffmann
    }
939 0aab0d3a Gerd Hoffmann
};
940 0aab0d3a Gerd Hoffmann
941 53c25cea Paul Brook
static void virtio_pci_register_devices(void)
942 53c25cea Paul Brook
{
943 0aab0d3a Gerd Hoffmann
    pci_qdev_register_many(virtio_info);
944 53c25cea Paul Brook
}
945 53c25cea Paul Brook
946 53c25cea Paul Brook
device_init(virtio_pci_register_devices)