Statistics
| Branch: | Revision:

root / hw / virtio.c @ cd92f4cc

History | View | Annotate | Download (21.8 kB)

1
/*
2
 * Virtio Support
3
 *
4
 * Copyright IBM, Corp. 2007
5
 *
6
 * Authors:
7
 *  Anthony Liguori   <aliguori@us.ibm.com>
8
 *
9
 * This work is licensed under the terms of the GNU GPL, version 2.  See
10
 * the COPYING file in the top-level directory.
11
 *
12
 */
13

    
14
#include <inttypes.h>
15

    
16
#include "trace.h"
17
#include "qemu-error.h"
18
#include "virtio.h"
19
#include "sysemu.h"
20

    
21
/* The alignment to use between consumer and producer parts of vring.
22
 * x86 pagesize again. */
23
#define VIRTIO_PCI_VRING_ALIGN         4096
24

    
25
/* QEMU doesn't strictly need write barriers since everything runs in
26
 * lock-step.  We'll leave the calls to wmb() in though to make it obvious for
27
 * KVM or if kqemu gets SMP support.
28
 * In any case, we must prevent the compiler from reordering the code.
29
 * TODO: we likely need some rmb()/mb() as well.
30
 */
31

    
32
#define wmb() __asm__ __volatile__("": : :"memory")
33

    
34
typedef struct VRingDesc
35
{
36
    uint64_t addr;
37
    uint32_t len;
38
    uint16_t flags;
39
    uint16_t next;
40
} VRingDesc;
41

    
42
typedef struct VRingAvail
43
{
44
    uint16_t flags;
45
    uint16_t idx;
46
    uint16_t ring[0];
47
} VRingAvail;
48

    
49
typedef struct VRingUsedElem
50
{
51
    uint32_t id;
52
    uint32_t len;
53
} VRingUsedElem;
54

    
55
typedef struct VRingUsed
56
{
57
    uint16_t flags;
58
    uint16_t idx;
59
    VRingUsedElem ring[0];
60
} VRingUsed;
61

    
62
typedef struct VRing
63
{
64
    unsigned int num;
65
    target_phys_addr_t desc;
66
    target_phys_addr_t avail;
67
    target_phys_addr_t used;
68
} VRing;
69

    
70
struct VirtQueue
71
{
72
    VRing vring;
73
    target_phys_addr_t pa;
74
    uint16_t last_avail_idx;
75
    int inuse;
76
    uint16_t vector;
77
    void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
78
    VirtIODevice *vdev;
79
    EventNotifier guest_notifier;
80
    EventNotifier host_notifier;
81
};
82

    
83
/* virt queue functions */
84
static void virtqueue_init(VirtQueue *vq)
85
{
86
    target_phys_addr_t pa = vq->pa;
87

    
88
    vq->vring.desc = pa;
89
    vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
90
    vq->vring.used = vring_align(vq->vring.avail +
91
                                 offsetof(VRingAvail, ring[vq->vring.num]),
92
                                 VIRTIO_PCI_VRING_ALIGN);
93
}
94

    
95
static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i)
96
{
97
    target_phys_addr_t pa;
98
    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr);
99
    return ldq_phys(pa);
100
}
101

    
102
static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i)
103
{
104
    target_phys_addr_t pa;
105
    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len);
106
    return ldl_phys(pa);
107
}
108

    
109
static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i)
110
{
111
    target_phys_addr_t pa;
112
    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags);
113
    return lduw_phys(pa);
114
}
115

    
116
static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i)
117
{
118
    target_phys_addr_t pa;
119
    pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next);
120
    return lduw_phys(pa);
