Statistics
| Branch: | Revision:

root / hw / virtio / virtio-pci.c @ 22773d60

History | View | Annotate | Download (47.7 kB)

1 53c25cea Paul Brook
/*
2 53c25cea Paul Brook
 * Virtio PCI Bindings
3 53c25cea Paul Brook
 *
4 53c25cea Paul Brook
 * Copyright IBM, Corp. 2007
5 53c25cea Paul Brook
 * Copyright (c) 2009 CodeSourcery
6 53c25cea Paul Brook
 *
7 53c25cea Paul Brook
 * Authors:
8 53c25cea Paul Brook
 *  Anthony Liguori   <aliguori@us.ibm.com>
9 53c25cea Paul Brook
 *  Paul Brook        <paul@codesourcery.com>
10 53c25cea Paul Brook
 *
11 53c25cea Paul Brook
 * This work is licensed under the terms of the GNU GPL, version 2.  See
12 53c25cea Paul Brook
 * the COPYING file in the top-level directory.
13 53c25cea Paul Brook
 *
14 6b620ca3 Paolo Bonzini
 * Contributions after 2012-01-13 are licensed under the terms of the
15 6b620ca3 Paolo Bonzini
 * GNU GPL, version 2 or (at your option) any later version.
16 53c25cea Paul Brook
 */
17 53c25cea Paul Brook
18 53c25cea Paul Brook
#include <inttypes.h>
19 53c25cea Paul Brook
20 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio.h"
21 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio-blk.h"
22 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio-net.h"
23 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio-serial.h"
24 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio-scsi.h"
25 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio-balloon.h"
26 83c9f4ca Paolo Bonzini
#include "hw/pci/pci.h"
27 1de7afc9 Paolo Bonzini
#include "qemu/error-report.h"
28 83c9f4ca Paolo Bonzini
#include "hw/pci/msi.h"
29 83c9f4ca Paolo Bonzini
#include "hw/pci/msix.h"
30 83c9f4ca Paolo Bonzini
#include "hw/loader.h"
31 9c17d615 Paolo Bonzini
#include "sysemu/kvm.h"
32 9c17d615 Paolo Bonzini
#include "sysemu/blockdev.h"
33 47b43a1f Paolo Bonzini
#include "virtio-pci.h"
34 1de7afc9 Paolo Bonzini
#include "qemu/range.h"
35 0d09e41a Paolo Bonzini
#include "hw/virtio/virtio-bus.h"
36 53c25cea Paul Brook
37 53c25cea Paul Brook
/* from Linux's linux/virtio_pci.h */
38 53c25cea Paul Brook
39 53c25cea Paul Brook
/* A 32-bit r/o bitmask of the features supported by the host */
40 53c25cea Paul Brook
#define VIRTIO_PCI_HOST_FEATURES        0
41 53c25cea Paul Brook
42 53c25cea Paul Brook
/* A 32-bit r/w bitmask of features activated by the guest */
43 53c25cea Paul Brook
#define VIRTIO_PCI_GUEST_FEATURES       4
44 53c25cea Paul Brook
45 53c25cea Paul Brook
/* A 32-bit r/w PFN for the currently selected queue */
46 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_PFN            8
47 53c25cea Paul Brook
48 53c25cea Paul Brook
/* A 16-bit r/o queue size for the currently selected queue */
49 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NUM            12
50 53c25cea Paul Brook
51 53c25cea Paul Brook
/* A 16-bit r/w queue selector */
52 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_SEL            14
53 53c25cea Paul Brook
54 53c25cea Paul Brook
/* A 16-bit r/w queue notifier */
55 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_NOTIFY         16
56 53c25cea Paul Brook
57 53c25cea Paul Brook
/* An 8-bit device status register.  */
58 53c25cea Paul Brook
#define VIRTIO_PCI_STATUS               18
59 53c25cea Paul Brook
60 53c25cea Paul Brook
/* An 8-bit r/o interrupt status register.  Reading the value will return the
61 53c25cea Paul Brook
 * current contents of the ISR and will also clear it.  This is effectively
62 53c25cea Paul Brook
 * a read-and-acknowledge. */
63 53c25cea Paul Brook
#define VIRTIO_PCI_ISR                  19
64 53c25cea Paul Brook
65 aba800a3 Michael S. Tsirkin
/* MSI-X registers: only enabled if MSI-X is enabled. */
66 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for configuration changes. */
67 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_CONFIG_VECTOR        20
68 aba800a3 Michael S. Tsirkin
/* A 16-bit vector for selected queue notifications. */
69 aba800a3 Michael S. Tsirkin
#define VIRTIO_MSI_QUEUE_VECTOR         22
70 aba800a3 Michael S. Tsirkin
71 aba800a3 Michael S. Tsirkin
/* Config space size */
72 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_NOMSI         20
73 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG_MSI           24
74 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_REGION_SIZE(dev)     (msix_present(dev) ? \
75 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
76 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
77 aba800a3 Michael S. Tsirkin
78 aba800a3 Michael S. Tsirkin
/* The remaining space is defined by each driver as the per-driver
79 aba800a3 Michael S. Tsirkin
 * configuration space */
80 aba800a3 Michael S. Tsirkin
#define VIRTIO_PCI_CONFIG(dev)          (msix_enabled(dev) ? \
81 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_MSI : \
82 aba800a3 Michael S. Tsirkin
                                         VIRTIO_PCI_CONFIG_NOMSI)
83 53c25cea Paul Brook
84 53c25cea Paul Brook
/* How many bits to shift physical queue address written to QUEUE_PFN.
85 53c25cea Paul Brook
 * 12 is historical, and due to x86 page size. */
86 53c25cea Paul Brook
#define VIRTIO_PCI_QUEUE_ADDR_SHIFT    12
87 53c25cea Paul Brook
88 3dbca8e6 Stefan Hajnoczi
/* Flags track per-device state like workarounds for quirks in older guests. */
89 3dbca8e6 Stefan Hajnoczi
#define VIRTIO_PCI_FLAG_BUS_MASTER_BUG  (1 << 0)
90 c81131db Alexander Graf
91 53c25cea Paul Brook
/* QEMU doesn't strictly need write barriers since everything runs in
92 53c25cea Paul Brook
 * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
93 53c25cea Paul Brook
 * KVM or if kqemu gets SMP support.
94 53c25cea Paul Brook
 */
95 53c25cea Paul Brook
#define wmb() do { } while (0)
96 53c25cea Paul Brook
97 8e4a424b Blue Swirl
/* HACK for virtio to determine if it's running a big endian guest */
98 8e4a424b Blue Swirl
bool virtio_is_big_endian(void);
99 8e4a424b Blue Swirl
100 53c25cea Paul Brook
/* virtio device */
101 d2a0ccc6 Michael S. Tsirkin
/* DeviceState to VirtIOPCIProxy. For use off data-path. TODO: use QOM. */
102 d2a0ccc6 Michael S. Tsirkin
static inline VirtIOPCIProxy *to_virtio_pci_proxy(DeviceState *d)
103 d2a0ccc6 Michael S. Tsirkin
{
104 d2a0ccc6 Michael S. Tsirkin
    return container_of(d, VirtIOPCIProxy, pci_dev.qdev);
105 d2a0ccc6 Michael S. Tsirkin
}
106 53c25cea Paul Brook
107 d2a0ccc6 Michael S. Tsirkin
/* DeviceState to VirtIOPCIProxy. Note: used on datapath,
108 d2a0ccc6 Michael S. Tsirkin
 * be careful and test performance if you change this.
109 d2a0ccc6 Michael S. Tsirkin
 */
110 d2a0ccc6 Michael S. Tsirkin
static inline VirtIOPCIProxy *to_virtio_pci_proxy_fast(DeviceState *d)
111 53c25cea Paul Brook
{
112 d2a0ccc6 Michael S. Tsirkin
    return container_of(d, VirtIOPCIProxy, pci_dev.qdev);
113 d2a0ccc6 Michael S. Tsirkin
}
114 d2a0ccc6 Michael S. Tsirkin
115 d2a0ccc6 Michael S. Tsirkin
static void virtio_pci_notify(DeviceState *d, uint16_t vector)
116 d2a0ccc6 Michael S. Tsirkin
{
117 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy_fast(d);
118 aba800a3 Michael S. Tsirkin
    if (msix_enabled(&proxy->pci_dev))
119 aba800a3 Michael S. Tsirkin
        msix_notify(&proxy->pci_dev, vector);
120 aba800a3 Michael S. Tsirkin
    else
121 aba800a3 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1);
122 53c25cea Paul Brook
}
123 53c25cea Paul Brook
124 d2a0ccc6 Michael S. Tsirkin
static void virtio_pci_save_config(DeviceState *d, QEMUFile *f)
125 ff24bd58 Michael S. Tsirkin
{
126 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
127 ff24bd58 Michael S. Tsirkin
    pci_device_save(&proxy->pci_dev, f);
128 ff24bd58 Michael S. Tsirkin
    msix_save(&proxy->pci_dev, f);
129 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
130 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, proxy->vdev->config_vector);
131 ff24bd58 Michael S. Tsirkin
}
132 ff24bd58 Michael S. Tsirkin
133 d2a0ccc6 Michael S. Tsirkin
static void virtio_pci_save_queue(DeviceState *d, int n, QEMUFile *f)
134 ff24bd58 Michael S. Tsirkin
{
135 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
136 ff24bd58 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev))
137 ff24bd58 Michael S. Tsirkin
        qemu_put_be16(f, virtio_queue_vector(proxy->vdev, n));
138 ff24bd58 Michael S. Tsirkin
}
139 ff24bd58 Michael S. Tsirkin
140 d2a0ccc6 Michael S. Tsirkin
static int virtio_pci_load_config(DeviceState *d, QEMUFile *f)
141 ff24bd58 Michael S. Tsirkin
{
142 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
143 ff24bd58 Michael S. Tsirkin
    int ret;
144 ff24bd58 Michael S. Tsirkin
    ret = pci_device_load(&proxy->pci_dev, f);
145 e6da7680 Michael S. Tsirkin
    if (ret) {
146 ff24bd58 Michael S. Tsirkin
        return ret;
147 e6da7680 Michael S. Tsirkin
    }
148 3cac001e Michael S. Tsirkin
    msix_unuse_all_vectors(&proxy->pci_dev);
149 ff24bd58 Michael S. Tsirkin
    msix_load(&proxy->pci_dev, f);
150 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
151 ff24bd58 Michael S. Tsirkin
        qemu_get_be16s(f, &proxy->vdev->config_vector);
152 e6da7680 Michael S. Tsirkin
    } else {
153 e6da7680 Michael S. Tsirkin
        proxy->vdev->config_vector = VIRTIO_NO_VECTOR;
154 e6da7680 Michael S. Tsirkin
    }
155 e6da7680 Michael S. Tsirkin
    if (proxy->vdev->config_vector != VIRTIO_NO_VECTOR) {
156 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, proxy->vdev->config_vector);
157 e6da7680 Michael S. Tsirkin
    }
158 ff24bd58 Michael S. Tsirkin
    return 0;
159 ff24bd58 Michael S. Tsirkin
}
160 ff24bd58 Michael S. Tsirkin
161 d2a0ccc6 Michael S. Tsirkin
static int virtio_pci_load_queue(DeviceState *d, int n, QEMUFile *f)
162 ff24bd58 Michael S. Tsirkin
{
163 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
164 ff24bd58 Michael S. Tsirkin
    uint16_t vector;
165 e6da7680 Michael S. Tsirkin
    if (msix_present(&proxy->pci_dev)) {
166 e6da7680 Michael S. Tsirkin
        qemu_get_be16s(f, &vector);
167 e6da7680 Michael S. Tsirkin
    } else {
168 e6da7680 Michael S. Tsirkin
        vector = VIRTIO_NO_VECTOR;
169 e6da7680 Michael S. Tsirkin
    }
170 ff24bd58 Michael S. Tsirkin
    virtio_queue_set_vector(proxy->vdev, n, vector);
171 e6da7680 Michael S. Tsirkin
    if (vector != VIRTIO_NO_VECTOR) {
172 e6da7680 Michael S. Tsirkin
        return msix_vector_use(&proxy->pci_dev, vector);
173 e6da7680 Michael S. Tsirkin
    }
174 ff24bd58 Michael S. Tsirkin
    return 0;
175 ff24bd58 Michael S. Tsirkin
}
176 ff24bd58 Michael S. Tsirkin
177 25db9ebe Stefan Hajnoczi
static int virtio_pci_set_host_notifier_internal(VirtIOPCIProxy *proxy,
178 26b9b5fe Paolo Bonzini
                                                 int n, bool assign, bool set_handler)
179 25db9ebe Stefan Hajnoczi
{
180 25db9ebe Stefan Hajnoczi
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
181 25db9ebe Stefan Hajnoczi
    EventNotifier *notifier = virtio_queue_get_host_notifier(vq);
182 da146d0a Avi Kivity
    int r = 0;
183 da146d0a Avi Kivity
184 25db9ebe Stefan Hajnoczi
    if (assign) {
185 25db9ebe Stefan Hajnoczi
        r = event_notifier_init(notifier, 1);
186 25db9ebe Stefan Hajnoczi
        if (r < 0) {
187 b36e3914 Michael S. Tsirkin
            error_report("%s: unable to init event notifier: %d",
188 b36e3914 Michael S. Tsirkin
                         __func__, r);
189 25db9ebe Stefan Hajnoczi
            return r;
190 25db9ebe Stefan Hajnoczi
        }
191 26b9b5fe Paolo Bonzini
        virtio_queue_set_host_notifier_fd_handler(vq, true, set_handler);
192 da146d0a Avi Kivity
        memory_region_add_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
193 753d5e14 Paolo Bonzini
                                  true, n, notifier);
194 25db9ebe Stefan Hajnoczi
    } else {
195 da146d0a Avi Kivity
        memory_region_del_eventfd(&proxy->bar, VIRTIO_PCI_QUEUE_NOTIFY, 2,
196 753d5e14 Paolo Bonzini
                                  true, n, notifier);
197 26b9b5fe Paolo Bonzini
        virtio_queue_set_host_notifier_fd_handler(vq, false, false);
198 25db9ebe Stefan Hajnoczi
        event_notifier_cleanup(notifier);
199 25db9ebe Stefan Hajnoczi
    }
