|
|
1.1 root 1: /*
2: * Virtio Support
3: *
4: * Copyright IBM, Corp. 2007
5: *
6: * Authors:
7: * Anthony Liguori <[email protected]>
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:
1.1.1.8 root 16: #include "trace.h"
17: #include "qemu-error.h"
1.1 root 18: #include "virtio.h"
19:
20: /* The alignment to use between consumer and producer parts of vring.
21: * x86 pagesize again. */
22: #define VIRTIO_PCI_VRING_ALIGN 4096
23:
24: /* QEMU doesn't strictly need write barriers since everything runs in
25: * lock-step. We'll leave the calls to wmb() in though to make it obvious for
26: * KVM or if kqemu gets SMP support.
1.1.1.6 root 27: * In any case, we must prevent the compiler from reordering the code.
28: * TODO: we likely need some rmb()/mb() as well.
1.1 root 29: */
1.1.1.6 root 30:
31: #define wmb() __asm__ __volatile__("": : :"memory")
1.1 root 32:
33: typedef struct VRingDesc
34: {
35: uint64_t addr;
36: uint32_t len;
37: uint16_t flags;
38: uint16_t next;
39: } VRingDesc;
40:
41: typedef struct VRingAvail
42: {
43: uint16_t flags;
44: uint16_t idx;
45: uint16_t ring[0];
46: } VRingAvail;
47:
48: typedef struct VRingUsedElem
49: {
50: uint32_t id;
51: uint32_t len;
52: } VRingUsedElem;
53:
54: typedef struct VRingUsed
55: {
56: uint16_t flags;
57: uint16_t idx;
58: VRingUsedElem ring[0];
59: } VRingUsed;
60:
61: typedef struct VRing
62: {
63: unsigned int num;
64: target_phys_addr_t desc;
65: target_phys_addr_t avail;
66: target_phys_addr_t used;
67: } VRing;
68:
69: struct VirtQueue
70: {
71: VRing vring;
1.1.1.5 root 72: target_phys_addr_t pa;
1.1 root 73: uint16_t last_avail_idx;
1.1.1.9 ! root 74: /* Last used index value we have signalled on */
! 75: uint16_t signalled_used;
! 76:
! 77: /* Last used index value we have signalled on */
! 78: bool signalled_used_valid;
! 79:
! 80: /* Notification enabled? */
! 81: bool notification;
! 82:
1.1 root 83: int inuse;
1.1.1.9 ! root 84:
1.1.1.5 root 85: uint16_t vector;
1.1 root 86: void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
1.1.1.7 root 87: VirtIODevice *vdev;
88: EventNotifier guest_notifier;
89: EventNotifier host_notifier;
1.1 root 90: };
91:
92: /* virt queue functions */
1.1.1.5 root 93: static void virtqueue_init(VirtQueue *vq)
1.1 root 94: {
1.1.1.5 root 95: target_phys_addr_t pa = vq->pa;
1.1 root 96:
97: vq->vring.desc = pa;
98: vq->vring.avail = pa + vq->vring.num * sizeof(VRingDesc);
99: vq->vring.used = vring_align(vq->vring.avail +
100: offsetof(VRingAvail, ring[vq->vring.num]),
101: VIRTIO_PCI_VRING_ALIGN);
102: }
103:
1.1.1.5 root 104: static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i)
1.1 root 105: {
106: target_phys_addr_t pa;
1.1.1.5 root 107: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr);
1.1 root 108: return ldq_phys(pa);
109: }
110:
1.1.1.5 root 111: static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i)
1.1 root 112: {
113: target_phys_addr_t pa;
1.1.1.5 root 114: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len);
1.1 root 115: return ldl_phys(pa);
116: }
117:
1.1.1.5 root 118: static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i)
1.1 root 119: {
120: target_phys_addr_t pa;
1.1.1.5 root 121: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags);
1.1 root 122: return lduw_phys(pa);
123: }
124:
1.1.1.5 root 125: static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i)
1.1 root 126: {
127: target_phys_addr_t pa;
1.1.1.5 root 128: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next);
1.1 root 129: return lduw_phys(pa);
130: }
131:
132: static inline uint16_t vring_avail_flags(VirtQueue *vq)
133: {
134: target_phys_addr_t pa;
135: pa = vq->vring.avail + offsetof(VRingAvail, flags);
136: return lduw_phys(pa);
137: }
138:
139: static inline uint16_t vring_avail_idx(VirtQueue *vq)
140: {
141: target_phys_addr_t pa;
142: pa = vq->vring.avail + offsetof(VRingAvail, idx);
143: return lduw_phys(pa);
144: }
145:
146: static inline uint16_t vring_avail_ring(VirtQueue *vq, int i)
147: {
148: target_phys_addr_t pa;
149: pa = vq->vring.avail + offsetof(VRingAvail, ring[i]);
150: return lduw_phys(pa);
151: }
152:
1.1.1.9 ! root 153: static inline uint16_t vring_used_event(VirtQueue *vq)
! 154: {
! 155: return vring_avail_ring(vq, vq->vring.num);
! 156: }
! 157:
1.1 root 158: static inline void vring_used_ring_id(VirtQueue *vq, int i, uint32_t val)
159: {
160: target_phys_addr_t pa;
161: pa = vq->vring.used + offsetof(VRingUsed, ring[i].id);
162: stl_phys(pa, val);
163: }
164:
165: static inline void vring_used_ring_len(VirtQueue *vq, int i, uint32_t val)
166: {
167: target_phys_addr_t pa;
168: pa = vq->vring.used + offsetof(VRingUsed, ring[i].len);
169: stl_phys(pa, val);
170: }
171:
172: static uint16_t vring_used_idx(VirtQueue *vq)
173: {
174: target_phys_addr_t pa;
175: pa = vq->vring.used + offsetof(VRingUsed, idx);
176: return lduw_phys(pa);
177: }
178:
1.1.1.9 ! root 179: static inline void vring_used_idx_set(VirtQueue *vq, uint16_t val)
1.1 root 180: {
181: target_phys_addr_t pa;
182: pa = vq->vring.used + offsetof(VRingUsed, idx);
1.1.1.9 ! root 183: stw_phys(pa, val);
1.1 root 184: }
185:
186: static inline void vring_used_flags_set_bit(VirtQueue *vq, int mask)
187: {
188: target_phys_addr_t pa;
189: pa = vq->vring.used + offsetof(VRingUsed, flags);
190: stw_phys(pa, lduw_phys(pa) | mask);
191: }
192:
193: static inline void vring_used_flags_unset_bit(VirtQueue *vq, int mask)
194: {
195: target_phys_addr_t pa;
196: pa = vq->vring.used + offsetof(VRingUsed, flags);
197: stw_phys(pa, lduw_phys(pa) & ~mask);
198: }
199:
1.1.1.9 ! root 200: static inline void vring_avail_event(VirtQueue *vq, uint16_t val)
! 201: {
! 202: target_phys_addr_t pa;
! 203: if (!vq->notification) {
! 204: return;
! 205: }
! 206: pa = vq->vring.used + offsetof(VRingUsed, ring[vq->vring.num]);
! 207: stw_phys(pa, val);
! 208: }
! 209:
1.1 root 210: void virtio_queue_set_notification(VirtQueue *vq, int enable)
211: {
1.1.1.9 ! root 212: vq->notification = enable;
! 213: if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
! 214: vring_avail_event(vq, vring_avail_idx(vq));
! 215: } else if (enable) {
1.1 root 216: vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY);
1.1.1.9 ! root 217: } else {
1.1 root 218: vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY);
1.1.1.9 ! root 219: }
1.1 root 220: }
221:
222: int virtio_queue_ready(VirtQueue *vq)
223: {
224: return vq->vring.avail != 0;
225: }
226:
227: int virtio_queue_empty(VirtQueue *vq)
228: {
229: return vring_avail_idx(vq) == vq->last_avail_idx;
230: }
231:
232: void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
233: unsigned int len, unsigned int idx)
234: {
235: unsigned int offset;
236: int i;
237:
1.1.1.8 root 238: trace_virtqueue_fill(vq, elem, len, idx);
239:
1.1 root 240: offset = 0;
241: for (i = 0; i < elem->in_num; i++) {
242: size_t size = MIN(len - offset, elem->in_sg[i].iov_len);
243:
1.1.1.5 root 244: cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
245: elem->in_sg[i].iov_len,
246: 1, size);
1.1 root 247:
1.1.1.5 root 248: offset += elem->in_sg[i].iov_len;
1.1 root 249: }
250:
1.1.1.5 root 251: for (i = 0; i < elem->out_num; i++)
252: cpu_physical_memory_unmap(elem->out_sg[i].iov_base,
253: elem->out_sg[i].iov_len,
254: 0, elem->out_sg[i].iov_len);
255:
1.1 root 256: idx = (idx + vring_used_idx(vq)) % vq->vring.num;
257:
258: /* Get a pointer to the next entry in the used ring. */
259: vring_used_ring_id(vq, idx, elem->index);
260: vring_used_ring_len(vq, idx, len);
261: }
262:
263: void virtqueue_flush(VirtQueue *vq, unsigned int count)
264: {
1.1.1.9 ! root 265: uint16_t old, new;
1.1 root 266: /* Make sure buffer is written before we update index. */
267: wmb();
1.1.1.8 root 268: trace_virtqueue_flush(vq, count);
1.1.1.9 ! root 269: old = vring_used_idx(vq);
! 270: new = old + count;
! 271: vring_used_idx_set(vq, new);
1.1 root 272: vq->inuse -= count;
1.1.1.9 ! root 273: if (unlikely((int16_t)(new - vq->signalled_used) < (uint16_t)(new - old)))
! 274: vq->signalled_used_valid = false;
1.1 root 275: }
276:
277: void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem,
278: unsigned int len)
279: {
280: virtqueue_fill(vq, elem, len, 0);
281: virtqueue_flush(vq, 1);
282: }
283:
284: static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx)
285: {
286: uint16_t num_heads = vring_avail_idx(vq) - idx;
287:
288: /* Check it isn't doing very strange things with descriptor numbers. */
289: if (num_heads > vq->vring.num) {
1.1.1.8 root 290: error_report("Guest moved used index from %u to %u",
291: idx, vring_avail_idx(vq));
1.1 root 292: exit(1);
293: }
294:
295: return num_heads;
296: }
297:
298: static unsigned int virtqueue_get_head(VirtQueue *vq, unsigned int idx)
299: {
300: unsigned int head;
301:
302: /* Grab the next descriptor number they're advertising, and increment
303: * the index we've seen. */
304: head = vring_avail_ring(vq, idx % vq->vring.num);
305:
306: /* If their number is silly, that's a fatal mistake. */
307: if (head >= vq->vring.num) {
1.1.1.8 root 308: error_report("Guest says index %u is available", head);
1.1 root 309: exit(1);
310: }
311:
312: return head;
313: }
314:
1.1.1.5 root 315: static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa,
316: unsigned int i, unsigned int max)
1.1 root 317: {
318: unsigned int next;
319:
320: /* If this descriptor says it doesn't chain, we're done. */
1.1.1.5 root 321: if (!(vring_desc_flags(desc_pa, i) & VRING_DESC_F_NEXT))
322: return max;
1.1 root 323:
324: /* Check they're not leading us off end of descriptors. */
1.1.1.5 root 325: next = vring_desc_next(desc_pa, i);
1.1 root 326: /* Make sure compiler knows to grab that: we don't want it changing! */
327: wmb();
328:
1.1.1.5 root 329: if (next >= max) {
1.1.1.8 root 330: error_report("Desc next is %u", next);
1.1 root 331: exit(1);
332: }
333:
334: return next;
335: }
336:
337: int virtqueue_avail_bytes(VirtQueue *vq, int in_bytes, int out_bytes)
338: {
339: unsigned int idx;
1.1.1.5 root 340: int total_bufs, in_total, out_total;
1.1 root 341:
342: idx = vq->last_avail_idx;
343:
1.1.1.5 root 344: total_bufs = in_total = out_total = 0;
1.1 root 345: while (virtqueue_num_heads(vq, idx)) {
1.1.1.5 root 346: unsigned int max, num_bufs, indirect = 0;
347: target_phys_addr_t desc_pa;
1.1 root 348: int i;
349:
1.1.1.5 root 350: max = vq->vring.num;
351: num_bufs = total_bufs;
1.1 root 352: i = virtqueue_get_head(vq, idx++);
1.1.1.5 root 353: desc_pa = vq->vring.desc;
354:
355: if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
356: if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
1.1.1.8 root 357: error_report("Invalid size for indirect buffer table");
1.1.1.5 root 358: exit(1);
359: }
360:
361: /* If we've got too many, that implies a descriptor loop. */
362: if (num_bufs >= max) {
1.1.1.8 root 363: error_report("Looped descriptor");
1.1.1.5 root 364: exit(1);
365: }
366:
367: /* loop over the indirect descriptor table */
368: indirect = 1;
369: max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
370: num_bufs = i = 0;
371: desc_pa = vring_desc_addr(desc_pa, i);
372: }
373:
1.1 root 374: do {
375: /* If we've got too many, that implies a descriptor loop. */
1.1.1.5 root 376: if (++num_bufs > max) {
1.1.1.8 root 377: error_report("Looped descriptor");
1.1 root 378: exit(1);
379: }
380:
1.1.1.5 root 381: if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
1.1 root 382: if (in_bytes > 0 &&
1.1.1.5 root 383: (in_total += vring_desc_len(desc_pa, i)) >= in_bytes)
1.1 root 384: return 1;
385: } else {
386: if (out_bytes > 0 &&
1.1.1.5 root 387: (out_total += vring_desc_len(desc_pa, i)) >= out_bytes)
1.1 root 388: return 1;
389: }
1.1.1.5 root 390: } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
391:
392: if (!indirect)
393: total_bufs = num_bufs;
394: else
395: total_bufs++;
1.1 root 396: }
397:
398: return 0;
399: }
400:
1.1.1.7 root 401: void virtqueue_map_sg(struct iovec *sg, target_phys_addr_t *addr,
402: size_t num_sg, int is_write)
403: {
404: unsigned int i;
405: target_phys_addr_t len;
406:
407: for (i = 0; i < num_sg; i++) {
408: len = sg[i].iov_len;
409: sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
410: if (sg[i].iov_base == NULL || len != sg[i].iov_len) {
1.1.1.8 root 411: error_report("virtio: trying to map MMIO memory");
1.1.1.7 root 412: exit(1);
413: }
414: }
415: }
416:
1.1 root 417: int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
418: {
1.1.1.5 root 419: unsigned int i, head, max;
420: target_phys_addr_t desc_pa = vq->vring.desc;
1.1 root 421:
422: if (!virtqueue_num_heads(vq, vq->last_avail_idx))
423: return 0;
424:
425: /* When we start there are none of either input nor output. */
426: elem->out_num = elem->in_num = 0;
427:
1.1.1.5 root 428: max = vq->vring.num;
429:
1.1 root 430: i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
1.1.1.9 ! root 431: if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) {
! 432: vring_avail_event(vq, vring_avail_idx(vq));
! 433: }
1.1.1.5 root 434:
435: if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
436: if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
1.1.1.8 root 437: error_report("Invalid size for indirect buffer table");
1.1.1.5 root 438: exit(1);
439: }
440:
441: /* loop over the indirect descriptor table */
442: max = vring_desc_len(desc_pa, i) / sizeof(VRingDesc);
443: desc_pa = vring_desc_addr(desc_pa, i);
444: i = 0;
445: }
446:
1.1.1.7 root 447: /* Collect all the descriptors */
1.1 root 448: do {
449: struct iovec *sg;
450:
1.1.1.5 root 451: if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
1.1.1.9 ! root 452: if (elem->in_num >= ARRAY_SIZE(elem->in_sg)) {
! 453: error_report("Too many write descriptors in indirect table");
! 454: exit(1);
! 455: }
1.1.1.5 root 456: elem->in_addr[elem->in_num] = vring_desc_addr(desc_pa, i);
1.1 root 457: sg = &elem->in_sg[elem->in_num++];
1.1.1.7 root 458: } else {
1.1.1.9 ! root 459: if (elem->out_num >= ARRAY_SIZE(elem->out_sg)) {
! 460: error_report("Too many read descriptors in indirect table");
! 461: exit(1);
! 462: }
1.1.1.7 root 463: elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
1.1 root 464: sg = &elem->out_sg[elem->out_num++];
1.1.1.7 root 465: }
1.1 root 466:
1.1.1.5 root 467: sg->iov_len = vring_desc_len(desc_pa, i);
1.1 root 468:
469: /* If we've got too many, that implies a descriptor loop. */
1.1.1.5 root 470: if ((elem->in_num + elem->out_num) > max) {
1.1.1.8 root 471: error_report("Looped descriptor");
1.1 root 472: exit(1);
473: }
1.1.1.5 root 474: } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
1.1 root 475:
1.1.1.7 root 476: /* Now map what we have collected */
477: virtqueue_map_sg(elem->in_sg, elem->in_addr, elem->in_num, 1);
478: virtqueue_map_sg(elem->out_sg, elem->out_addr, elem->out_num, 0);
479:
1.1 root 480: elem->index = head;
481:
482: vq->inuse++;
483:
1.1.1.8 root 484: trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num);
1.1 root 485: return elem->in_num + elem->out_num;
486: }
487:
488: /* virtio device */
1.1.1.5 root 489: static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
1.1 root 490: {
1.1.1.5 root 491: if (vdev->binding->notify) {
492: vdev->binding->notify(vdev->binding_opaque, vector);
493: }
1.1 root 494: }
495:
1.1.1.5 root 496: void virtio_update_irq(VirtIODevice *vdev)
1.1 root 497: {
1.1.1.5 root 498: virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
1.1 root 499: }
500:
1.1.1.5 root 501: void virtio_reset(void *opaque)
1.1 root 502: {
503: VirtIODevice *vdev = opaque;
504: int i;
505:
1.1.1.7 root 506: virtio_set_status(vdev, 0);
507:
1.1 root 508: if (vdev->reset)
509: vdev->reset(vdev);
510:
1.1.1.7 root 511: vdev->guest_features = 0;
1.1 root 512: vdev->queue_sel = 0;
513: vdev->status = 0;
514: vdev->isr = 0;
1.1.1.5 root 515: vdev->config_vector = VIRTIO_NO_VECTOR;
516: virtio_notify_vector(vdev, vdev->config_vector);
1.1 root 517:
518: for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
519: vdev->vq[i].vring.desc = 0;
520: vdev->vq[i].vring.avail = 0;
521: vdev->vq[i].vring.used = 0;
522: vdev->vq[i].last_avail_idx = 0;
1.1.1.5 root 523: vdev->vq[i].pa = 0;
524: vdev->vq[i].vector = VIRTIO_NO_VECTOR;
1.1.1.9 ! root 525: vdev->vq[i].signalled_used = 0;
! 526: vdev->vq[i].signalled_used_valid = false;
! 527: vdev->vq[i].notification = true;
1.1 root 528: }
529: }
530:
1.1.1.5 root 531: uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
1.1 root 532: {
533: uint8_t val;
534:
535: vdev->get_config(vdev, vdev->config);
536:
537: if (addr > (vdev->config_len - sizeof(val)))
538: return (uint32_t)-1;
539:
540: memcpy(&val, vdev->config + addr, sizeof(val));
541: return val;
542: }
543:
1.1.1.5 root 544: uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
1.1 root 545: {
546: uint16_t val;
547:
548: vdev->get_config(vdev, vdev->config);
549:
550: if (addr > (vdev->config_len - sizeof(val)))
551: return (uint32_t)-1;
552:
553: memcpy(&val, vdev->config + addr, sizeof(val));
554: return val;
555: }
556:
1.1.1.5 root 557: uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
1.1 root 558: {
559: uint32_t val;
560:
561: vdev->get_config(vdev, vdev->config);
562:
563: if (addr > (vdev->config_len - sizeof(val)))
564: return (uint32_t)-1;
565:
566: memcpy(&val, vdev->config + addr, sizeof(val));
567: return val;
568: }
569:
1.1.1.5 root 570: void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
1.1 root 571: {
572: uint8_t val = data;
573:
574: if (addr > (vdev->config_len - sizeof(val)))
575: return;
576:
577: memcpy(vdev->config + addr, &val, sizeof(val));
578:
579: if (vdev->set_config)
580: vdev->set_config(vdev, vdev->config);
581: }
582:
1.1.1.5 root 583: void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
1.1 root 584: {
585: uint16_t val = data;
586:
587: if (addr > (vdev->config_len - sizeof(val)))
588: return;
589:
590: memcpy(vdev->config + addr, &val, sizeof(val));
591:
592: if (vdev->set_config)
593: vdev->set_config(vdev, vdev->config);
594: }
595:
1.1.1.5 root 596: void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
1.1 root 597: {
598: uint32_t val = data;
599:
600: if (addr > (vdev->config_len - sizeof(val)))
601: return;
602:
603: memcpy(vdev->config + addr, &val, sizeof(val));
604:
605: if (vdev->set_config)
606: vdev->set_config(vdev, vdev->config);
607: }
608:
1.1.1.5 root 609: void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
1.1 root 610: {
1.1.1.5 root 611: vdev->vq[n].pa = addr;
612: virtqueue_init(&vdev->vq[n]);
613: }
614:
615: target_phys_addr_t virtio_queue_get_addr(VirtIODevice *vdev, int n)
616: {
617: return vdev->vq[n].pa;
618: }
1.1 root 619:
1.1.1.5 root 620: int virtio_queue_get_num(VirtIODevice *vdev, int n)
621: {
622: return vdev->vq[n].vring.num;
623: }
1.1 root 624:
1.1.1.8 root 625: void virtio_queue_notify_vq(VirtQueue *vq)
626: {
627: if (vq->vring.desc) {
628: VirtIODevice *vdev = vq->vdev;
629: trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
630: vq->handle_output(vdev, vq);
631: }
632: }
633:
1.1.1.5 root 634: void virtio_queue_notify(VirtIODevice *vdev, int n)
635: {
1.1.1.9 ! root 636: virtio_queue_notify_vq(&vdev->vq[n]);
1.1 root 637: }
638:
1.1.1.5 root 639: uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
640: {
641: return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector :
642: VIRTIO_NO_VECTOR;
643: }
644:
645: void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
646: {
647: if (n < VIRTIO_PCI_QUEUE_MAX)
648: vdev->vq[n].vector = vector;
649: }
650:
1.1 root 651: VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
652: void (*handle_output)(VirtIODevice *, VirtQueue *))
653: {
654: int i;
655:
656: for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
657: if (vdev->vq[i].vring.num == 0)
658: break;
659: }
660:
661: if (i == VIRTIO_PCI_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE)
662: abort();
663:
664: vdev->vq[i].vring.num = queue_size;
665: vdev->vq[i].handle_output = handle_output;
666:
667: return &vdev->vq[i];
668: }
669:
1.1.1.7 root 670: void virtio_irq(VirtQueue *vq)
671: {
1.1.1.8 root 672: trace_virtio_irq(vq);
1.1.1.7 root 673: vq->vdev->isr |= 0x01;
674: virtio_notify_vector(vq->vdev, vq->vector);
675: }
676:
1.1.1.9 ! root 677: /* Assuming a given event_idx value from the other size, if
! 678: * we have just incremented index from old to new_idx,
! 679: * should we trigger an event? */
! 680: static inline int vring_need_event(uint16_t event, uint16_t new, uint16_t old)
! 681: {
! 682: /* Note: Xen has similar logic for notification hold-off
! 683: * in include/xen/interface/io/ring.h with req_event and req_prod
! 684: * corresponding to event_idx + 1 and new respectively.
! 685: * Note also that req_event and req_prod in Xen start at 1,
! 686: * event indexes in virtio start at 0. */
! 687: return (uint16_t)(new - event - 1) < (uint16_t)(new - old);
! 688: }
! 689:
! 690: static bool vring_notify(VirtIODevice *vdev, VirtQueue *vq)
1.1 root 691: {
1.1.1.9 ! root 692: uint16_t old, new;
! 693: bool v;
1.1.1.2 root 694: /* Always notify when queue is empty (when feature acknowledge) */
1.1.1.9 ! root 695: if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) &&
! 696: !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) {
! 697: return true;
! 698: }
! 699:
! 700: if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) {
! 701: return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT);
! 702: }
! 703:
! 704: v = vq->signalled_used_valid;
! 705: vq->signalled_used_valid = true;
! 706: old = vq->signalled_used;
! 707: new = vq->signalled_used = vring_used_idx(vq);
! 708: return !v || vring_need_event(vring_used_event(vq), new, old);
! 709: }
! 710:
! 711: void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
! 712: {
! 713: if (!vring_notify(vdev, vq)) {
1.1 root 714: return;
1.1.1.9 ! root 715: }
1.1 root 716:
1.1.1.8 root 717: trace_virtio_notify(vdev, vq);
1.1 root 718: vdev->isr |= 0x01;
1.1.1.5 root 719: virtio_notify_vector(vdev, vq->vector);
1.1 root 720: }
721:
722: void virtio_notify_config(VirtIODevice *vdev)
723: {
724: if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))
725: return;
726:
727: vdev->isr |= 0x03;
1.1.1.5 root 728: virtio_notify_vector(vdev, vdev->config_vector);
1.1 root 729: }
730:
731: void virtio_save(VirtIODevice *vdev, QEMUFile *f)
732: {
733: int i;
734:
1.1.1.5 root 735: if (vdev->binding->save_config)
736: vdev->binding->save_config(vdev->binding_opaque, f);
1.1 root 737:
738: qemu_put_8s(f, &vdev->status);
739: qemu_put_8s(f, &vdev->isr);
740: qemu_put_be16s(f, &vdev->queue_sel);
1.1.1.7 root 741: qemu_put_be32s(f, &vdev->guest_features);
1.1 root 742: qemu_put_be32(f, vdev->config_len);
743: qemu_put_buffer(f, vdev->config, vdev->config_len);
744:
745: for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
746: if (vdev->vq[i].vring.num == 0)
747: break;
748: }
749:
750: qemu_put_be32(f, i);
751:
752: for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
753: if (vdev->vq[i].vring.num == 0)
754: break;
755:
756: qemu_put_be32(f, vdev->vq[i].vring.num);
1.1.1.5 root 757: qemu_put_be64(f, vdev->vq[i].pa);
1.1 root 758: qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
1.1.1.5 root 759: if (vdev->binding->save_queue)
760: vdev->binding->save_queue(vdev->binding_opaque, i, f);
1.1 root 761: }
762: }
763:
1.1.1.5 root 764: int virtio_load(VirtIODevice *vdev, QEMUFile *f)
1.1 root 765: {
1.1.1.5 root 766: int num, i, ret;
1.1.1.6 root 767: uint32_t features;
1.1.1.7 root 768: uint32_t supported_features =
1.1.1.6 root 769: vdev->binding->get_features(vdev->binding_opaque);
1.1 root 770:
1.1.1.5 root 771: if (vdev->binding->load_config) {
772: ret = vdev->binding->load_config(vdev->binding_opaque, f);
773: if (ret)
774: return ret;
775: }
1.1 root 776:
777: qemu_get_8s(f, &vdev->status);
778: qemu_get_8s(f, &vdev->isr);
779: qemu_get_be16s(f, &vdev->queue_sel);
1.1.1.6 root 780: qemu_get_be32s(f, &features);
781: if (features & ~supported_features) {
1.1.1.8 root 782: error_report("Features 0x%x unsupported. Allowed features: 0x%x",
783: features, supported_features);
1.1.1.6 root 784: return -1;
785: }
1.1.1.7 root 786: if (vdev->set_features)
787: vdev->set_features(vdev, features);
788: vdev->guest_features = features;
1.1 root 789: vdev->config_len = qemu_get_be32(f);
790: qemu_get_buffer(f, vdev->config, vdev->config_len);
791:
792: num = qemu_get_be32(f);
793:
794: for (i = 0; i < num; i++) {
795: vdev->vq[i].vring.num = qemu_get_be32(f);
1.1.1.5 root 796: vdev->vq[i].pa = qemu_get_be64(f);
1.1 root 797: qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
1.1.1.9 ! root 798: vdev->vq[i].signalled_used_valid = false;
! 799: vdev->vq[i].notification = true;
1.1 root 800:
1.1.1.5 root 801: if (vdev->vq[i].pa) {
1.1.1.8 root 802: uint16_t nheads;
1.1.1.5 root 803: virtqueue_init(&vdev->vq[i]);
1.1.1.8 root 804: nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
805: /* Check it isn't doing very strange things with descriptor numbers. */
806: if (nheads > vdev->vq[i].vring.num) {
807: error_report("VQ %d size 0x%x Guest index 0x%x "
1.1.1.9 ! root 808: "inconsistent with Host index 0x%x: delta 0x%x",
1.1.1.8 root 809: i, vdev->vq[i].vring.num,
810: vring_avail_idx(&vdev->vq[i]),
811: vdev->vq[i].last_avail_idx, nheads);
812: return -1;
813: }
814: } else if (vdev->vq[i].last_avail_idx) {
815: error_report("VQ %d address 0x0 "
1.1.1.9 ! root 816: "inconsistent with Host index 0x%x",
1.1.1.8 root 817: i, vdev->vq[i].last_avail_idx);
818: return -1;
819: }
1.1.1.5 root 820: if (vdev->binding->load_queue) {
821: ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
822: if (ret)
823: return ret;
1.1 root 824: }
825: }
826:
1.1.1.5 root 827: virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
828: return 0;
1.1 root 829: }
830:
1.1.1.4 root 831: void virtio_cleanup(VirtIODevice *vdev)
832: {
1.1.1.8 root 833: qemu_del_vm_change_state_handler(vdev->vmstate);
1.1.1.4 root 834: if (vdev->config)
835: qemu_free(vdev->config);
836: qemu_free(vdev->vq);
837: }
838:
1.1.1.8 root 839: static void virtio_vmstate_change(void *opaque, int running, int reason)
840: {
841: VirtIODevice *vdev = opaque;
842: bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
843: vdev->vm_running = running;
844:
845: if (backend_run) {
846: virtio_set_status(vdev, vdev->status);
847: }
848:
849: if (vdev->binding->vmstate_change) {
850: vdev->binding->vmstate_change(vdev->binding_opaque, backend_run);
851: }
852:
853: if (!backend_run) {
854: virtio_set_status(vdev, vdev->status);
855: }
856: }
857:
1.1.1.5 root 858: VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
859: size_t config_size, size_t struct_size)
1.1 root 860: {
861: VirtIODevice *vdev;
1.1.1.6 root 862: int i;
1.1 root 863:
1.1.1.5 root 864: vdev = qemu_mallocz(struct_size);
1.1 root 865:
1.1.1.5 root 866: vdev->device_id = device_id;
1.1 root 867: vdev->status = 0;
868: vdev->isr = 0;
869: vdev->queue_sel = 0;
1.1.1.5 root 870: vdev->config_vector = VIRTIO_NO_VECTOR;
1.1 root 871: vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
1.1.1.9 ! root 872: vdev->vm_running = vm_running;
1.1.1.7 root 873: for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
1.1.1.6 root 874: vdev->vq[i].vector = VIRTIO_NO_VECTOR;
1.1.1.7 root 875: vdev->vq[i].vdev = vdev;
876: }
1.1 root 877:
878: vdev->name = name;
879: vdev->config_len = config_size;
880: if (vdev->config_len)
881: vdev->config = qemu_mallocz(config_size);
882: else
883: vdev->config = NULL;
884:
1.1.1.8 root 885: vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
886:
1.1 root 887: return vdev;
888: }
1.1.1.5 root 889:
890: void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
891: void *opaque)
892: {
893: vdev->binding = binding;
894: vdev->binding_opaque = opaque;
895: }
1.1.1.7 root 896:
897: target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
898: {
899: return vdev->vq[n].vring.desc;
900: }
901:
902: target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n)
903: {
904: return vdev->vq[n].vring.avail;
905: }
906:
907: target_phys_addr_t virtio_queue_get_used_addr(VirtIODevice *vdev, int n)
908: {
909: return vdev->vq[n].vring.used;
910: }
911:
912: target_phys_addr_t virtio_queue_get_ring_addr(VirtIODevice *vdev, int n)
913: {
914: return vdev->vq[n].vring.desc;
915: }
916:
917: target_phys_addr_t virtio_queue_get_desc_size(VirtIODevice *vdev, int n)
918: {
919: return sizeof(VRingDesc) * vdev->vq[n].vring.num;
920: }
921:
922: target_phys_addr_t virtio_queue_get_avail_size(VirtIODevice *vdev, int n)
923: {
924: return offsetof(VRingAvail, ring) +
925: sizeof(uint64_t) * vdev->vq[n].vring.num;
926: }
927:
928: target_phys_addr_t virtio_queue_get_used_size(VirtIODevice *vdev, int n)
929: {
930: return offsetof(VRingUsed, ring) +
931: sizeof(VRingUsedElem) * vdev->vq[n].vring.num;
932: }
933:
934: target_phys_addr_t virtio_queue_get_ring_size(VirtIODevice *vdev, int n)
935: {
936: return vdev->vq[n].vring.used - vdev->vq[n].vring.desc +
937: virtio_queue_get_used_size(vdev, n);
938: }
939:
940: uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
941: {
942: return vdev->vq[n].last_avail_idx;
943: }
944:
945: void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
946: {
947: vdev->vq[n].last_avail_idx = idx;
948: }
949:
950: VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
951: {
952: return vdev->vq + n;
953: }
954:
955: EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
956: {
957: return &vq->guest_notifier;
958: }
959: EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
960: {
961: return &vq->host_notifier;
962: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.