121
}
122

    
123
static inline uint16_t vring_avail_flags(VirtQueue *vq)
124
{
125
    target_phys_addr_t pa;
126
    pa = vq->vring.avail + offsetof(VRingAvail, flags);
127
    return lduw_phys(pa);
128
}
129

    
130
static inline uint16_t vring_avail_idx(VirtQueue *vq)
131
{
132
    target_phys_addr_t pa;
133
    pa = vq->vring.avail + offsetof(VRingAvail, idx);
134
    return lduw_phys(pa);
135
}
136

    
137
static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
138
{
139
    target_phys_addr_t pa;
140
    pa = vq->vring.avail + offsetof(VRingAvail, ring[i]);
141
    return lduw_phys(pa);
142
}
143

    
144
static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
145
{
146
    target_phys_addr_t pa;
147
    pa = vq->vring.used + offsetof(VRingUsed, ring[i].id);
148
    stl_phys(pa, val);
149
}
150

    
151
static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val)
152
{
153
    target_phys_addr_t pa;
154
    pa = vq->vring.used + offsetof(VRingUsed, ring[i].len);
155
    stl_phys(pa, val);
156
}
157

    
158
static uint16_t vring_used_idx(VirtQueue *vq)
159
{
160
    target_phys_addr_t pa;
161
    pa = vq->vring.used + offsetof(VRingUsed, idx);
162
    return lduw_phys(pa);
163
}
164

    
165
static inline void vring_used_idx_increment(VirtQueue *vq, uint16_t val)
166
{
167
    target_phys_addr_t pa;
168
    pa = vq->vring.used + offsetof(VRingUsed, idx);
169
    stw_phys(pa, vring_used_idx(vq) + val);
170
}
171

    
172
static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
173
{
174
    target_phys_addr_t pa;
175
    pa = vq->vring.used + offsetof(VRingUsed, flags);
176
    stw_phys(pa, lduw_phys(pa) | mask);
177
}
178

    
179
static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask)
180
{
181
    target_phys_addr_t pa;
182
    pa = vq->vring.used + offsetof(VRingUsed, flags);
183
    stw_phys(pa, lduw_phys(pa) & ~mask);
184
}
185

    
186
void virtio_queue_set_notification(VirtQueue *vq, int enable)
187
{
188
    if (enable)
189
        vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
190
    else
191
        vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY);
192
}
193

    
194
int virtio_queue_ready(VirtQueue *vq)
195
{
196
    return vq->vring.avail != 0;
197
}
198

    
199
int virtio_queue_empty(VirtQueue *vq)
200
{
201
    return vring_avail_idx(vq) == vq->last_avail_idx;
202
}
203

    
204
void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
205
                    unsigned int len, unsigned int idx)
206
{
207
    unsigned int offset;
208
    int i;
209

    
210
    trace_virtqueue_fill(vq, elem, len, idx);
211

    
212
    offset = 0;
213
    for (i = 0; i < elem->in_num; i++) {
214
        size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
215

    
216
        cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
217
                                  elem->in_sg[i].iov_len,
218
                                  1, size);
219

    
220
        offset += elem->in_sg[i].iov_len;
221
    }
222

    
223
    for (i = 0; i < elem->out_num; i++)
224
        cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
225
                                  elem->out_sg[i].iov_len,
226
                                  0, elem->out_sg[i].iov_len);
227

    
228
    idx = (idx + vring_used_idx(vq)) % vq->vring.num;
229

    
230
    /* Get a pointer to the next entry in the used ring. */
231
    vring_used_ring_id(vq, idx, elem->index);
232
    vring_used_ring_len(vq, idx, len);
233
}
234

    
235
void virtqueue_flush(VirtQueue *vq, unsigned int count)
236
{
237
    /* Make sure buffer is written before we update index. */
238
    wmb();
239
    trace_virtqueue_flush(vq, count);
240
    vring_used_idx_increment(vq, count);
241
    vq->inuse -= count;
242
}
243

    
244
void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
245
                    unsigned int len)
246
{
247
    virtqueue_fill(vq, elem, len, 0);
248
    virtqueue_flush(vq, 1);
249
}
250

    
251
static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
252
{
253
    uint16_t num_heads = vring_avail_idx(vq) - idx;
254

    
255
    /* Check it isn't doing very strange things with descriptor numbers. */
256
    if (num_heads > vq->vring.num) {
257
        error_report("Guest moved used index from %u to %u",
258
                     idx, vring_avail_idx(vq));
259
        exit(1);
260
    }
261

    
262
    return num_heads;
263
}
264

    
265
static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx)
266
{
267
    unsigned int head;
268

    
269
    /* Grab the next descriptor number they're advertising, and increment
270
     * the index we've seen. */
271
    head = vring_avail_ring(vq, idx % vq->vring.num);
272

    
273
    /* If their number is silly, that's a fatal mistake. */
274
    if (head >= vq->vring.num) {
275
        error_report("Guest says index %u is available", head);
276
        exit(1);
277
    }
278

    
279
    return head;
280
}
281

    
282
static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa,
283
                                    unsigned int i, unsigned int max)