200 25db9ebe Stefan Hajnoczi
    return r;
201 25db9ebe Stefan Hajnoczi
}
202 25db9ebe Stefan Hajnoczi
203 b36e3914 Michael S. Tsirkin
static void virtio_pci_start_ioeventfd(VirtIOPCIProxy *proxy)
204 25db9ebe Stefan Hajnoczi
{
205 25db9ebe Stefan Hajnoczi
    int n, r;
206 25db9ebe Stefan Hajnoczi
207 25db9ebe Stefan Hajnoczi
    if (!(proxy->flags & VIRTIO_PCI_FLAG_USE_IOEVENTFD) ||
208 25db9ebe Stefan Hajnoczi
        proxy->ioeventfd_disabled ||
209 25db9ebe Stefan Hajnoczi
        proxy->ioeventfd_started) {
210 b36e3914 Michael S. Tsirkin
        return;
211 25db9ebe Stefan Hajnoczi
    }
212 25db9ebe Stefan Hajnoczi
213 25db9ebe Stefan Hajnoczi
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
214 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
215 25db9ebe Stefan Hajnoczi
            continue;
216 25db9ebe Stefan Hajnoczi
        }
217 25db9ebe Stefan Hajnoczi
218 26b9b5fe Paolo Bonzini
        r = virtio_pci_set_host_notifier_internal(proxy, n, true, true);
219 25db9ebe Stefan Hajnoczi
        if (r < 0) {
220 25db9ebe Stefan Hajnoczi
            goto assign_error;
221 25db9ebe Stefan Hajnoczi
        }
222 25db9ebe Stefan Hajnoczi
    }
223 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = true;
224 b36e3914 Michael S. Tsirkin
    return;
225 25db9ebe Stefan Hajnoczi
226 25db9ebe Stefan Hajnoczi
assign_error:
227 25db9ebe Stefan Hajnoczi
    while (--n >= 0) {
228 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
229 25db9ebe Stefan Hajnoczi
            continue;
230 25db9ebe Stefan Hajnoczi
        }
231 25db9ebe Stefan Hajnoczi
232 26b9b5fe Paolo Bonzini
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
233 b36e3914 Michael S. Tsirkin
        assert(r >= 0);
234 25db9ebe Stefan Hajnoczi
    }
235 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = false;
236 b36e3914 Michael S. Tsirkin
    error_report("%s: failed. Fallback to a userspace (slower).", __func__);
237 25db9ebe Stefan Hajnoczi
}
238 25db9ebe Stefan Hajnoczi
239 b36e3914 Michael S. Tsirkin
static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
240 25db9ebe Stefan Hajnoczi
{
241 b36e3914 Michael S. Tsirkin
    int r;
242 25db9ebe Stefan Hajnoczi
    int n;
243 25db9ebe Stefan Hajnoczi
244 25db9ebe Stefan Hajnoczi
    if (!proxy->ioeventfd_started) {
245 b36e3914 Michael S. Tsirkin
        return;
246 25db9ebe Stefan Hajnoczi
    }
247 25db9ebe Stefan Hajnoczi
248 25db9ebe Stefan Hajnoczi
    for (n = 0; n < VIRTIO_PCI_QUEUE_MAX; n++) {
249 25db9ebe Stefan Hajnoczi
        if (!virtio_queue_get_num(proxy->vdev, n)) {
250 25db9ebe Stefan Hajnoczi
            continue;
251 25db9ebe Stefan Hajnoczi
        }
252 25db9ebe Stefan Hajnoczi
253 26b9b5fe Paolo Bonzini
        r = virtio_pci_set_host_notifier_internal(proxy, n, false, false);
254 b36e3914 Michael S. Tsirkin
        assert(r >= 0);
255 25db9ebe Stefan Hajnoczi
    }
256 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_started = false;
257 25db9ebe Stefan Hajnoczi
}
258 25db9ebe Stefan Hajnoczi
259 60653b28 Paolo Bonzini
static void virtio_pci_reset(DeviceState *d)
260 7055e687 Michael S. Tsirkin
{
261 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
262 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
263 7055e687 Michael S. Tsirkin
    virtio_reset(proxy->vdev);
264 3cac001e Michael S. Tsirkin
    msix_unuse_all_vectors(&proxy->pci_dev);
265 25db9ebe Stefan Hajnoczi
    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
266 7055e687 Michael S. Tsirkin
}
267 7055e687 Michael S. Tsirkin
268 53c25cea Paul Brook
static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
269 53c25cea Paul Brook
{
270 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
271 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
272 a8170e5e Avi Kivity
    hwaddr pa;
273 53c25cea Paul Brook
274 53c25cea Paul Brook
    switch (addr) {
275 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
276 53c25cea Paul Brook
        /* Guest does not negotiate properly?  We have to assume nothing. */
277 53c25cea Paul Brook
        if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
278 ad0c9332 Paolo Bonzini
            val = vdev->bad_features ? vdev->bad_features(vdev) : 0;
279 53c25cea Paul Brook
        }
280 ad0c9332 Paolo Bonzini
        virtio_set_features(vdev, val);
281 53c25cea Paul Brook
        break;
282 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
283 a8170e5e Avi Kivity
        pa = (hwaddr)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT;
284 1b8e9b27 Michael S. Tsirkin
        if (pa == 0) {
285 25db9ebe Stefan Hajnoczi
            virtio_pci_stop_ioeventfd(proxy);
286 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
287 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
288 1b8e9b27 Michael S. Tsirkin
        }
289 7055e687 Michael S. Tsirkin
        else
290 7055e687 Michael S. Tsirkin
            virtio_queue_set_addr(vdev, vdev->queue_sel, pa);
291 53c25cea Paul Brook
        break;
292 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
293 53c25cea Paul Brook
        if (val < VIRTIO_PCI_QUEUE_MAX)
294 53c25cea Paul Brook
            vdev->queue_sel = val;
295 53c25cea Paul Brook
        break;
296 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NOTIFY:
297 7157e2e2 Stefan Hajnoczi
        if (val < VIRTIO_PCI_QUEUE_MAX) {
298 7157e2e2 Stefan Hajnoczi
            virtio_queue_notify(vdev, val);
299 7157e2e2 Stefan Hajnoczi
        }
300 53c25cea Paul Brook
        break;
301 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
302 25db9ebe Stefan Hajnoczi
        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {
303 25db9ebe Stefan Hajnoczi
            virtio_pci_stop_ioeventfd(proxy);
304 25db9ebe Stefan Hajnoczi
        }
305 25db9ebe Stefan Hajnoczi
306 3e607cb5 Michael S. Tsirkin
        virtio_set_status(vdev, val & 0xFF);
307 25db9ebe Stefan Hajnoczi
308 25db9ebe Stefan Hajnoczi
        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
309 25db9ebe Stefan Hajnoczi
            virtio_pci_start_ioeventfd(proxy);
310 25db9ebe Stefan Hajnoczi
        }
311 25db9ebe Stefan Hajnoczi
312 1b8e9b27 Michael S. Tsirkin
        if (vdev->status == 0) {
313 1b8e9b27 Michael S. Tsirkin
            virtio_reset(proxy->vdev);
314 1b8e9b27 Michael S. Tsirkin
            msix_unuse_all_vectors(&proxy->pci_dev);
315 1b8e9b27 Michael S. Tsirkin
        }
316 c81131db Alexander Graf
317 c81131db Alexander Graf
        /* Linux before 2.6.34 sets the device as OK without enabling
318 c81131db Alexander Graf
           the PCI device bus master bit. In this case we need to disable
319 c81131db Alexander Graf
           some safety checks. */
320 c81131db Alexander Graf
        if ((val & VIRTIO_CONFIG_S_DRIVER_OK) &&
321 c81131db Alexander Graf
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
322 3dbca8e6 Stefan Hajnoczi
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
323 c81131db Alexander Graf
        }
324 53c25cea Paul Brook
        break;
325 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
326 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);
327 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
328 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
329 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
330 aba800a3 Michael S. Tsirkin
        vdev->config_vector = val;
331 aba800a3 Michael S. Tsirkin
        break;
332 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
333 aba800a3 Michael S. Tsirkin
        msix_vector_unuse(&proxy->pci_dev,
334 aba800a3 Michael S. Tsirkin
                          virtio_queue_vector(vdev, vdev->queue_sel));
335 aba800a3 Michael S. Tsirkin
        /* Make it possible for guest to discover an error took place. */
336 aba800a3 Michael S. Tsirkin
        if (msix_vector_use(&proxy->pci_dev, val) < 0)
337 aba800a3 Michael S. Tsirkin
            val = VIRTIO_NO_VECTOR;
338 aba800a3 Michael S. Tsirkin
        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
339 aba800a3 Michael S. Tsirkin
        break;
340 aba800a3 Michael S. Tsirkin
    default:
341 4e02d460 Stefan Hajnoczi
        error_report("%s: unexpected address 0x%x value 0x%x",
342 4e02d460 Stefan Hajnoczi
                     __func__, addr, val);
343 aba800a3 Michael S. Tsirkin
        break;
344 53c25cea Paul Brook
    }
345 53c25cea Paul Brook
}
346 53c25cea Paul Brook
347 aba800a3 Michael S. Tsirkin
static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
348 53c25cea Paul Brook
{
349 53c25cea Paul Brook
    VirtIODevice *vdev = proxy->vdev;
350 53c25cea Paul Brook
    uint32_t ret = 0xFFFFFFFF;
351 53c25cea Paul Brook
352 53c25cea Paul Brook
    switch (addr) {
353 53c25cea Paul Brook
    case VIRTIO_PCI_HOST_FEATURES:
354 8172539d Michael S. Tsirkin
        ret = proxy->host_features;
355 53c25cea Paul Brook
        break;
356 53c25cea Paul Brook
    case VIRTIO_PCI_GUEST_FEATURES:
357 704a76fc Michael S. Tsirkin
        ret = vdev->guest_features;
358 53c25cea Paul Brook
        break;
359 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_PFN:
360 53c25cea Paul Brook
        ret = virtio_queue_get_addr(vdev, vdev->queue_sel)
361 53c25cea Paul Brook
              >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
362 53c25cea Paul Brook
        break;
363 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_NUM:
364 53c25cea Paul Brook
        ret = virtio_queue_get_num(vdev, vdev->queue_sel);
365 53c25cea Paul Brook
        break;
366 53c25cea Paul Brook
    case VIRTIO_PCI_QUEUE_SEL:
367 53c25cea Paul Brook
        ret = vdev->queue_sel;
368 53c25cea Paul Brook
        break;
369 53c25cea Paul Brook
    case VIRTIO_PCI_STATUS:
370 53c25cea Paul Brook
        ret = vdev->status;
371 53c25cea Paul Brook
        break;
372 53c25cea Paul Brook
    case VIRTIO_PCI_ISR:
373 53c25cea Paul Brook
        /* reading from the ISR also clears it. */
374 53c25cea Paul Brook
        ret = vdev->isr;
375 53c25cea Paul Brook
        vdev->isr = 0;
376 7055e687 Michael S. Tsirkin
        qemu_set_irq(proxy->pci_dev.irq[0], 0);
377 53c25cea Paul Brook
        break;
378 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_CONFIG_VECTOR:
379 aba800a3 Michael S. Tsirkin
        ret = vdev->config_vector;
380 aba800a3 Michael S. Tsirkin
        break;
381 aba800a3 Michael S. Tsirkin
    case VIRTIO_MSI_QUEUE_VECTOR:
382 aba800a3 Michael S. Tsirkin
        ret = virtio_queue_vector(vdev, vdev->queue_sel);
383 aba800a3 Michael S. Tsirkin
        break;
384 53c25cea Paul Brook
    default:
385 53c25cea Paul Brook
        break;
386 53c25cea Paul Brook
    }
387 53c25cea Paul Brook
388 53c25cea Paul Brook
    return ret;
389 53c25cea Paul Brook
}
390 53c25cea Paul Brook
391 df6db5b3 Alexander Graf
static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
392 df6db5b3 Alexander Graf
                                       unsigned size)
393 53c25cea Paul Brook
{
394 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = opaque;
395 aba800a3 Michael S. Tsirkin
    uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
396 df6db5b3 Alexander Graf
    uint64_t val = 0;
397 aba800a3 Michael S. Tsirkin
    if (addr < config) {
398 df6db5b3 Alexander Graf
        return virtio_ioport_read(proxy, addr);
399 aba800a3 Michael S. Tsirkin
    }
400 aba800a3 Michael S. Tsirkin
    addr -= config;
401 53c25cea Paul Brook
402 df6db5b3 Alexander Graf
    switch (size) {
403 df6db5b3 Alexander Graf
    case 1:
404 df6db5b3 Alexander Graf
        val = virtio_config_readb(proxy->vdev, addr);
405 df6db5b3 Alexander Graf
        break;
406 df6db5b3 Alexander Graf
    case 2:
407 df6db5b3 Alexander Graf
        val = virtio_config_readw(proxy->vdev, addr);
408 8e4a424b Blue Swirl
        if (virtio_is_big_endian()) {
409 8e4a424b Blue Swirl
            val = bswap16(val);
410 8e4a424b Blue Swirl
        }
411 df6db5b3 Alexander Graf
        break;
412 df6db5b3 Alexander Graf
    case 4:
413 df6db5b3 Alexander Graf
        val = virtio_config_readl(proxy->vdev, addr);
414 8e4a424b Blue Swirl
        if (virtio_is_big_endian()) {
415 8e4a424b Blue Swirl
            val = bswap32(val);
416 8e4a424b Blue Swirl
        }
417 df6db5b3 Alexander Graf
        break;
418 82afa586 Benjamin Herrenschmidt
    }
419 df6db5b3 Alexander Graf
    return val;
420 53c25cea Paul Brook
}
421 53c25cea Paul Brook
422 df6db5b3 Alexander Graf
static void virtio_pci_config_write(void *opaque, hwaddr addr,
423 df6db5b3 Alexander Graf
                                    uint64_t val, unsigned size)
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
    if (addr < config) {
428 aba800a3 Michael S. Tsirkin
        virtio_ioport_write(proxy, addr, val);
429 aba800a3 Michael S. Tsirkin
        return;
430 aba800a3 Michael S. Tsirkin
    }
