Statistics
| Branch: | Revision:

root / hw / virtio-pci.c @ 4ab0ba9e

History | View | Annotate | Download (28.1 kB)

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