284
{
285
    unsigned int next;
286

    
287
    /* If this descriptor says it doesn't chain, we're done. */
288
    if (!(vring_desc_flags(desc_pa, i) & VRING_DESC_F_NEXT))
289
        return max;
290

    
291
    /* Check they're not leading us off end of descriptors. */
292
    next = vring_desc_next(desc_pa, i);
293
    /* Make sure compiler knows to grab that: we don't want it changing! */
294
    wmb();
295

    
296
    if (next >= max) {
297
        error_report("Desc next is %u", next);
298
        exit(1);
299
    }
300

    
301
    return next;
302
}
303

    
304
int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
305
{
306
    unsigned int idx;
307
    int total_bufs, in_total, out_total;
308

    
309
    idx = vq->last_avail_idx;
310

    
311
    total_bufs = in_total = out_total = 0;
312
    while (virtqueue_num_heads(vq, idx)) {
313
        unsigned int max, num_bufs, indirect = 0;
314
        target_phys_addr_t desc_pa;
315
        int i;
316

    
317
        max = vq->vring.num;
318
        num_bufs = total_bufs;
319
        i = virtqueue_get_head(vq, idx++);
320
        desc_pa = vq->vring.desc;
321

    
322
        if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
323
            if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
324
                error_report("Invalid size for indirect buffer table");
325
                exit(1);
326
            }
327

    
328
            /* If we've got too many, that implies a descriptor loop. */
329
            if (num_bufs >= max) {
330
                error_report("Looped descriptor");
331
                exit(1);
332
            }
333

    
334
            /* loop over the indirect descriptor table */
335
            indirect = 1;
336
            max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
337
            num_bufs = i = 0;
338
            desc_pa = vring_desc_addr(desc_pa, i);
339
        }
340

    
341
        do {
342
            /* If we've got too many, that implies a descriptor loop. */
343
            if (++num_bufs > max) {
344
                error_report("Looped descriptor");
345
                exit(1);
346
            }
347

    
348
            if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
349
                if (in_bytes > 0 &&
350
                    (in_total += vring_desc_len(desc_pa, i)) >= in_bytes)
351
                    return 1;
352
            } else {
353
                if (out_bytes > 0 &&
354
                    (out_total += vring_desc_len(desc_pa, i)) >= out_bytes)
355
                    return 1;
356
            }
357
        } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
358

    
359
        if (!indirect)
360
            total_bufs = num_bufs;
361
        else
362
            total_bufs++;
363
    }
364

    
365
    return 0;
366
}
367

    
368
void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
369
    size_t num_sg, int is_write)
370
{
371
    unsigned int i;
372
    target_phys_addr_t len;
373

    
374
    for (i = 0; i < num_sg; i++) {
375
        len = sg[i].iov_len;
376
        sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
377
        if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
378
            error_report("virtio: trying to map MMIO memory");
379
            exit(1);
380
        }
381
    }
382
}
383

    
384
int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
385
{
386
    unsigned int i, head, max;
387
    target_phys_addr_t desc_pa = vq->vring.desc;
388

    
389
    if (!virtqueue_num_heads(vq, vq->last_avail_idx))
390
        return 0;
391

    
392
    /* When we start there are none of either input nor output. */
393
    elem->out_num = elem->in_num = 0;
394

    
395
    max = vq->vring.num;
396

    
397
    i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
398

    
399
    if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
400
        if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
401
            error_report("Invalid size for indirect buffer table");
402
            exit(1);
403
        }
404

    
405
        /* loop over the indirect descriptor table */
406
        max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
407
        desc_pa = vring_desc_addr(desc_pa, i);
408
        i = 0;
409
    }
410

    
411
    /* Collect all the descriptors */
412
    do {
413
        struct iovec *sg;
414

    
415
        if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
416
            elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
417
            sg = &elem->in_sg[elem->in_num++];
418
        } else {
419
            elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
420
            sg = &elem->out_sg[elem->out_num++];
421
        }
422

    
423
        sg->iov_len = vring_desc_len(desc_pa, i);
424

    
425
        /* If we've got too many, that implies a descriptor loop. */
426
        if ((elem->in_num + elem->out_num) > max) {
427
            error_report("Looped descriptor");
428
            exit(1);
429
        }