431 aba800a3 Michael S. Tsirkin
    addr -= config;
432 df6db5b3 Alexander Graf
    /*
433 df6db5b3 Alexander Graf
     * Virtio-PCI is odd. Ioports are LE but config space is target native
434 df6db5b3 Alexander Graf
     * endian.
435 df6db5b3 Alexander Graf
     */
436 df6db5b3 Alexander Graf
    switch (size) {
437 df6db5b3 Alexander Graf
    case 1:
438 df6db5b3 Alexander Graf
        virtio_config_writeb(proxy->vdev, addr, val);
439 df6db5b3 Alexander Graf
        break;
440 df6db5b3 Alexander Graf
    case 2:
441 8e4a424b Blue Swirl
        if (virtio_is_big_endian()) {
442 8e4a424b Blue Swirl
            val = bswap16(val);
443 8e4a424b Blue Swirl
        }
444 df6db5b3 Alexander Graf
        virtio_config_writew(proxy->vdev, addr, val);
445 df6db5b3 Alexander Graf
        break;
446 df6db5b3 Alexander Graf
    case 4:
447 8e4a424b Blue Swirl
        if (virtio_is_big_endian()) {
448 8e4a424b Blue Swirl
            val = bswap32(val);
449 8e4a424b Blue Swirl
        }
450 df6db5b3 Alexander Graf
        virtio_config_writel(proxy->vdev, addr, val);
451 df6db5b3 Alexander Graf
        break;
452 82afa586 Benjamin Herrenschmidt
    }
453 53c25cea Paul Brook
}
454 53c25cea Paul Brook
455 da146d0a Avi Kivity
static const MemoryRegionOps virtio_pci_config_ops = {
456 df6db5b3 Alexander Graf
    .read = virtio_pci_config_read,
457 df6db5b3 Alexander Graf
    .write = virtio_pci_config_write,
458 df6db5b3 Alexander Graf
    .impl = {
459 df6db5b3 Alexander Graf
        .min_access_size = 1,
460 df6db5b3 Alexander Graf
        .max_access_size = 4,
461 df6db5b3 Alexander Graf
    },
462 8e4a424b Blue Swirl
    .endianness = DEVICE_LITTLE_ENDIAN,
463 da146d0a Avi Kivity
};
464 aba800a3 Michael S. Tsirkin
465 aba800a3 Michael S. Tsirkin
static void virtio_write_config(PCIDevice *pci_dev, uint32_t address,
466 aba800a3 Michael S. Tsirkin
                                uint32_t val, int len)
467 aba800a3 Michael S. Tsirkin
{
468 ed757e14 Yan Vugenfirer
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
469 ed757e14 Yan Vugenfirer
470 1129714f Michael S. Tsirkin
    pci_default_write_config(pci_dev, address, val, len);
471 1129714f Michael S. Tsirkin
472 1129714f Michael S. Tsirkin
    if (range_covers_byte(address, len, PCI_COMMAND) &&
473 1129714f Michael S. Tsirkin
        !(pci_dev->config[PCI_COMMAND] & PCI_COMMAND_MASTER) &&
474 1129714f Michael S. Tsirkin
        !(proxy->flags & VIRTIO_PCI_FLAG_BUS_MASTER_BUG)) {
475 1129714f Michael S. Tsirkin
        virtio_pci_stop_ioeventfd(proxy);
476 1129714f Michael S. Tsirkin
        virtio_set_status(proxy->vdev,
477 1129714f Michael S. Tsirkin
                          proxy->vdev->status & ~VIRTIO_CONFIG_S_DRIVER_OK);
478 ed757e14 Yan Vugenfirer
    }
479 53c25cea Paul Brook
}
480 53c25cea Paul Brook
481 d2a0ccc6 Michael S. Tsirkin
static unsigned virtio_pci_get_features(DeviceState *d)
482 6d74ca5a Michael S. Tsirkin
{
483 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
484 8172539d Michael S. Tsirkin
    return proxy->host_features;
485 6d74ca5a Michael S. Tsirkin
}
486 6d74ca5a Michael S. Tsirkin
487 7d37d351 Jan Kiszka
static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
488 7d37d351 Jan Kiszka
                                        unsigned int queue_no,
489 7d37d351 Jan Kiszka
                                        unsigned int vector,
490 7d37d351 Jan Kiszka
                                        MSIMessage msg)
491 7d37d351 Jan Kiszka
{
492 7d37d351 Jan Kiszka
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
493 15b2bd18 Paolo Bonzini
    int ret;
494 7d37d351 Jan Kiszka
495 7d37d351 Jan Kiszka
    if (irqfd->users == 0) {
496 7d37d351 Jan Kiszka
        ret = kvm_irqchip_add_msi_route(kvm_state, msg);
497 7d37d351 Jan Kiszka
        if (ret < 0) {
498 7d37d351 Jan Kiszka
            return ret;
499 7d37d351 Jan Kiszka
        }
500 7d37d351 Jan Kiszka
        irqfd->virq = ret;
501 7d37d351 Jan Kiszka
    }
502 7d37d351 Jan Kiszka
    irqfd->users++;
503 7d37d351 Jan Kiszka
    return 0;
504 7d37d351 Jan Kiszka
}
505 7d37d351 Jan Kiszka
506 7d37d351 Jan Kiszka
static void kvm_virtio_pci_vq_vector_release(VirtIOPCIProxy *proxy,
507 7d37d351 Jan Kiszka
                                             unsigned int vector)
508 7d37d351 Jan Kiszka
{
509 774345f9 Michael S. Tsirkin
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
510 774345f9 Michael S. Tsirkin
    if (--irqfd->users == 0) {
511 774345f9 Michael S. Tsirkin
        kvm_irqchip_release_virq(kvm_state, irqfd->virq);
512 774345f9 Michael S. Tsirkin
    }
513 774345f9 Michael S. Tsirkin
}
514 774345f9 Michael S. Tsirkin
515 f1d0f15a Michael S. Tsirkin
static int kvm_virtio_pci_irqfd_use(VirtIOPCIProxy *proxy,
516 f1d0f15a Michael S. Tsirkin
                                 unsigned int queue_no,
517 f1d0f15a Michael S. Tsirkin
                                 unsigned int vector)
518 f1d0f15a Michael S. Tsirkin
{
519 f1d0f15a Michael S. Tsirkin
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
520 f1d0f15a Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
521 f1d0f15a Michael S. Tsirkin
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
522 f1d0f15a Michael S. Tsirkin
    int ret;
523 f1d0f15a Michael S. Tsirkin
    ret = kvm_irqchip_add_irqfd_notifier(kvm_state, n, irqfd->virq);
524 f1d0f15a Michael S. Tsirkin
    return ret;
525 f1d0f15a Michael S. Tsirkin
}
526 f1d0f15a Michael S. Tsirkin
527 f1d0f15a Michael S. Tsirkin
static void kvm_virtio_pci_irqfd_release(VirtIOPCIProxy *proxy,
528 f1d0f15a Michael S. Tsirkin
                                      unsigned int queue_no,
529 f1d0f15a Michael S. Tsirkin
                                      unsigned int vector)
530 f1d0f15a Michael S. Tsirkin
{
531 7d37d351 Jan Kiszka
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
532 15b2bd18 Paolo Bonzini
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
533 7d37d351 Jan Kiszka
    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];
534 15b2bd18 Paolo Bonzini
    int ret;
535 7d37d351 Jan Kiszka
536 b131c74a Jan Kiszka
    ret = kvm_irqchip_remove_irqfd_notifier(kvm_state, n, irqfd->virq);
537 7d37d351 Jan Kiszka
    assert(ret == 0);
538 f1d0f15a Michael S. Tsirkin
}
539 7d37d351 Jan Kiszka
540 774345f9 Michael S. Tsirkin
static int kvm_virtio_pci_vector_use(VirtIOPCIProxy *proxy, int nvqs)
541 774345f9 Michael S. Tsirkin
{
542 774345f9 Michael S. Tsirkin
    PCIDevice *dev = &proxy->pci_dev;
543 774345f9 Michael S. Tsirkin
    VirtIODevice *vdev = proxy->vdev;
544 774345f9 Michael S. Tsirkin
    unsigned int vector;
545 774345f9 Michael S. Tsirkin
    int ret, queue_no;
546 774345f9 Michael S. Tsirkin
    MSIMessage msg;
547 774345f9 Michael S. Tsirkin
548 774345f9 Michael S. Tsirkin
    for (queue_no = 0; queue_no < nvqs; queue_no++) {
549 774345f9 Michael S. Tsirkin
        if (!virtio_queue_get_num(vdev, queue_no)) {
550 774345f9 Michael S. Tsirkin
            break;
551 774345f9 Michael S. Tsirkin
        }
552 774345f9 Michael S. Tsirkin
        vector = virtio_queue_vector(vdev, queue_no);
553 774345f9 Michael S. Tsirkin
        if (vector >= msix_nr_vectors_allocated(dev)) {
554 774345f9 Michael S. Tsirkin
            continue;
555 774345f9 Michael S. Tsirkin
        }
556 774345f9 Michael S. Tsirkin
        msg = msix_get_message(dev, vector);
557 774345f9 Michael S. Tsirkin
        ret = kvm_virtio_pci_vq_vector_use(proxy, queue_no, vector, msg);
558 774345f9 Michael S. Tsirkin
        if (ret < 0) {
559 774345f9 Michael S. Tsirkin
            goto undo;
560 7d37d351 Jan Kiszka
        }
561 f1d0f15a Michael S. Tsirkin
        /* If guest supports masking, set up irqfd now.
562 f1d0f15a Michael S. Tsirkin
         * Otherwise, delay until unmasked in the frontend.
563 f1d0f15a Michael S. Tsirkin
         */
564 f1d0f15a Michael S. Tsirkin
        if (proxy->vdev->guest_notifier_mask) {
565 f1d0f15a Michael S. Tsirkin
            ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
566 f1d0f15a Michael S. Tsirkin
            if (ret < 0) {
567 f1d0f15a Michael S. Tsirkin
                kvm_virtio_pci_vq_vector_release(proxy, vector);
568 f1d0f15a Michael S. Tsirkin
                goto undo;
569 f1d0f15a Michael S. Tsirkin
            }
570 f1d0f15a Michael S. Tsirkin
        }
571 7d37d351 Jan Kiszka
    }
572 7d37d351 Jan Kiszka
    return 0;
573 774345f9 Michael S. Tsirkin
574 774345f9 Michael S. Tsirkin
undo:
575 774345f9 Michael S. Tsirkin
    while (--queue_no >= 0) {
576 774345f9 Michael S. Tsirkin
        vector = virtio_queue_vector(vdev, queue_no);
577 774345f9 Michael S. Tsirkin
        if (vector >= msix_nr_vectors_allocated(dev)) {
578 774345f9 Michael S. Tsirkin
            continue;
579 774345f9 Michael S. Tsirkin
        }
580 f1d0f15a Michael S. Tsirkin
        if (proxy->vdev->guest_notifier_mask) {
581 e387f99e Michael S. Tsirkin
            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
582 f1d0f15a Michael S. Tsirkin
        }
583 774345f9 Michael S. Tsirkin
        kvm_virtio_pci_vq_vector_release(proxy, vector);
584 774345f9 Michael S. Tsirkin
    }
585 774345f9 Michael S. Tsirkin
    return ret;
586 7d37d351 Jan Kiszka
}
587 7d37d351 Jan Kiszka
588 774345f9 Michael S. Tsirkin
static void kvm_virtio_pci_vector_release(VirtIOPCIProxy *proxy, int nvqs)
589 774345f9 Michael S. Tsirkin
{
590 774345f9 Michael S. Tsirkin
    PCIDevice *dev = &proxy->pci_dev;
591 774345f9 Michael S. Tsirkin
    VirtIODevice *vdev = proxy->vdev;
592 774345f9 Michael S. Tsirkin
    unsigned int vector;
593 774345f9 Michael S. Tsirkin
    int queue_no;
594 774345f9 Michael S. Tsirkin
595 774345f9 Michael S. Tsirkin
    for (queue_no = 0; queue_no < nvqs; queue_no++) {
596 774345f9 Michael S. Tsirkin
        if (!virtio_queue_get_num(vdev, queue_no)) {
597 774345f9 Michael S. Tsirkin
            break;
598 774345f9 Michael S. Tsirkin
        }
599 774345f9 Michael S. Tsirkin
        vector = virtio_queue_vector(vdev, queue_no);
600 774345f9 Michael S. Tsirkin
        if (vector >= msix_nr_vectors_allocated(dev)) {
601 774345f9 Michael S. Tsirkin
            continue;
602 774345f9 Michael S. Tsirkin
        }
603 f1d0f15a Michael S. Tsirkin
        /* If guest supports masking, clean up irqfd now.
604 f1d0f15a Michael S. Tsirkin
         * Otherwise, it was cleaned when masked in the frontend.
605 f1d0f15a Michael S. Tsirkin
         */
606 f1d0f15a Michael S. Tsirkin
        if (proxy->vdev->guest_notifier_mask) {
607 e387f99e Michael S. Tsirkin
            kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
608 f1d0f15a Michael S. Tsirkin
        }
609 774345f9 Michael S. Tsirkin
        kvm_virtio_pci_vq_vector_release(proxy, vector);
610 774345f9 Michael S. Tsirkin
    }
611 774345f9 Michael S. Tsirkin
}
612 774345f9 Michael S. Tsirkin
613 a38b2c49 Michael S. Tsirkin
static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
614 a38b2c49 Michael S. Tsirkin
                                       unsigned int queue_no,
