Statistics
| Branch: | Revision:

root / hw / virtio-pci.c @ 0200db65

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