430
    } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
431

    
432
    /* Now map what we have collected */
433
    virtqueue_map_sg(elem->in_sg, elem->in_addr, elem->in_num, 1);
434
    virtqueue_map_sg(elem->out_sg, elem->out_addr, elem->out_num, 0);
435

    
436
    elem->index = head;
437

    
438
    vq->inuse++;
439

    
440
    trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num);
441
    return elem->in_num + elem->out_num;
442
}
443

    
444
/* virtio device */
445
static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
446
{
447
    if (vdev->binding->notify) {
448
        vdev->binding->notify(vdev->binding_opaque, vector);
449
    }
450
}
451

    
452
void virtio_update_irq(VirtIODevice *vdev)
453
{
454
    virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
455
}
456

    
457
void virtio_reset(void *opaque)
458
{
459
    VirtIODevice *vdev = opaque;
460
    int i;
461

    
462
    virtio_set_status(vdev, 0);
463

    
464
    if (vdev->reset)
465
        vdev->reset(vdev);
466

    
467
    vdev->guest_features = 0;
468
    vdev->queue_sel = 0;
469
    vdev->status = 0;
470
    vdev->isr = 0;
471
    vdev->config_vector = VIRTIO_NO_VECTOR;
472
    virtio_notify_vector(vdev, vdev->config_vector);
473

    
474
    for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
475
        vdev->vq[i].vring.desc = 0;
476
        vdev->vq[i].vring.avail = 0;
477
        vdev->vq[i].vring.used = 0;
478
        vdev->vq[i].last_avail_idx = 0;
479
        vdev->vq[i].pa = 0;
480
        vdev->vq[i].vector = VIRTIO_NO_VECTOR;
481
    }
482
}
483

    
484
uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
485
{
486
    uint8_t val;
487

    
488
    vdev->get_config(vdev, vdev->config);
489

    
490
    if (addr > (vdev->config_len - sizeof(val)))
491
        return (uint32_t)-1;
492

    
493
    memcpy(&val, vdev->config + addr, sizeof(val));
494
    return val;
495
}
496

    
497
uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
498
{
499
    uint16_t val;
500

    
501
    vdev->get_config(vdev, vdev->config);
502

    
503
    if (addr > (vdev->config_len - sizeof(val)))
504
        return (uint32_t)-1;
505

    
506
    memcpy(&val, vdev->config + addr, sizeof(val));
507
    return val;
508
}
509

    
510
uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
511
{
512
    uint32_t val;
513

    
514
    vdev->get_config(vdev, vdev->config);
515

    
516
    if (addr > (vdev->config_len - sizeof(val)))
517
        return (uint32_t)-1;
518

    
519
    memcpy(&val, vdev->config + addr, sizeof(val));
520
    return val;
521
}
522

    
523
void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
524
{
525
    uint8_t val = data;
526

    
527
    if (addr > (vdev->config_len - sizeof(val)))
528
        return;
529

    
530
    memcpy(vdev->config + addr, &val, sizeof(val));
531

    
532
    if (vdev->set_config)
533
        vdev->set_config(vdev, vdev->config);
534
}
535

    
536
void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
537
{
538
    uint16_t val = data;
539

    
540
    if (addr > (vdev->config_len - sizeof(val)))
541
        return;
542

    
543
    memcpy(vdev->config + addr, &val, sizeof(val));
544

    
545
    if (vdev->set_config)
546
        vdev->set_config(vdev, vdev->config);
547
}
548

    
549
void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
550
{
551
    uint32_t val = data;
552

    
553
    if (addr > (vdev->config_len - sizeof(val)))
554
        return;
555

    
556
    memcpy(vdev->config + addr, &val, sizeof(val));
557

    
558
    if (vdev->set_config)
559
        vdev->set_config(vdev, vdev->config);
560
}
561

    
562
void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
563
{
564
    vdev->vq[n].pa = addr;
565
    virtqueue_init(&vdev->vq[n]);
566
}
567

    
568
target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
569
{
570
    return vdev->vq[n].pa;
571
}
572

    
573
int virtio_queue_get_num(VirtIODevice *vdev, int n)
574
{
575
    return vdev->vq[n].vring.num;
576
}
577

    
578
void virtio_queue_notify(VirtIODevice *vdev, int n)
579
{
580
    if (n < VIRTIO_PCI_QUEUE_MAX && vdev->vq[n].vring.desc) {
581
        trace_virtio_queue_notify(vdev, n, &vdev->vq[n]);
582
        vdev->vq[n].handle_output(vdev, &vdev->vq[n]);
583
    }
584
}
585

    
586
uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
587
{
588
    return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector :
589
        VIRTIO_NO_VECTOR;
590
}
591

    
592
void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
593
{
594
    if (n < VIRTIO_PCI_QUEUE_MAX)
595
        vdev->vq[n].vector = vector;
596
}
597

    
598
VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
599
                            void (*handle_output)(VirtIODevice *, VirtQueue *))