615 a38b2c49 Michael S. Tsirkin
                                       unsigned int vector,
616 a38b2c49 Michael S. Tsirkin
                                       MSIMessage msg)
617 774345f9 Michael S. Tsirkin
{
618 774345f9 Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
619 774345f9 Michael S. Tsirkin
    EventNotifier *n = virtio_queue_get_guest_notifier(vq);
620 a38b2c49 Michael S. Tsirkin
    VirtIOIRQFD *irqfd;
621 53510bfc Michael Roth
    int ret = 0;
622 774345f9 Michael S. Tsirkin
623 a38b2c49 Michael S. Tsirkin
    if (proxy->vector_irqfd) {
624 a38b2c49 Michael S. Tsirkin
        irqfd = &proxy->vector_irqfd[vector];
625 a38b2c49 Michael S. Tsirkin
        if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
626 a38b2c49 Michael S. Tsirkin
            ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
627 a38b2c49 Michael S. Tsirkin
            if (ret < 0) {
628 a38b2c49 Michael S. Tsirkin
                return ret;
629 a38b2c49 Michael S. Tsirkin
            }
630 774345f9 Michael S. Tsirkin
        }
631 774345f9 Michael S. Tsirkin
    }
632 774345f9 Michael S. Tsirkin
633 f1d0f15a Michael S. Tsirkin
    /* If guest supports masking, irqfd is already setup, unmask it.
634 f1d0f15a Michael S. Tsirkin
     * Otherwise, set it up now.
635 f1d0f15a Michael S. Tsirkin
     */
636 f1d0f15a Michael S. Tsirkin
    if (proxy->vdev->guest_notifier_mask) {
637 f1d0f15a Michael S. Tsirkin
        proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, false);
638 f1d0f15a Michael S. Tsirkin
        /* Test after unmasking to avoid losing events. */
639 f1d0f15a Michael S. Tsirkin
        if (proxy->vdev->guest_notifier_pending &&
640 f1d0f15a Michael S. Tsirkin
            proxy->vdev->guest_notifier_pending(proxy->vdev, queue_no)) {
641 f1d0f15a Michael S. Tsirkin
            event_notifier_set(n);
642 f1d0f15a Michael S. Tsirkin
        }
643 f1d0f15a Michael S. Tsirkin
    } else {
644 f1d0f15a Michael S. Tsirkin
        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);
645 7d37d351 Jan Kiszka
    }
646 774345f9 Michael S. Tsirkin
    return ret;
647 7d37d351 Jan Kiszka
}
648 7d37d351 Jan Kiszka
649 a38b2c49 Michael S. Tsirkin
static void virtio_pci_vq_vector_mask(VirtIOPCIProxy *proxy,
650 7d37d351 Jan Kiszka
                                             unsigned int queue_no,
651 7d37d351 Jan Kiszka
                                             unsigned int vector)
652 7d37d351 Jan Kiszka
{
653 f1d0f15a Michael S. Tsirkin
    /* If guest supports masking, keep irqfd but mask it.
654 f1d0f15a Michael S. Tsirkin
     * Otherwise, clean it up now.
655 f1d0f15a Michael S. Tsirkin
     */ 
656 f1d0f15a Michael S. Tsirkin
    if (proxy->vdev->guest_notifier_mask) {
657 f1d0f15a Michael S. Tsirkin
        proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, true);
658 f1d0f15a Michael S. Tsirkin
    } else {
659 e387f99e Michael S. Tsirkin
        kvm_virtio_pci_irqfd_release(proxy, queue_no, vector);
660 f1d0f15a Michael S. Tsirkin
    }
661 7d37d351 Jan Kiszka
}
662 7d37d351 Jan Kiszka
663 a38b2c49 Michael S. Tsirkin
static int virtio_pci_vector_unmask(PCIDevice *dev, unsigned vector,
664 a38b2c49 Michael S. Tsirkin
                                    MSIMessage msg)
665 7d37d351 Jan Kiszka
{
666 7d37d351 Jan Kiszka
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
667 7d37d351 Jan Kiszka
    VirtIODevice *vdev = proxy->vdev;
668 7d37d351 Jan Kiszka
    int ret, queue_no;
669 7d37d351 Jan Kiszka
670 2d620f59 Michael S. Tsirkin
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
671 7d37d351 Jan Kiszka
        if (!virtio_queue_get_num(vdev, queue_no)) {
672 7d37d351 Jan Kiszka
            break;
673 7d37d351 Jan Kiszka
        }
674 7d37d351 Jan Kiszka
        if (virtio_queue_vector(vdev, queue_no) != vector) {
675 7d37d351 Jan Kiszka
            continue;
676 7d37d351 Jan Kiszka
        }
677 a38b2c49 Michael S. Tsirkin
        ret = virtio_pci_vq_vector_unmask(proxy, queue_no, vector, msg);
678 7d37d351 Jan Kiszka
        if (ret < 0) {
679 7d37d351 Jan Kiszka
            goto undo;
680 7d37d351 Jan Kiszka
        }
681 7d37d351 Jan Kiszka
    }
682 7d37d351 Jan Kiszka
    return 0;
683 7d37d351 Jan Kiszka
684 7d37d351 Jan Kiszka
undo:
685 7d37d351 Jan Kiszka
    while (--queue_no >= 0) {
686 7d37d351 Jan Kiszka
        if (virtio_queue_vector(vdev, queue_no) != vector) {
687 7d37d351 Jan Kiszka
            continue;
688 7d37d351 Jan Kiszka
        }
689 a38b2c49 Michael S. Tsirkin
        virtio_pci_vq_vector_mask(proxy, queue_no, vector);
690 7d37d351 Jan Kiszka
    }
691 7d37d351 Jan Kiszka
    return ret;
692 7d37d351 Jan Kiszka
}
693 7d37d351 Jan Kiszka
694 a38b2c49 Michael S. Tsirkin
static void virtio_pci_vector_mask(PCIDevice *dev, unsigned vector)
695 7d37d351 Jan Kiszka
{
696 7d37d351 Jan Kiszka
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
697 7d37d351 Jan Kiszka
    VirtIODevice *vdev = proxy->vdev;
698 7d37d351 Jan Kiszka
    int queue_no;
699 7d37d351 Jan Kiszka
700 2d620f59 Michael S. Tsirkin
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
701 7d37d351 Jan Kiszka
        if (!virtio_queue_get_num(vdev, queue_no)) {
702 7d37d351 Jan Kiszka
            break;
703 7d37d351 Jan Kiszka
        }
704 7d37d351 Jan Kiszka
        if (virtio_queue_vector(vdev, queue_no) != vector) {
705 7d37d351 Jan Kiszka
            continue;
706 7d37d351 Jan Kiszka
        }
707 a38b2c49 Michael S. Tsirkin
        virtio_pci_vq_vector_mask(proxy, queue_no, vector);
708 7d37d351 Jan Kiszka
    }
709 7d37d351 Jan Kiszka
}
710 7d37d351 Jan Kiszka
711 a38b2c49 Michael S. Tsirkin
static void virtio_pci_vector_poll(PCIDevice *dev,
712 a38b2c49 Michael S. Tsirkin
                                   unsigned int vector_start,
713 a38b2c49 Michael S. Tsirkin
                                   unsigned int vector_end)
714 89d62be9 Michael S. Tsirkin
{
715 89d62be9 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = container_of(dev, VirtIOPCIProxy, pci_dev);
716 89d62be9 Michael S. Tsirkin
    VirtIODevice *vdev = proxy->vdev;
717 89d62be9 Michael S. Tsirkin
    int queue_no;
718 89d62be9 Michael S. Tsirkin
    unsigned int vector;
719 89d62be9 Michael S. Tsirkin
    EventNotifier *notifier;
720 89d62be9 Michael S. Tsirkin
    VirtQueue *vq;
721 89d62be9 Michael S. Tsirkin
722 2d620f59 Michael S. Tsirkin
    for (queue_no = 0; queue_no < proxy->nvqs_with_notifiers; queue_no++) {
723 89d62be9 Michael S. Tsirkin
        if (!virtio_queue_get_num(vdev, queue_no)) {
724 89d62be9 Michael S. Tsirkin
            break;
725 89d62be9 Michael S. Tsirkin
        }
726 89d62be9 Michael S. Tsirkin
        vector = virtio_queue_vector(vdev, queue_no);
727 89d62be9 Michael S. Tsirkin
        if (vector < vector_start || vector >= vector_end ||
728 89d62be9 Michael S. Tsirkin
            !msix_is_masked(dev, vector)) {
729 89d62be9 Michael S. Tsirkin
            continue;
730 89d62be9 Michael S. Tsirkin
        }
731 89d62be9 Michael S. Tsirkin
        vq = virtio_get_queue(vdev, queue_no);
732 89d62be9 Michael S. Tsirkin
        notifier = virtio_queue_get_guest_notifier(vq);
733 f1d0f15a Michael S. Tsirkin
        if (vdev->guest_notifier_pending) {
734 f1d0f15a Michael S. Tsirkin
            if (vdev->guest_notifier_pending(vdev, queue_no)) {
735 f1d0f15a Michael S. Tsirkin
                msix_set_pending(dev, vector);
736 f1d0f15a Michael S. Tsirkin
            }
737 f1d0f15a Michael S. Tsirkin
        } else if (event_notifier_test_and_clear(notifier)) {
738 89d62be9 Michael S. Tsirkin
            msix_set_pending(dev, vector);
739 89d62be9 Michael S. Tsirkin
        }
740 89d62be9 Michael S. Tsirkin
    }
741 89d62be9 Michael S. Tsirkin
}
742 89d62be9 Michael S. Tsirkin
743 89d62be9 Michael S. Tsirkin
static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign,
744 89d62be9 Michael S. Tsirkin
                                         bool with_irqfd)
745 ade80dc8 Michael S. Tsirkin
{
746 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
747 ade80dc8 Michael S. Tsirkin
    VirtQueue *vq = virtio_get_queue(proxy->vdev, n);
748 ade80dc8 Michael S. Tsirkin
    EventNotifier *notifier = virtio_queue_get_guest_notifier(vq);
749 ade80dc8 Michael S. Tsirkin
750 ade80dc8 Michael S. Tsirkin
    if (assign) {
751 ade80dc8 Michael S. Tsirkin
        int r = event_notifier_init(notifier, 0);
752 ade80dc8 Michael S. Tsirkin
        if (r < 0) {
753 ade80dc8 Michael S. Tsirkin
            return r;
754 ade80dc8 Michael S. Tsirkin
        }
755 89d62be9 Michael S. Tsirkin
        virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd);
756 ade80dc8 Michael S. Tsirkin
    } else {
757 89d62be9 Michael S. Tsirkin
        virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd);
758 ade80dc8 Michael S. Tsirkin
        event_notifier_cleanup(notifier);
759 ade80dc8 Michael S. Tsirkin
    }
760 ade80dc8 Michael S. Tsirkin
761 ade80dc8 Michael S. Tsirkin
    return 0;
