Statistics
| Branch: | Revision:

root / hw / virtio-pci.c @ ba7cb5a8

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