600
{
601
    int i;
602

    
603
    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
604
        if (vdev->vq[i].vring.num == 0)
605
            break;
606
    }
607

    
608
    if (i == VIRTIO_PCI_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE)
609
        abort();
610

    
611
    vdev->vq[i].vring.num = queue_size;
612
    vdev->vq[i].handle_output = handle_output;
613

    
614
    return &vdev->vq[i];
615
}
616

    
617
void virtio_irq(VirtQueue *vq)
618
{
619
    trace_virtio_irq(vq);
620
    vq->vdev->isr |= 0x01;
621
    virtio_notify_vector(vq->vdev, vq->vector);
622
}
623

    
624
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
625
{
626
    /* Always notify when queue is empty (when feature acknowledge) */
627
    if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
628
        (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
629
         (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
630
        return;
631

    
632
    trace_virtio_notify(vdev, vq);
633
    vdev->isr |= 0x01;
634
    virtio_notify_vector(vdev, vq->vector);
635
}
636

    
637
void virtio_notify_config(VirtIODevice *vdev)
638
{
639
    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))
640
        return;
641

    
642
    vdev->isr |= 0x03;
643
    virtio_notify_vector(vdev, vdev->config_vector);
644
}
645

    
646
void virtio_save(VirtIODevice *vdev, QEMUFile *f)
647
{
648
    int i;
649

    
650
    if (vdev->binding->save_config)
651
        vdev->binding->save_config(vdev->binding_opaque, f);
652

    
653
    qemu_put_8s(f, &vdev->status);
654
    qemu_put_8s(f, &vdev->isr);
655
    qemu_put_be16s(f, &vdev->queue_sel);
656
    qemu_put_be32s(f, &vdev->guest_features);
657
    qemu_put_be32(f, vdev->config_len);
658
    qemu_put_buffer(f, vdev->config, vdev->config_len);
659

    
660
    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
661
        if (vdev->vq[i].vring.num == 0)
662
            break;
663
    }
664

    
665
    qemu_put_be32(f, i);
666

    
667
    for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
668
        if (vdev->vq[i].vring.num == 0)
669
            break;
670

    
671
        qemu_put_be32(f, vdev->vq[i].vring.num);
672
        qemu_put_be64(f, vdev->vq[i].pa);
673
        qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
674
        if (vdev->binding->save_queue)
675
            vdev->binding->save_queue(vdev->binding_opaque, i, f);
676
    }