762 ade80dc8 Michael S. Tsirkin
}
763 ade80dc8 Michael S. Tsirkin
764 d2a0ccc6 Michael S. Tsirkin
static bool virtio_pci_query_guest_notifiers(DeviceState *d)
765 5430a28f mst@redhat.com
{
766 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
767 5430a28f mst@redhat.com
    return msix_enabled(&proxy->pci_dev);
768 5430a28f mst@redhat.com
}
769 5430a28f mst@redhat.com
770 2d620f59 Michael S. Tsirkin
static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign)
771 54dd9321 Michael S. Tsirkin
{
772 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
773 54dd9321 Michael S. Tsirkin
    VirtIODevice *vdev = proxy->vdev;
774 54dd9321 Michael S. Tsirkin
    int r, n;
775 89d62be9 Michael S. Tsirkin
    bool with_irqfd = msix_enabled(&proxy->pci_dev) &&
776 89d62be9 Michael S. Tsirkin
        kvm_msi_via_irqfd_enabled();
777 54dd9321 Michael S. Tsirkin
778 2d620f59 Michael S. Tsirkin
    nvqs = MIN(nvqs, VIRTIO_PCI_QUEUE_MAX);
779 2d620f59 Michael S. Tsirkin
780 2d620f59 Michael S. Tsirkin
    /* When deassigning, pass a consistent nvqs value
781 2d620f59 Michael S. Tsirkin
     * to avoid leaking notifiers.
782 2d620f59 Michael S. Tsirkin
     */
783 2d620f59 Michael S. Tsirkin
    assert(assign || nvqs == proxy->nvqs_with_notifiers);
784 2d620f59 Michael S. Tsirkin
785 2d620f59 Michael S. Tsirkin
    proxy->nvqs_with_notifiers = nvqs;
786 2d620f59 Michael S. Tsirkin
787 7d37d351 Jan Kiszka
    /* Must unset vector notifier while guest notifier is still assigned */
788 a38b2c49 Michael S. Tsirkin
    if ((proxy->vector_irqfd || vdev->guest_notifier_mask) && !assign) {
789 7d37d351 Jan Kiszka
        msix_unset_vector_notifiers(&proxy->pci_dev);
790 a38b2c49 Michael S. Tsirkin
        if (proxy->vector_irqfd) {
791 a38b2c49 Michael S. Tsirkin
            kvm_virtio_pci_vector_release(proxy, nvqs);
792 a38b2c49 Michael S. Tsirkin
            g_free(proxy->vector_irqfd);
793 a38b2c49 Michael S. Tsirkin
            proxy->vector_irqfd = NULL;
794 a38b2c49 Michael S. Tsirkin
        }
795 7d37d351 Jan Kiszka
    }
796 7d37d351 Jan Kiszka
797 2d620f59 Michael S. Tsirkin
    for (n = 0; n < nvqs; n++) {
798 54dd9321 Michael S. Tsirkin
        if (!virtio_queue_get_num(vdev, n)) {
799 54dd9321 Michael S. Tsirkin
            break;
800 54dd9321 Michael S. Tsirkin
        }
801 54dd9321 Michael S. Tsirkin
802 89d62be9 Michael S. Tsirkin
        r = virtio_pci_set_guest_notifier(d, n, assign,
803 89d62be9 Michael S. Tsirkin
                                          kvm_msi_via_irqfd_enabled());
804 54dd9321 Michael S. Tsirkin
        if (r < 0) {
805 54dd9321 Michael S. Tsirkin
            goto assign_error;
806 54dd9321 Michael S. Tsirkin
        }
807 54dd9321 Michael S. Tsirkin
    }
808 54dd9321 Michael S. Tsirkin
809 7d37d351 Jan Kiszka
    /* Must set vector notifier after guest notifier has been assigned */
810 a38b2c49 Michael S. Tsirkin
    if ((with_irqfd || vdev->guest_notifier_mask) && assign) {
811 a38b2c49 Michael S. Tsirkin
        if (with_irqfd) {
812 a38b2c49 Michael S. Tsirkin
            proxy->vector_irqfd =
813 a38b2c49 Michael S. Tsirkin
                g_malloc0(sizeof(*proxy->vector_irqfd) *
814 a38b2c49 Michael S. Tsirkin
                          msix_nr_vectors_allocated(&proxy->pci_dev));
815 a38b2c49 Michael S. Tsirkin
            r = kvm_virtio_pci_vector_use(proxy, nvqs);
816 a38b2c49 Michael S. Tsirkin
            if (r < 0) {
817 a38b2c49 Michael S. Tsirkin
                goto assign_error;
818 a38b2c49 Michael S. Tsirkin
            }
819 774345f9 Michael S. Tsirkin
        }
820 7d37d351 Jan Kiszka
        r = msix_set_vector_notifiers(&proxy->pci_dev,
821 a38b2c49 Michael S. Tsirkin
                                      virtio_pci_vector_unmask,
822 a38b2c49 Michael S. Tsirkin
                                      virtio_pci_vector_mask,
823 a38b2c49 Michael S. Tsirkin
                                      virtio_pci_vector_poll);
824 7d37d351 Jan Kiszka
        if (r < 0) {
825 774345f9 Michael S. Tsirkin
            goto notifiers_error;
826 7d37d351 Jan Kiszka
        }
827 7d37d351 Jan Kiszka
    }
828 7d37d351 Jan Kiszka
829 54dd9321 Michael S. Tsirkin
    return 0;
830 54dd9321 Michael S. Tsirkin
831 774345f9 Michael S. Tsirkin
notifiers_error:
832 a38b2c49 Michael S. Tsirkin
    if (with_irqfd) {
833 a38b2c49 Michael S. Tsirkin
        assert(assign);
834 a38b2c49 Michael S. Tsirkin
        kvm_virtio_pci_vector_release(proxy, nvqs);
835 a38b2c49 Michael S. Tsirkin
    }
836 774345f9 Michael S. Tsirkin
837 54dd9321 Michael S. Tsirkin
assign_error:
838 54dd9321 Michael S. Tsirkin
    /* We get here on assignment failure. Recover by undoing for VQs 0 .. n. */
839 7d37d351 Jan Kiszka
    assert(assign);
840 54dd9321 Michael S. Tsirkin
    while (--n >= 0) {
841 89d62be9 Michael S. Tsirkin
        virtio_pci_set_guest_notifier(d, n, !assign, with_irqfd);
842 54dd9321 Michael S. Tsirkin
    }
843 54dd9321 Michael S. Tsirkin
    return r;
844 54dd9321 Michael S. Tsirkin
}
845 54dd9321 Michael S. Tsirkin
846 d2a0ccc6 Michael S. Tsirkin
static int virtio_pci_set_host_notifier(DeviceState *d, int n, bool assign)
847 ade80dc8 Michael S. Tsirkin
{
848 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
849 25db9ebe Stefan Hajnoczi
850 25db9ebe Stefan Hajnoczi
    /* Stop using ioeventfd for virtqueue kick if the device starts using host
851 25db9ebe Stefan Hajnoczi
     * notifiers.  This makes it easy to avoid stepping on each others' toes.
852 25db9ebe Stefan Hajnoczi
     */
853 25db9ebe Stefan Hajnoczi
    proxy->ioeventfd_disabled = assign;
854 ade80dc8 Michael S. Tsirkin
    if (assign) {
855 25db9ebe Stefan Hajnoczi
        virtio_pci_stop_ioeventfd(proxy);
856 25db9ebe Stefan Hajnoczi
    }
857 25db9ebe Stefan Hajnoczi
    /* We don't need to start here: it's not needed because backend
858 25db9ebe Stefan Hajnoczi
     * currently only stops on status change away from ok,
859 25db9ebe Stefan Hajnoczi
     * reset, vmstop and such. If we do add code to start here,
860 25db9ebe Stefan Hajnoczi
     * need to check vmstate, device state etc. */
861 26b9b5fe Paolo Bonzini
    return virtio_pci_set_host_notifier_internal(proxy, n, assign, false);
862 25db9ebe Stefan Hajnoczi
}
863 25db9ebe Stefan Hajnoczi
864 d2a0ccc6 Michael S. Tsirkin
static void virtio_pci_vmstate_change(DeviceState *d, bool running)
865 25db9ebe Stefan Hajnoczi
{
866 d2a0ccc6 Michael S. Tsirkin
    VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d);
867 25db9ebe Stefan Hajnoczi
868 25db9ebe Stefan Hajnoczi
    if (running) {
869 89c473fd Michael S. Tsirkin
        /* Try to find out if the guest has bus master disabled, but is
870 89c473fd Michael S. Tsirkin
           in ready state. Then we have a buggy guest OS. */
871 89c473fd Michael S. Tsirkin
        if ((proxy->vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
872 89c473fd Michael S. Tsirkin
            !(proxy->pci_dev.config[PCI_COMMAND] & PCI_COMMAND_MASTER)) {
873 89c473fd Michael S. Tsirkin
            proxy->flags |= VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
874 89c473fd Michael S. Tsirkin
        }
875 25db9ebe Stefan Hajnoczi
        virtio_pci_start_ioeventfd(proxy);
876 ade80dc8 Michael S. Tsirkin
    } else {
877 25db9ebe Stefan Hajnoczi
        virtio_pci_stop_ioeventfd(proxy);
878 ade80dc8 Michael S. Tsirkin
    }
879 ade80dc8 Michael S. Tsirkin
}
880 ade80dc8 Michael S. Tsirkin
881 53c25cea Paul Brook
static const VirtIOBindings virtio_pci_bindings = {
882 ff24bd58 Michael S. Tsirkin
    .notify = virtio_pci_notify,
883 ff24bd58 Michael S. Tsirkin
    .save_config = virtio_pci_save_config,
884 ff24bd58 Michael S. Tsirkin
    .load_config = virtio_pci_load_config,
885 ff24bd58 Michael S. Tsirkin
    .save_queue = virtio_pci_save_queue,
886 ff24bd58 Michael S. Tsirkin
    .load_queue = virtio_pci_load_queue,
887 6d74ca5a Michael S. Tsirkin
    .get_features = virtio_pci_get_features,
888 5430a28f mst@redhat.com
    .query_guest_notifiers = virtio_pci_query_guest_notifiers,
889 ade80dc8 Michael S. Tsirkin
    .set_host_notifier = virtio_pci_set_host_notifier,
890 54dd9321 Michael S. Tsirkin
    .set_guest_notifiers = virtio_pci_set_guest_notifiers,
891 25db9ebe Stefan Hajnoczi
    .vmstate_change = virtio_pci_vmstate_change,
892 53c25cea Paul Brook
};
893 53c25cea Paul Brook
894 befeac45 Michael S. Tsirkin
void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev)
895 53c25cea Paul Brook
{
896 53c25cea Paul Brook
    uint8_t *config;
897 53c25cea Paul Brook
    uint32_t size;
898 53c25cea Paul Brook
899 53c25cea Paul Brook
    proxy->vdev = vdev;
900 53c25cea Paul Brook
901 53c25cea Paul Brook
    config = proxy->pci_dev.config;
902 53c25cea Paul Brook
903 e75ccf2c Isaku Yamahata
    if (proxy->class_code) {
904 e75ccf2c Isaku Yamahata
        pci_config_set_class(config, proxy->class_code);
905 e75ccf2c Isaku Yamahata
    }
906 ad3d11e6 Hui Kai Ran
    pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
907 ad3d11e6 Hui Kai Ran
                 pci_get_word(config + PCI_VENDOR_ID));
908 ad3d11e6 Hui Kai Ran
    pci_set_word(config + PCI_SUBSYSTEM_ID, vdev->device_id);
909 ad3d11e6 Hui Kai Ran
    config[PCI_INTERRUPT_PIN] = 1;
910 53c25cea Paul Brook
911 b2357c48 Alex Williamson
    if (vdev->nvectors &&
912 b2357c48 Alex Williamson
        msix_init_exclusive_bar(&proxy->pci_dev, vdev->nvectors, 1)) {
913 aba800a3 Michael S. Tsirkin
        vdev->nvectors = 0;
914 b2357c48 Alex Williamson
    }
915 aba800a3 Michael S. Tsirkin
916 ed757e14 Yan Vugenfirer
    proxy->pci_dev.config_write = virtio_write_config;
917 ed757e14 Yan Vugenfirer
918 aba800a3 Michael S. Tsirkin
    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev) + vdev->config_len;
919 53c25cea Paul Brook
    if (size & (size-1))
920 53c25cea Paul Brook
        size = 1 << qemu_fls(size);
921 53c25cea Paul Brook
922 da146d0a Avi Kivity
    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
923 da146d0a Avi Kivity
                          "virtio-pci", size);
924 e824b2cc Avi Kivity
    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
925 e824b2cc Avi Kivity
                     &proxy->bar);
926 53c25cea Paul Brook
927 25db9ebe Stefan Hajnoczi
    if (!kvm_has_many_ioeventfds()) {
928 25db9ebe Stefan Hajnoczi
        proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
929 25db9ebe Stefan Hajnoczi
    }
930 25db9ebe Stefan Hajnoczi
931 d2a0ccc6 Michael S. Tsirkin
    virtio_bind_device(vdev, &virtio_pci_bindings, DEVICE(proxy));
932 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
933 8172539d Michael S. Tsirkin
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
934 8172539d Michael S. Tsirkin
    proxy->host_features = vdev->get_features(vdev, proxy->host_features);
935 53c25cea Paul Brook
}
936 53c25cea Paul Brook
937 f90c2bcd Alex Williamson
static void virtio_exit_pci(PCIDevice *pci_dev)
938 0f457d91 Michael S. Tsirkin
{
939 da146d0a Avi Kivity
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
940 da146d0a Avi Kivity
941 da146d0a Avi Kivity
    memory_region_destroy(&proxy->bar);
942 b2357c48 Alex Williamson
    msix_uninit_exclusive_bar(pci_dev);
943 0f457d91 Michael S. Tsirkin
}
944 0f457d91 Michael S. Tsirkin
945 98b19252 Amit Shah
static int virtio_serial_init_pci(PCIDevice *pci_dev)
946 21d58b57 Mark McLoughlin
{
947 d6beee99 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
948 85c2c735 Mark McLoughlin
    VirtIODevice *vdev;
949 85c2c735 Mark McLoughlin
950 d6beee99 Gerd Hoffmann
    if (proxy->class_code != PCI_CLASS_COMMUNICATION_OTHER &&
951 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_DISPLAY_OTHER && /* qemu 0.10 */
952 d6beee99 Gerd Hoffmann
        proxy->class_code != PCI_CLASS_OTHERS)          /* qemu-kvm  */
953 d6beee99 Gerd Hoffmann
        proxy->class_code = PCI_CLASS_COMMUNICATION_OTHER;
954 d6beee99 Gerd Hoffmann
955 6b331efb Amit Shah
    vdev = virtio_serial_init(&pci_dev->qdev, &proxy->serial);
956 25fe3654 Amit Shah
    if (!vdev) {
957 25fe3654 Amit Shah
        return -1;
958 25fe3654 Amit Shah
    }
959 554f1997 Gal Hammer
960 554f1997 Gal Hammer
    /* backwards-compatibility with machines that were created with
961 554f1997 Gal Hammer
       DEV_NVECTORS_UNSPECIFIED */
962 573fb60c Amit Shah
    vdev->nvectors = proxy->nvectors == DEV_NVECTORS_UNSPECIFIED
963 6b331efb Amit Shah
                                        ? proxy->serial.max_virtserial_ports + 1
964 573fb60c Amit Shah
                                        : proxy->nvectors;
965 e75ccf2c Isaku Yamahata
    virtio_init_pci(proxy, vdev);
966 a1829205 Amit Shah
    proxy->nvectors = vdev->nvectors;
967 81a322d4 Gerd Hoffmann
    return 0;
968 53c25cea Paul Brook
}
969 53c25cea Paul Brook
970 f90c2bcd Alex Williamson
static void virtio_serial_exit_pci(PCIDevice *pci_dev)
971 8b53a865 Amit Shah
{
972 8b53a865 Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
973 8b53a865 Amit Shah
974 32059220 Amit Shah
    virtio_pci_stop_ioeventfd(proxy);
975 8b53a865 Amit Shah
    virtio_serial_exit(proxy->vdev);
976 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
977 8b53a865 Amit Shah
}
978 8b53a865 Amit Shah
979 81a322d4 Gerd Hoffmann
static int virtio_net_init_pci(PCIDevice *pci_dev)
980 53c25cea Paul Brook
{
981 53c25cea Paul Brook
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
982 53c25cea Paul Brook
    VirtIODevice *vdev;
983 53c25cea Paul Brook
984 1e89ad5b Anthony Liguori
    vdev = virtio_net_init(&pci_dev->qdev, &proxy->nic, &proxy->net,
985 1e89ad5b Anthony Liguori
                           proxy->host_features);
986 a1e0fea5 Gerd Hoffmann
987 97b15621 Gerd Hoffmann
    vdev->nvectors = proxy->nvectors;
988 e75ccf2c Isaku Yamahata
    virtio_init_pci(proxy, vdev);
989 a1e0fea5 Gerd Hoffmann
990 a1e0fea5 Gerd Hoffmann
    /* make the actual value visible */
991 a1e0fea5 Gerd Hoffmann
    proxy->nvectors = vdev->nvectors;
992 81a322d4 Gerd Hoffmann
    return 0;
993 53c25cea Paul Brook
}
994 53c25cea Paul Brook
995 f90c2bcd Alex Williamson
static void virtio_net_exit_pci(PCIDevice *pci_dev)
996 97b15621 Gerd Hoffmann
{
997 97b15621 Gerd Hoffmann
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
998 97b15621 Gerd Hoffmann
999 25db9ebe Stefan Hajnoczi
    virtio_pci_stop_ioeventfd(proxy);
1000 97b15621 Gerd Hoffmann
    virtio_net_exit(proxy->vdev);
1001 f90c2bcd Alex Williamson
    virtio_exit_pci(pci_dev);
1002 97b15621 Gerd Hoffmann
}
1003 97b15621 Gerd Hoffmann
1004 16c915ba Amit Shah
static int virtio_rng_init_pci(PCIDevice *pci_dev)
1005 16c915ba Amit Shah
{
1006 16c915ba Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1007 16c915ba Amit Shah
    VirtIODevice *vdev;
1008 16c915ba Amit Shah
1009 500054f1 Anthony Liguori
    if (proxy->rng.rng == NULL) {
1010 500054f1 Anthony Liguori
        proxy->rng.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM));
1011 500054f1 Anthony Liguori
1012 500054f1 Anthony Liguori
        object_property_add_child(OBJECT(pci_dev),
1013 500054f1 Anthony Liguori
                                  "default-backend",
1014 500054f1 Anthony Liguori
                                  OBJECT(proxy->rng.default_backend),
1015 500054f1 Anthony Liguori
                                  NULL);
1016 500054f1 Anthony Liguori
1017 500054f1 Anthony Liguori
        object_property_set_link(OBJECT(pci_dev),
1018 500054f1 Anthony Liguori
                                 OBJECT(proxy->rng.default_backend),
1019 500054f1 Anthony Liguori
                                 "rng", NULL);
1020 500054f1 Anthony Liguori
    }
1021 500054f1 Anthony Liguori
1022 16c915ba Amit Shah
    vdev = virtio_rng_init(&pci_dev->qdev, &proxy->rng);
1023 16c915ba Amit Shah
    if (!vdev) {
1024 16c915ba Amit Shah
        return -1;
1025 16c915ba Amit Shah
    }
1026 16c915ba Amit Shah
    virtio_init_pci(proxy, vdev);
1027 16c915ba Amit Shah
    return 0;
1028 16c915ba Amit Shah
}
1029 16c915ba Amit Shah
1030 16c915ba Amit Shah
static void virtio_rng_exit_pci(PCIDevice *pci_dev)
1031 16c915ba Amit Shah
{
1032 16c915ba Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1033 16c915ba Amit Shah
1034 16c915ba Amit Shah
    virtio_pci_stop_ioeventfd(proxy);
1035 16c915ba Amit Shah
    virtio_rng_exit(proxy->vdev);
1036 16c915ba Amit Shah
    virtio_exit_pci(pci_dev);
1037 16c915ba Amit Shah
}
1038 16c915ba Amit Shah
1039 40021f08 Anthony Liguori
static Property virtio_net_properties[] = {
1040 40021f08 Anthony Liguori
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, false),
1041 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 3),
1042 40021f08 Anthony Liguori
    DEFINE_VIRTIO_NET_FEATURES(VirtIOPCIProxy, host_features),
1043 40021f08 Anthony Liguori
    DEFINE_NIC_PROPERTIES(VirtIOPCIProxy, nic),
1044 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("x-txtimer", VirtIOPCIProxy, net.txtimer, TX_TIMER_INTERVAL),
1045 40021f08 Anthony Liguori
    DEFINE_PROP_INT32("x-txburst", VirtIOPCIProxy, net.txburst, TX_BURST),
1046 40021f08 Anthony Liguori
    DEFINE_PROP_STRING("tx", VirtIOPCIProxy, net.tx),
1047 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1048 40021f08 Anthony Liguori
};
1049 40021f08 Anthony Liguori
1050 40021f08 Anthony Liguori
static void virtio_net_class_init(ObjectClass *klass, void *data)
1051 40021f08 Anthony Liguori
{
1052 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1053 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1054 40021f08 Anthony Liguori
1055 40021f08 Anthony Liguori
    k->init = virtio_net_init_pci;
1056 40021f08 Anthony Liguori
    k->exit = virtio_net_exit_pci;
1057 c45e5b5b Gerd Hoffmann
    k->romfile = "efi-virtio.rom";
1058 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1059 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_VIRTIO_NET;
1060 40021f08 Anthony Liguori
    k->revision = VIRTIO_PCI_ABI_VERSION;
1061 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_NETWORK_ETHERNET;
1062 39bffca2 Anthony Liguori
    dc->reset = virtio_pci_reset;
1063 39bffca2 Anthony Liguori
    dc->props = virtio_net_properties;
1064 40021f08 Anthony Liguori
}
1065 40021f08 Anthony Liguori
1066 8c43a6f0 Andreas Färber
static const TypeInfo virtio_net_info = {
1067 39bffca2 Anthony Liguori
    .name          = "virtio-net-pci",
1068 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
1069 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOPCIProxy),
1070 39bffca2 Anthony Liguori
    .class_init    = virtio_net_class_init,
1071 e855761c Anthony Liguori
};
1072 e855761c Anthony Liguori
1073 40021f08 Anthony Liguori
static Property virtio_serial_properties[] = {
1074 40021f08 Anthony Liguori
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
1075 554f1997 Gal Hammer
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
1076 40021f08 Anthony Liguori
    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
1077 40021f08 Anthony Liguori
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
1078 40021f08 Anthony Liguori
    DEFINE_PROP_UINT32("max_ports", VirtIOPCIProxy, serial.max_virtserial_ports, 31),
1079 40021f08 Anthony Liguori
    DEFINE_PROP_END_OF_LIST(),
1080 e855761c Anthony Liguori
};
1081 e855761c Anthony Liguori
1082 40021f08 Anthony Liguori
static void virtio_serial_class_init(ObjectClass *klass, void *data)
1083 40021f08 Anthony Liguori
{
1084 39bffca2 Anthony Liguori
    DeviceClass *dc = DEVICE_CLASS(klass);
1085 40021f08 Anthony Liguori
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1086 40021f08 Anthony Liguori
1087 40021f08 Anthony Liguori
    k->init = virtio_serial_init_pci;
1088 40021f08 Anthony Liguori
    k->exit = virtio_serial_exit_pci;
1089 40021f08 Anthony Liguori
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1090 40021f08 Anthony Liguori
    k->device_id = PCI_DEVICE_ID_VIRTIO_CONSOLE;
1091 40021f08 Anthony Liguori
    k->revision = VIRTIO_PCI_ABI_VERSION;
1092 40021f08 Anthony Liguori
    k->class_id = PCI_CLASS_COMMUNICATION_OTHER;
1093 39bffca2 Anthony Liguori
    dc->reset = virtio_pci_reset;
1094 39bffca2 Anthony Liguori
    dc->props = virtio_serial_properties;
1095 40021f08 Anthony Liguori
}
1096 40021f08 Anthony Liguori
1097 8c43a6f0 Andreas Färber
static const TypeInfo virtio_serial_info = {
1098 39bffca2 Anthony Liguori
    .name          = "virtio-serial-pci",
1099 39bffca2 Anthony Liguori
    .parent        = TYPE_PCI_DEVICE,
1100 39bffca2 Anthony Liguori
    .instance_size = sizeof(VirtIOPCIProxy),
1101 39bffca2 Anthony Liguori
    .class_init    = virtio_serial_class_init,
1102 40021f08 Anthony Liguori
};
1103 40021f08 Anthony Liguori
1104 16c915ba Amit Shah
static void virtio_rng_initfn(Object *obj)
1105 16c915ba Amit Shah
{
1106 16c915ba Amit Shah
    PCIDevice *pci_dev = PCI_DEVICE(obj);
1107 16c915ba Amit Shah
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1108 16c915ba Amit Shah
1109 16c915ba Amit Shah
    object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,
1110 16c915ba Amit Shah
                             (Object **)&proxy->rng.rng, NULL);
1111 16c915ba Amit Shah
}
1112 16c915ba Amit Shah
1113 16c915ba Amit Shah
static Property virtio_rng_properties[] = {
1114 16c915ba Amit Shah
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
1115 904d6f58 Anthony Liguori
    /* Set a default rate limit of 2^47 bytes per minute or roughly 2TB/s.  If
1116 904d6f58 Anthony Liguori
       you have an entropy source capable of generating more entropy than this
1117 904d6f58 Anthony Liguori
       and you can pass it through via virtio-rng, then hats off to you.  Until
1118 904d6f58 Anthony Liguori
       then, this is unlimited for all practical purposes.
1119 904d6f58 Anthony Liguori
    */
1120 904d6f58 Anthony Liguori
    DEFINE_PROP_UINT64("max-bytes", VirtIOPCIProxy, rng.max_bytes, INT64_MAX),
1121 904d6f58 Anthony Liguori
    DEFINE_PROP_UINT32("period", VirtIOPCIProxy, rng.period_ms, 1 << 16),
1122 16c915ba Amit Shah
    DEFINE_PROP_END_OF_LIST(),
1123 16c915ba Amit Shah
};
1124 16c915ba Amit Shah
1125 16c915ba Amit Shah
static void virtio_rng_class_init(ObjectClass *klass, void *data)
1126 16c915ba Amit Shah
{
1127 16c915ba Amit Shah
    DeviceClass *dc = DEVICE_CLASS(klass);
1128 16c915ba Amit Shah
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1129 16c915ba Amit Shah
1130 16c915ba Amit Shah
    k->init = virtio_rng_init_pci;
1131 16c915ba Amit Shah
    k->exit = virtio_rng_exit_pci;
1132 16c915ba Amit Shah
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1133 16c915ba Amit Shah
    k->device_id = PCI_DEVICE_ID_VIRTIO_RNG;
1134 16c915ba Amit Shah
    k->revision = VIRTIO_PCI_ABI_VERSION;
1135 16c915ba Amit Shah
    k->class_id = PCI_CLASS_OTHERS;
1136 16c915ba Amit Shah
    dc->reset = virtio_pci_reset;
1137 16c915ba Amit Shah
    dc->props = virtio_rng_properties;
1138 16c915ba Amit Shah
}
1139 16c915ba Amit Shah
1140 8c43a6f0 Andreas Färber
static const TypeInfo virtio_rng_info = {
1141 16c915ba Amit Shah
    .name          = "virtio-rng-pci",
1142 16c915ba Amit Shah
    .parent        = TYPE_PCI_DEVICE,
1143 16c915ba Amit Shah
    .instance_size = sizeof(VirtIOPCIProxy),
1144 16c915ba Amit Shah
    .instance_init = virtio_rng_initfn,
1145 16c915ba Amit Shah
    .class_init    = virtio_rng_class_init,
1146 16c915ba Amit Shah
};
1147 16c915ba Amit Shah
1148 60653b28 Paolo Bonzini
#ifdef CONFIG_VIRTFS
1149 60653b28 Paolo Bonzini
static int virtio_9p_init_pci(PCIDevice *pci_dev)
1150 60653b28 Paolo Bonzini
{
1151 60653b28 Paolo Bonzini
    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
1152 60653b28 Paolo Bonzini
    VirtIODevice *vdev;
1153 60653b28 Paolo Bonzini
1154 60653b28 Paolo Bonzini
    vdev = virtio_9p_init(&pci_dev->qdev, &proxy->fsconf);
1155 60653b28 Paolo Bonzini
    vdev->nvectors = proxy->nvectors;
1156 60653b28 Paolo Bonzini
    virtio_init_pci(proxy, vdev);
1157 60653b28 Paolo Bonzini
    /* make the actual value visible */
1158 60653b28 Paolo Bonzini
    proxy->nvectors = vdev->nvectors;
1159 60653b28 Paolo Bonzini
    return 0;
1160 60653b28 Paolo Bonzini
}
1161 60653b28 Paolo Bonzini
1162 60653b28 Paolo Bonzini
static Property virtio_9p_properties[] = {
1163 60653b28 Paolo Bonzini
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
1164 60653b28 Paolo Bonzini
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
1165 60653b28 Paolo Bonzini
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
1166 60653b28 Paolo Bonzini
    DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
1167 60653b28 Paolo Bonzini
    DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
1168 60653b28 Paolo Bonzini
    DEFINE_PROP_END_OF_LIST(),
1169 60653b28 Paolo Bonzini
};
1170 60653b28 Paolo Bonzini
1171 60653b28 Paolo Bonzini
static void virtio_9p_class_init(ObjectClass *klass, void *data)
1172 60653b28 Paolo Bonzini
{
1173 60653b28 Paolo Bonzini
    DeviceClass *dc = DEVICE_CLASS(klass);
1174 60653b28 Paolo Bonzini
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1175 60653b28 Paolo Bonzini
1176 60653b28 Paolo Bonzini
    k->init = virtio_9p_init_pci;
1177 60653b28 Paolo Bonzini
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1178 60653b28 Paolo Bonzini
    k->device_id = PCI_DEVICE_ID_VIRTIO_9P;
1179 60653b28 Paolo Bonzini
    k->revision = VIRTIO_PCI_ABI_VERSION;
1180 60653b28 Paolo Bonzini
    k->class_id = 0x2;
1181 60653b28 Paolo Bonzini
    dc->props = virtio_9p_properties;
1182 60653b28 Paolo Bonzini
    dc->reset = virtio_pci_reset;
1183 60653b28 Paolo Bonzini
}
1184 60653b28 Paolo Bonzini
1185 60653b28 Paolo Bonzini
static const TypeInfo virtio_9p_info = {
1186 60653b28 Paolo Bonzini
    .name          = "virtio-9p-pci",
1187 60653b28 Paolo Bonzini
    .parent        = TYPE_PCI_DEVICE,
1188 60653b28 Paolo Bonzini
    .instance_size = sizeof(VirtIOPCIProxy),
1189 60653b28 Paolo Bonzini
    .class_init    = virtio_9p_class_init,
1190 60653b28 Paolo Bonzini
};
1191 60653b28 Paolo Bonzini
#endif
1192 60653b28 Paolo Bonzini
1193 085bccb7 KONRAD Frederic
/*
1194 085bccb7 KONRAD Frederic
 * virtio-pci: This is the PCIDevice which has a virtio-pci-bus.
1195 085bccb7 KONRAD Frederic
 */