677
}
678

    
679
int virtio_load(VirtIODevice *vdev, QEMUFile *f)
680
{
681
    int num, i, ret;
682
    uint32_t features;
683
    uint32_t supported_features =
684
        vdev->binding->get_features(vdev->binding_opaque);
685
    uint16_t num_heads;
686

    
687
    if (vdev->binding->load_config) {
688
        ret = vdev->binding->load_config(vdev->binding_opaque, f);
689
        if (ret)
690
            return ret;
691
    }
692

    
693
    qemu_get_8s(f, &vdev->status);
694
    qemu_get_8s(f, &vdev->isr);
695
    qemu_get_be16s(f, &vdev->queue_sel);
696
    qemu_get_be32s(f, &features);
697
    if (features & ~supported_features) {
698
        error_report("Features 0x%x unsupported. Allowed features: 0x%x",
699
                     features, supported_features);
700
        return -1;
701
    }
702
    if (vdev->set_features)
703
        vdev->set_features(vdev, features);
704
    vdev->guest_features = features;
705
    vdev->config_len = qemu_get_be32(f);
706
    qemu_get_buffer(f, vdev->config, vdev->config_len);
707

    
708
    num = qemu_get_be32(f);
709

    
710
    for (i = 0; i < num; i++) {
711
        vdev->vq[i].vring.num = qemu_get_be32(f);
712
        vdev->vq[i].pa = qemu_get_be64(f);
713
        qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
714

    
715
        if (vdev->vq[i].pa) {
716
            virtqueue_init(&vdev->vq[i]);
717
        }
718
        num_heads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
719
        /* Check it isn't doing very strange things with descriptor numbers. */
720
        if (num_heads > vdev->vq[i].vring.num) {
721
                error_report("VQ %d size 0x%x Guest index 0x%x "
722
                             "inconsistent with Host index 0x%x: delta 0x%x",
723
                             i, vdev->vq[i].vring.num,
724
                             vring_avail_idx(&vdev->vq[i]),
725
                             vdev->vq[i].last_avail_idx, num_heads);
726
                return -1;
727
        }
728
        if (vdev->binding->load_queue) {
729
            ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
730
            if (ret)
731
                return ret;
732
        }
733
    }
734

    
735
    virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
736
    return 0;
737
}
738

    
739
void virtio_cleanup(VirtIODevice *vdev)
740
{
741
    if (vdev->config)
742
        qemu_free(vdev->config);
743
    qemu_free(vdev->vq);
744
}
745

    
746
VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
747
                                 size_t config_size, size_t struct_size)
748
{
749
    VirtIODevice *vdev;
750
    int i;
751

    
752
    vdev = qemu_mallocz(struct_size);
753

    
754
    vdev->device_id = device_id;
755
    vdev->status = 0;
756
    vdev->isr = 0;
757
    vdev->queue_sel = 0;
758
    vdev->config_vector = VIRTIO_NO_VECTOR;
759
    vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
760
    for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
761
        vdev->vq[i].vector = VIRTIO_NO_VECTOR;
762
        vdev->vq[i].vdev = vdev;
763
    }
764

    
765
    vdev->name = name;
766
    vdev->config_len = config_size;
767
    if (vdev->config_len)
768
        vdev->config = qemu_mallocz(config_size);
769
    else
770
        vdev->config = NULL;
771

    
772
    return vdev;
773
}
774

    
775
void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
776
                        void *opaque)
777
{
778
    vdev->binding = binding;
779
    vdev->binding_opaque = opaque;
780
}
781

    
782
target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
783
{
784
    return vdev->vq[n].vring.desc;
785
}
786

    
787
target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n)
788
{
789
    return vdev->vq[n].vring.avail;
790
}
791

    
792
target_phys_addr_t virtio_queue_get_used_addr(VirtIODevice *vdev, int n)
793
{
794
    return vdev->vq[n].vring.used;
795
}
796

    
797
target_phys_addr_t virtio_queue_get_ring_addr(VirtIODevice *vdev, int n)
798
{
799
    return vdev->vq[n].vring.desc;
800
}
801

    
802
target_phys_addr_t virtio_queue_get_desc_size(VirtIODevice *vdev, int n)
803
{
804
    return sizeof(VRingDesc) * vdev->vq[n].vring.num;
805
}
806

    
807
target_phys_addr_t virtio_queue_get_avail_size(VirtIODevice *vdev, int n)
808
{
809
    return offsetof(VRingAvail, ring) +
810
        sizeof(uint64_t) * vdev->vq[n].vring.num;
811
}
812

    
813
target_phys_addr_t virtio_queue_get_used_size(VirtIODevice *vdev, int n)
814
{
815
    return offsetof(VRingUsed, ring) +
816
        sizeof(VRingUsedElem) * vdev->vq[n].vring.num;
817
}
818

    
819
target_phys_addr_t virtio_queue_get_ring_size(VirtIODevice *vdev, int n)
820
{
821
    return vdev->vq[n].vring.used - vdev->vq[n].vring.desc +
822
            virtio_queue_get_used_size(vdev, n);
823
}
824

    
825
uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
826
{
827
    return vdev->vq[n].last_avail_idx;
828
}
829

    
830
void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
831
{
832
    vdev->vq[n].last_avail_idx = idx;
833
}
834

    
835
VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
836
{
837
    return vdev->vq + n;
838
}
839

    
840
EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
841
{
842
    return &vq->guest_notifier;
843
}
844
EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
845
{
846
    return &vq->host_notifier;
847
}