1196 085bccb7 KONRAD Frederic
1197 085bccb7 KONRAD Frederic
/* This is called by virtio-bus just after the device is plugged. */
1198 085bccb7 KONRAD Frederic
static void virtio_pci_device_plugged(DeviceState *d)
1199 085bccb7 KONRAD Frederic
{
1200 085bccb7 KONRAD Frederic
    VirtIOPCIProxy *proxy = VIRTIO_PCI(d);
1201 085bccb7 KONRAD Frederic
    VirtioBusState *bus = &proxy->bus;
1202 085bccb7 KONRAD Frederic
    uint8_t *config;
1203 085bccb7 KONRAD Frederic
    uint32_t size;
1204 085bccb7 KONRAD Frederic
1205 085bccb7 KONRAD Frederic
    proxy->vdev = bus->vdev;
1206 085bccb7 KONRAD Frederic
1207 085bccb7 KONRAD Frederic
    config = proxy->pci_dev.config;
1208 085bccb7 KONRAD Frederic
    if (proxy->class_code) {
1209 085bccb7 KONRAD Frederic
        pci_config_set_class(config, proxy->class_code);
1210 085bccb7 KONRAD Frederic
    }
1211 085bccb7 KONRAD Frederic
    pci_set_word(config + PCI_SUBSYSTEM_VENDOR_ID,
1212 085bccb7 KONRAD Frederic
                 pci_get_word(config + PCI_VENDOR_ID));
1213 085bccb7 KONRAD Frederic
    pci_set_word(config + PCI_SUBSYSTEM_ID, virtio_bus_get_vdev_id(bus));
1214 085bccb7 KONRAD Frederic
    config[PCI_INTERRUPT_PIN] = 1;
1215 085bccb7 KONRAD Frederic
1216 085bccb7 KONRAD Frederic
    if (proxy->nvectors &&
1217 085bccb7 KONRAD Frederic
        msix_init_exclusive_bar(&proxy->pci_dev, proxy->nvectors, 1)) {
1218 085bccb7 KONRAD Frederic
        proxy->nvectors = 0;
1219 085bccb7 KONRAD Frederic
    }
1220 085bccb7 KONRAD Frederic
1221 085bccb7 KONRAD Frederic
    proxy->pci_dev.config_write = virtio_write_config;
1222 085bccb7 KONRAD Frederic
1223 085bccb7 KONRAD Frederic
    size = VIRTIO_PCI_REGION_SIZE(&proxy->pci_dev)
1224 085bccb7 KONRAD Frederic
         + virtio_bus_get_vdev_config_len(bus);
1225 085bccb7 KONRAD Frederic
    if (size & (size - 1)) {
1226 085bccb7 KONRAD Frederic
        size = 1 << qemu_fls(size);
1227 085bccb7 KONRAD Frederic
    }
1228 085bccb7 KONRAD Frederic
1229 085bccb7 KONRAD Frederic
    memory_region_init_io(&proxy->bar, &virtio_pci_config_ops, proxy,
1230 085bccb7 KONRAD Frederic
                          "virtio-pci", size);
1231 085bccb7 KONRAD Frederic
    pci_register_bar(&proxy->pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO,
1232 085bccb7 KONRAD Frederic
                     &proxy->bar);
1233 085bccb7 KONRAD Frederic
1234 085bccb7 KONRAD Frederic
    if (!kvm_has_many_ioeventfds()) {
1235 085bccb7 KONRAD Frederic
        proxy->flags &= ~VIRTIO_PCI_FLAG_USE_IOEVENTFD;
1236 085bccb7 KONRAD Frederic
    }
1237 085bccb7 KONRAD Frederic
1238 085bccb7 KONRAD Frederic
    proxy->host_features |= 0x1 << VIRTIO_F_NOTIFY_ON_EMPTY;
1239 085bccb7 KONRAD Frederic
    proxy->host_features |= 0x1 << VIRTIO_F_BAD_FEATURE;
1240 085bccb7 KONRAD Frederic
    proxy->host_features = virtio_bus_get_vdev_features(bus,
1241 085bccb7 KONRAD Frederic
                                                      proxy->host_features);
1242 085bccb7 KONRAD Frederic
}
1243 085bccb7 KONRAD Frederic
1244 085bccb7 KONRAD Frederic
static int virtio_pci_init(PCIDevice *pci_dev)
1245 085bccb7 KONRAD Frederic
{
1246 085bccb7 KONRAD Frederic
    VirtIOPCIProxy *dev = VIRTIO_PCI(pci_dev);
1247 085bccb7 KONRAD Frederic
    VirtioPCIClass *k = VIRTIO_PCI_GET_CLASS(pci_dev);
1248 085bccb7 KONRAD Frederic
    virtio_pci_bus_new(&dev->bus, dev);
1249 085bccb7 KONRAD Frederic
    if (k->init != NULL) {
1250 085bccb7 KONRAD Frederic
        return k->init(dev);
1251 085bccb7 KONRAD Frederic
    }
1252 085bccb7 KONRAD Frederic
    return 0;
1253 085bccb7 KONRAD Frederic
}
1254 085bccb7 KONRAD Frederic
1255 085bccb7 KONRAD Frederic
static void virtio_pci_exit(PCIDevice *pci_dev)
1256 085bccb7 KONRAD Frederic
{
1257 085bccb7 KONRAD Frederic
    VirtIOPCIProxy *proxy = VIRTIO_PCI(pci_dev);
1258 10479a80 KONRAD Frederic
    virtio_pci_stop_ioeventfd(proxy);
1259 085bccb7 KONRAD Frederic
    virtio_exit_pci(pci_dev);
1260 085bccb7 KONRAD Frederic
}
1261 085bccb7 KONRAD Frederic
1262 085bccb7 KONRAD Frederic
/*
1263 085bccb7 KONRAD Frederic
 * This will be renamed virtio_pci_reset at the end of the series.
1264 085bccb7 KONRAD Frederic
 * virtio_pci_reset is still in use at this moment.
1265 085bccb7 KONRAD Frederic
 */
1266 085bccb7 KONRAD Frederic
static void virtio_pci_rst(DeviceState *qdev)
1267 085bccb7 KONRAD Frederic
{
1268 085bccb7 KONRAD Frederic
    VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev);
1269 085bccb7 KONRAD Frederic
    VirtioBusState *bus = VIRTIO_BUS(&proxy->bus);
1270 085bccb7 KONRAD Frederic
    virtio_pci_stop_ioeventfd(proxy);
1271 085bccb7 KONRAD Frederic
    virtio_bus_reset(bus);
1272 085bccb7 KONRAD Frederic
    msix_unuse_all_vectors(&proxy->pci_dev);
1273 085bccb7 KONRAD Frederic
    proxy->flags &= ~VIRTIO_PCI_FLAG_BUS_MASTER_BUG;
1274 085bccb7 KONRAD Frederic
}
1275 085bccb7 KONRAD Frederic
1276 085bccb7 KONRAD Frederic
static void virtio_pci_class_init(ObjectClass *klass, void *data)
1277 085bccb7 KONRAD Frederic
{
1278 085bccb7 KONRAD Frederic
    DeviceClass *dc = DEVICE_CLASS(klass);
1279 085bccb7 KONRAD Frederic
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
1280 085bccb7 KONRAD Frederic
1281 085bccb7 KONRAD Frederic
    k->init = virtio_pci_init;
1282 085bccb7 KONRAD Frederic
    k->exit = virtio_pci_exit;
1283 085bccb7 KONRAD Frederic
    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1284 085bccb7 KONRAD Frederic
    k->revision = VIRTIO_PCI_ABI_VERSION;
1285 085bccb7 KONRAD Frederic
    k->class_id = PCI_CLASS_OTHERS;
1286 085bccb7 KONRAD Frederic
    dc->reset = virtio_pci_rst;
1287 085bccb7 KONRAD Frederic
}
1288 085bccb7 KONRAD Frederic
1289 085bccb7 KONRAD Frederic
static const TypeInfo virtio_pci_info = {
1290 085bccb7 KONRAD Frederic
    .name          = TYPE_VIRTIO_PCI,
1291 085bccb7 KONRAD Frederic
    .parent        = TYPE_PCI_DEVICE,
1292 085bccb7 KONRAD Frederic
    .instance_size = sizeof(VirtIOPCIProxy),
1293 085bccb7 KONRAD Frederic
    .class_init    = virtio_pci_class_init,
1294 085bccb7 KONRAD Frederic
    .class_size    = sizeof(VirtioPCIClass),
1295 085bccb7 KONRAD Frederic
    .abstract      = true,
1296 085bccb7 KONRAD Frederic
};
1297 085bccb7 KONRAD Frederic
1298 653ced07 KONRAD Frederic
/* virtio-blk-pci */
1299 653ced07 KONRAD Frederic
1300 653ced07 KONRAD Frederic
static Property virtio_blk_pci_properties[] = {
1301 653ced07 KONRAD Frederic
    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
1302 653ced07 KONRAD Frederic
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
1303 653ced07 KONRAD Frederic
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
1304 653ced07 KONRAD Frederic
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
1305 653ced07 KONRAD Frederic
#ifdef CONFIG_VIRTIO_BLK_DATA_PLANE
1306 653ced07 KONRAD Frederic
    DEFINE_PROP_BIT("x-data-plane", VirtIOBlkPCI, blk.data_plane, 0, false),
1307 653ced07 KONRAD Frederic
#endif
1308 653ced07 KONRAD Frederic
    DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
1309 653ced07 KONRAD Frederic
    DEFINE_VIRTIO_BLK_PROPERTIES(VirtIOBlkPCI, blk),
1310 653ced07 KONRAD Frederic
    DEFINE_PROP_END_OF_LIST(),
1311 653ced07 KONRAD Frederic
};
1312 653ced07 KONRAD Frederic
1313 653ced07 KONRAD Frederic
static int virtio_blk_pci_init(VirtIOPCIProxy *vpci_dev)
1314 653ced07 KONRAD Frederic
{
1315 653ced07 KONRAD Frederic
    VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(vpci_dev);
1316 653ced07 KONRAD Frederic
    DeviceState *vdev = DEVICE(&dev->vdev);
1317 653ced07 KONRAD Frederic
    virtio_blk_set_conf(vdev, &(dev->blk));
1318 653ced07 KONRAD Frederic
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1319 653ced07 KONRAD Frederic
    if (qdev_init(vdev) < 0) {
1320 653ced07 KONRAD Frederic
        return -1;
1321 653ced07 KONRAD Frederic
    }
1322 653ced07 KONRAD Frederic
    return 0;
1323 653ced07 KONRAD Frederic
}
1324 653ced07 KONRAD Frederic
1325 653ced07 KONRAD Frederic
static void virtio_blk_pci_class_init(ObjectClass *klass, void *data)
1326 653ced07 KONRAD Frederic
{
1327 653ced07 KONRAD Frederic
    DeviceClass *dc = DEVICE_CLASS(klass);
1328 653ced07 KONRAD Frederic
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
1329 653ced07 KONRAD Frederic
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1330 653ced07 KONRAD Frederic
1331 653ced07 KONRAD Frederic
    dc->props = virtio_blk_pci_properties;
1332 653ced07 KONRAD Frederic
    k->init = virtio_blk_pci_init;
1333 653ced07 KONRAD Frederic
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1334 653ced07 KONRAD Frederic
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BLOCK;
1335 653ced07 KONRAD Frederic
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
1336 653ced07 KONRAD Frederic
    pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
1337 653ced07 KONRAD Frederic
}
1338 653ced07 KONRAD Frederic
1339 653ced07 KONRAD Frederic
static void virtio_blk_pci_instance_init(Object *obj)
1340 653ced07 KONRAD Frederic
{
1341 653ced07 KONRAD Frederic
    VirtIOBlkPCI *dev = VIRTIO_BLK_PCI(obj);
1342 653ced07 KONRAD Frederic
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BLK);
1343 653ced07 KONRAD Frederic
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
1344 653ced07 KONRAD Frederic
}
1345 653ced07 KONRAD Frederic
1346 653ced07 KONRAD Frederic
static const TypeInfo virtio_blk_pci_info = {
1347 653ced07 KONRAD Frederic
    .name          = TYPE_VIRTIO_BLK_PCI,
1348 653ced07 KONRAD Frederic
    .parent        = TYPE_VIRTIO_PCI,
1349 653ced07 KONRAD Frederic
    .instance_size = sizeof(VirtIOBlkPCI),
1350 653ced07 KONRAD Frederic
    .instance_init = virtio_blk_pci_instance_init,
1351 653ced07 KONRAD Frederic
    .class_init    = virtio_blk_pci_class_init,
1352 653ced07 KONRAD Frederic
};
1353 653ced07 KONRAD Frederic
1354 bc7b90a0 KONRAD Frederic
/* virtio-scsi-pci */
1355 bc7b90a0 KONRAD Frederic
1356 bc7b90a0 KONRAD Frederic
static Property virtio_scsi_pci_properties[] = {
1357 bc7b90a0 KONRAD Frederic
    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
1358 bc7b90a0 KONRAD Frederic
                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
1359 bc7b90a0 KONRAD Frederic
    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
1360 bc7b90a0 KONRAD Frederic
                       DEV_NVECTORS_UNSPECIFIED),
1361 bc7b90a0 KONRAD Frederic
    DEFINE_VIRTIO_SCSI_FEATURES(VirtIOPCIProxy, host_features),
1362 bc7b90a0 KONRAD Frederic
    DEFINE_VIRTIO_SCSI_PROPERTIES(VirtIOSCSIPCI, vdev.conf),
1363 bc7b90a0 KONRAD Frederic
    DEFINE_PROP_END_OF_LIST(),
1364 bc7b90a0 KONRAD Frederic
};
1365 bc7b90a0 KONRAD Frederic
1366 bc7b90a0 KONRAD Frederic
static int virtio_scsi_pci_init_pci(VirtIOPCIProxy *vpci_dev)
1367 bc7b90a0 KONRAD Frederic
{
1368 bc7b90a0 KONRAD Frederic
    VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(vpci_dev);
1369 bc7b90a0 KONRAD Frederic
    DeviceState *vdev = DEVICE(&dev->vdev);
1370 bc7b90a0 KONRAD Frederic
1371 bc7b90a0 KONRAD Frederic
    if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
1372 bc7b90a0 KONRAD Frederic
        vpci_dev->nvectors = dev->vdev.conf.num_queues + 3;
1373 bc7b90a0 KONRAD Frederic
    }
1374 bc7b90a0 KONRAD Frederic
1375 bc7b90a0 KONRAD Frederic
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1376 bc7b90a0 KONRAD Frederic
    if (qdev_init(vdev) < 0) {
1377 bc7b90a0 KONRAD Frederic
        return -1;
1378 bc7b90a0 KONRAD Frederic
    }
1379 bc7b90a0 KONRAD Frederic
    return 0;
1380 bc7b90a0 KONRAD Frederic
}
1381 bc7b90a0 KONRAD Frederic
1382 bc7b90a0 KONRAD Frederic
static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data)
1383 bc7b90a0 KONRAD Frederic
{
1384 bc7b90a0 KONRAD Frederic
    DeviceClass *dc = DEVICE_CLASS(klass);
1385 bc7b90a0 KONRAD Frederic
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
1386 bc7b90a0 KONRAD Frederic
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1387 bc7b90a0 KONRAD Frederic
    k->init = virtio_scsi_pci_init_pci;
1388 bc7b90a0 KONRAD Frederic
    dc->props = virtio_scsi_pci_properties;
1389 bc7b90a0 KONRAD Frederic
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1390 bc7b90a0 KONRAD Frederic
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SCSI;
1391 bc7b90a0 KONRAD Frederic
    pcidev_k->revision = 0x00;
1392 bc7b90a0 KONRAD Frederic
    pcidev_k->class_id = PCI_CLASS_STORAGE_SCSI;
1393 bc7b90a0 KONRAD Frederic
}
1394 bc7b90a0 KONRAD Frederic
1395 bc7b90a0 KONRAD Frederic
static void virtio_scsi_pci_instance_init(Object *obj)
1396 bc7b90a0 KONRAD Frederic
{
1397 bc7b90a0 KONRAD Frederic
    VirtIOSCSIPCI *dev = VIRTIO_SCSI_PCI(obj);
1398 bc7b90a0 KONRAD Frederic
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_SCSI);
1399 bc7b90a0 KONRAD Frederic
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
1400 bc7b90a0 KONRAD Frederic
}
1401 bc7b90a0 KONRAD Frederic
1402 bc7b90a0 KONRAD Frederic
static const TypeInfo virtio_scsi_pci_info = {
1403 bc7b90a0 KONRAD Frederic
    .name          = TYPE_VIRTIO_SCSI_PCI,
1404 bc7b90a0 KONRAD Frederic
    .parent        = TYPE_VIRTIO_PCI,
1405 bc7b90a0 KONRAD Frederic
    .instance_size = sizeof(VirtIOSCSIPCI),
1406 bc7b90a0 KONRAD Frederic
    .instance_init = virtio_scsi_pci_instance_init,
1407 bc7b90a0 KONRAD Frederic
    .class_init    = virtio_scsi_pci_class_init,
1408 bc7b90a0 KONRAD Frederic
};
1409 bc7b90a0 KONRAD Frederic
1410 e378e88d KONRAD Frederic
/* virtio-balloon-pci */
1411 e378e88d KONRAD Frederic
1412 e378e88d KONRAD Frederic
static Property virtio_balloon_pci_properties[] = {
1413 e378e88d KONRAD Frederic
    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
1414 e378e88d KONRAD Frederic
    DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
1415 e378e88d KONRAD Frederic
    DEFINE_PROP_END_OF_LIST(),
1416 e378e88d KONRAD Frederic
};
1417 e378e88d KONRAD Frederic
1418 e378e88d KONRAD Frederic
static int virtio_balloon_pci_init(VirtIOPCIProxy *vpci_dev)
1419 e378e88d KONRAD Frederic
{
1420 e378e88d KONRAD Frederic
    VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(vpci_dev);
1421 e378e88d KONRAD Frederic
    DeviceState *vdev = DEVICE(&dev->vdev);
1422 e378e88d KONRAD Frederic
1423 e378e88d KONRAD Frederic
    if (vpci_dev->class_code != PCI_CLASS_OTHERS &&
1424 e378e88d KONRAD Frederic
        vpci_dev->class_code != PCI_CLASS_MEMORY_RAM) { /* qemu < 1.1 */
1425 e378e88d KONRAD Frederic
        vpci_dev->class_code = PCI_CLASS_OTHERS;
1426 e378e88d KONRAD Frederic
    }
1427 e378e88d KONRAD Frederic
1428 e378e88d KONRAD Frederic
    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
1429 e378e88d KONRAD Frederic
    if (qdev_init(vdev) < 0) {
1430 e378e88d KONRAD Frederic
        return -1;
1431 e378e88d KONRAD Frederic
    }
1432 e378e88d KONRAD Frederic
    return 0;
1433 e378e88d KONRAD Frederic
}
1434 e378e88d KONRAD Frederic
1435 e378e88d KONRAD Frederic
static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
1436 e378e88d KONRAD Frederic
{
1437 e378e88d KONRAD Frederic
    DeviceClass *dc = DEVICE_CLASS(klass);
1438 e378e88d KONRAD Frederic
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
1439 e378e88d KONRAD Frederic
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
1440 e378e88d KONRAD Frederic
    k->init = virtio_balloon_pci_init;
1441 e378e88d KONRAD Frederic
    dc->props = virtio_balloon_pci_properties;
1442 e378e88d KONRAD Frederic
    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
1443 e378e88d KONRAD Frederic
    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
1444 e378e88d KONRAD Frederic
    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
1445 e378e88d KONRAD Frederic
    pcidev_k->class_id = PCI_CLASS_OTHERS;
1446 e378e88d KONRAD Frederic
}
1447 e378e88d KONRAD Frederic
1448 e378e88d KONRAD Frederic
static void virtio_balloon_pci_instance_init(Object *obj)
1449 e378e88d KONRAD Frederic
{
1450 e378e88d KONRAD Frederic
    VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(obj);
1451 e378e88d KONRAD Frederic
    object_initialize(OBJECT(&dev->vdev), TYPE_VIRTIO_BALLOON);
1452 e378e88d KONRAD Frederic
    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
1453 e378e88d KONRAD Frederic
}
1454 e378e88d KONRAD Frederic
1455 e378e88d KONRAD Frederic
static const TypeInfo virtio_balloon_pci_info = {
1456 e378e88d KONRAD Frederic
    .name          = TYPE_VIRTIO_BALLOON_PCI,
1457 e378e88d KONRAD Frederic
    .parent        = TYPE_VIRTIO_PCI,
1458 e378e88d KONRAD Frederic
    .instance_size = sizeof(VirtIOBalloonPCI),
1459 e378e88d KONRAD Frederic
    .instance_init = virtio_balloon_pci_instance_init,
1460 e378e88d KONRAD Frederic
    .class_init    = virtio_balloon_pci_class_init,
1461 e378e88d KONRAD Frederic
};
1462 e378e88d KONRAD Frederic
1463 0a2acf5e KONRAD Frederic
/* virtio-pci-bus */
1464 0a2acf5e KONRAD Frederic
1465 0a2acf5e KONRAD Frederic
void virtio_pci_bus_new(VirtioBusState *bus, VirtIOPCIProxy *dev)
1466 0a2acf5e KONRAD Frederic
{
1467 0a2acf5e KONRAD Frederic
    DeviceState *qdev = DEVICE(dev);
1468 0a2acf5e KONRAD Frederic
    BusState *qbus;
1469 0a2acf5e KONRAD Frederic
    qbus_create_inplace((BusState *)bus, TYPE_VIRTIO_PCI_BUS, qdev, NULL);
1470 0a2acf5e KONRAD Frederic
    qbus = BUS(bus);
1471 cbd19063 KONRAD Frederic
    qbus->allow_hotplug = 1;
1472 0a2acf5e KONRAD Frederic
}
1473 0a2acf5e KONRAD Frederic
1474 0a2acf5e KONRAD Frederic
static void virtio_pci_bus_class_init(ObjectClass *klass, void *data)
1475 0a2acf5e KONRAD Frederic
{
1476 0a2acf5e KONRAD Frederic
    BusClass *bus_class = BUS_CLASS(klass);
1477 0a2acf5e KONRAD Frederic
    VirtioBusClass *k = VIRTIO_BUS_CLASS(klass);
1478 0a2acf5e KONRAD Frederic
    bus_class->max_dev = 1;
1479 0a2acf5e KONRAD Frederic
    k->notify = virtio_pci_notify;
1480 0a2acf5e KONRAD Frederic
    k->save_config = virtio_pci_save_config;
1481 0a2acf5e KONRAD Frederic
    k->load_config = virtio_pci_load_config;
1482 0a2acf5e KONRAD Frederic
    k->save_queue = virtio_pci_save_queue;
1483 0a2acf5e KONRAD Frederic
    k->load_queue = virtio_pci_load_queue;
1484 0a2acf5e KONRAD Frederic
    k->get_features = virtio_pci_get_features;
1485 0a2acf5e KONRAD Frederic
    k->query_guest_notifiers = virtio_pci_query_guest_notifiers;
1486 0a2acf5e KONRAD Frederic
    k->set_host_notifier = virtio_pci_set_host_notifier;
1487 0a2acf5e KONRAD Frederic
    k->set_guest_notifiers = virtio_pci_set_guest_notifiers;
1488 0a2acf5e KONRAD Frederic
    k->vmstate_change = virtio_pci_vmstate_change;
1489 085bccb7 KONRAD Frederic
    k->device_plugged = virtio_pci_device_plugged;
1490 0a2acf5e KONRAD Frederic
}
1491 0a2acf5e KONRAD Frederic
1492 0a2acf5e KONRAD Frederic
static const TypeInfo virtio_pci_bus_info = {
1493 0a2acf5e KONRAD Frederic
    .name          = TYPE_VIRTIO_PCI_BUS,
1494 0a2acf5e KONRAD Frederic
    .parent        = TYPE_VIRTIO_BUS,
1495 0a2acf5e KONRAD Frederic
    .instance_size = sizeof(VirtioPCIBusState),
1496 0a2acf5e KONRAD Frederic
    .class_init    = virtio_pci_bus_class_init,
1497 0a2acf5e KONRAD Frederic
};
1498 0a2acf5e KONRAD Frederic
1499 83f7d43a Andreas Färber
static void virtio_pci_register_types(void)
1500 53c25cea Paul Brook
{
1501 39bffca2 Anthony Liguori
    type_register_static(&virtio_net_info);
1502 39bffca2 Anthony Liguori
    type_register_static(&virtio_serial_info);
1503 16c915ba Amit Shah
    type_register_static(&virtio_rng_info);
1504 0a2acf5e KONRAD Frederic
    type_register_static(&virtio_pci_bus_info);
1505 085bccb7 KONRAD Frederic
    type_register_static(&virtio_pci_info);
1506 60653b28 Paolo Bonzini
#ifdef CONFIG_VIRTFS
1507 60653b28 Paolo Bonzini
    type_register_static(&virtio_9p_info);
1508 60653b28 Paolo Bonzini
#endif
1509 653ced07 KONRAD Frederic
    type_register_static(&virtio_blk_pci_info);
1510 bc7b90a0 KONRAD Frederic
    type_register_static(&virtio_scsi_pci_info);
1511 e378e88d KONRAD Frederic
    type_register_static(&virtio_balloon_pci_info);
1512 53c25cea Paul Brook
}
1513 53c25cea Paul Brook
1514 83f7d43a Andreas Färber
type_init(virtio_pci_register_types)