|
|
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: #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.
1.1.1.6 root 28: * In any case, we must prevent the compiler from reordering the code.
29: * TODO: we likely need some rmb()/mb() as well.
1.1 root 30: */
1.1.1.6 root 31:
32: #define wmb() __asm__ __volatile__("": : :"memory")
1.1 root 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;
1.1.1.5 root 73: target_phys_addr_t pa;
1.1 root 74: uint16_t last_avail_idx;
75: int inuse;
1.1.1.5 root 76: uint16_t vector;
1.1 root 77: void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq);
1.1.1.7 root 78: VirtIODevice *vdev;
79: EventNotifier guest_notifier;
80: EventNotifier host_notifier;
1.1 root 81: };
82:
83: /* virt queue functions */
1.1.1.5 root 84: static void virtqueue_init(VirtQueue *vq)
1.1 root 85: {
1.1.1.5 root 86: target_phys_addr_t pa = vq->pa;
1.1 root 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:
1.1.1.5 root 95: static inline uint64_t vring_desc_addr(target_phys_addr_t desc_pa, int i)
1.1 root 96: {
97: target_phys_addr_t pa;
1.1.1.5 root 98: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, addr);
1.1 root 99: return ldq_phys(pa);
100: }
101:
1.1.1.5 root 102: static inline uint32_t vring_desc_len(target_phys_addr_t desc_pa, int i)
1.1 root 103: {
104: target_phys_addr_t pa;
1.1.1.5 root 105: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, len);
1.1 root 106: return ldl_phys(pa);
107: }
108:
1.1.1.5 root 109: static inline uint16_t vring_desc_flags(target_phys_addr_t desc_pa, int i)
1.1 root 110: {
111: target_phys_addr_t pa;
1.1.1.5 root 112: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, flags);
1.1 root 113: return lduw_phys(pa);
114: }
115:
1.1.1.5 root 116: static inline uint16_t vring_desc_next(target_phys_addr_t desc_pa, int i)
1.1 root 117: {
118: target_phys_addr_t pa;
1.1.1.5 root 119: pa = desc_pa + sizeof(VRingDesc) * i + offsetof(VRingDesc, next);
1.1 root 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:
1.1.1.8 ! root 210: trace_virtqueue_fill(vq, elem, len, idx);
! 211:
1.1 root 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:
1.1.1.5 root 216: cpu_physical_memory_unmap(elem->in_sg[i].iov_base,
217: elem->in_sg[i].iov_len,
218: 1, size);
1.1 root 219:
1.1.1.5 root 220: offset += elem->in_sg[i].iov_len;
1.1 root 221: }
222:
1.1.1.5 root 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:
1.1 root 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();
1.1.1.8 ! root 239: trace_virtqueue_flush(vq, count);
1.1 root 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) {
1.1.1.8 ! root 257: error_report("Guest moved used index from %u to %u",
! 258: idx, vring_avail_idx(vq));
1.1 root 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) {
1.1.1.8 ! root 275: error_report("Guest says index %u is available", head);
1.1 root 276: exit(1);
277: }
278:
279: return head;
280: }
281:
1.1.1.5 root 282: static unsigned virtqueue_next_desc(target_phys_addr_t desc_pa,
283: unsigned int i, unsigned int max)
1.1 root 284: {
285: unsigned int next;
286:
287: /* If this descriptor says it doesn't chain, we're done. */
1.1.1.5 root 288: if (!(vring_desc_flags(desc_pa, i) & VRING_DESC_F_NEXT))
289: return max;
1.1 root 290:
291: /* Check they're not leading us off end of descriptors. */
1.1.1.5 root 292: next = vring_desc_next(desc_pa, i);
1.1 root 293: /* Make sure compiler knows to grab that: we don't want it changing! */
294: wmb();
295:
1.1.1.5 root 296: if (next >= max) {
1.1.1.8 ! root 297: error_report("Desc next is %u", next);
1.1 root 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;
1.1.1.5 root 307: int total_bufs, in_total, out_total;
1.1 root 308:
309: idx = vq->last_avail_idx;
310:
1.1.1.5 root 311: total_bufs = in_total = out_total = 0;
1.1 root 312: while (virtqueue_num_heads(vq, idx)) {
1.1.1.5 root 313: unsigned int max, num_bufs, indirect = 0;
314: target_phys_addr_t desc_pa;
1.1 root 315: int i;
316:
1.1.1.5 root 317: max = vq->vring.num;
318: num_bufs = total_bufs;
1.1 root 319: i = virtqueue_get_head(vq, idx++);
1.1.1.5 root 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)) {
1.1.1.8 ! root 324: error_report("Invalid size for indirect buffer table");
1.1.1.5 root 325: exit(1);
326: }
327:
328: /* If we've got too many, that implies a descriptor loop. */
329: if (num_bufs >= max) {
1.1.1.8 ! root 330: error_report("Looped descriptor");
1.1.1.5 root 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:
1.1 root 341: do {
342: /* If we've got too many, that implies a descriptor loop. */
1.1.1.5 root 343: if (++num_bufs > max) {
1.1.1.8 ! root 344: error_report("Looped descriptor");
1.1 root 345: exit(1);
346: }
347:
1.1.1.5 root 348: if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_WRITE) {
1.1 root 349: if (in_bytes > 0 &&
1.1.1.5 root 350: (in_total += vring_desc_len(desc_pa, i)) >= in_bytes)
1.1 root 351: return 1;
352: } else {
353: if (out_bytes > 0 &&
1.1.1.5 root 354: (out_total += vring_desc_len(desc_pa, i)) >= out_bytes)
1.1 root 355: return 1;
356: }
1.1.1.5 root 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++;
1.1 root 363: }
364:
365: return 0;
366: }
367:
1.1.1.7 root 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) {
1.1.1.8 ! root 378: error_report("virtio: trying to map MMIO memory");
1.1.1.7 root 379: exit(1);
380: }
381: }
382: }
383:
1.1 root 384: int virtqueue_pop(VirtQueue *vq, VirtQueueElement *elem)
385: {
1.1.1.5 root 386: unsigned int i, head, max;
387: target_phys_addr_t desc_pa = vq->vring.desc;
1.1 root 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:
1.1.1.5 root 395: max = vq->vring.num;
396:
1.1 root 397: i = head = virtqueue_get_head(vq, vq->last_avail_idx++);
1.1.1.5 root 398:
399: if (vring_desc_flags(desc_pa, i) & VRING_DESC_F_INDIRECT) {
400: if (vring_desc_len(desc_pa, i) % sizeof(VRingDesc)) {
1.1.1.8 ! root 401: error_report("Invalid size for indirect buffer table");
1.1.1.5 root 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:
1.1.1.7 root 411: /* Collect all the descriptors */
1.1 root 412: do {
413: struct iovec *sg;
414:
1.1.1.5 root 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);
1.1 root 417: sg = &elem->in_sg[elem->in_num++];
1.1.1.7 root 418: } else {
419: elem->out_addr[elem->out_num] = vring_desc_addr(desc_pa, i);
1.1 root 420: sg = &elem->out_sg[elem->out_num++];
1.1.1.7 root 421: }
1.1 root 422:
1.1.1.5 root 423: sg->iov_len = vring_desc_len(desc_pa, i);
1.1 root 424:
425: /* If we've got too many, that implies a descriptor loop. */
1.1.1.5 root 426: if ((elem->in_num + elem->out_num) > max) {
1.1.1.8 ! root 427: error_report("Looped descriptor");
1.1 root 428: exit(1);
429: }
1.1.1.5 root 430: } while ((i = virtqueue_next_desc(desc_pa, i, max)) != max);
1.1 root 431:
1.1.1.7 root 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:
1.1 root 436: elem->index = head;
437:
438: vq->inuse++;
439:
1.1.1.8 ! root 440: trace_virtqueue_pop(vq, elem, elem->in_num, elem->out_num);
1.1 root 441: return elem->in_num + elem->out_num;
442: }
443:
444: /* virtio device */
1.1.1.5 root 445: static void virtio_notify_vector(VirtIODevice *vdev, uint16_t vector)
1.1 root 446: {
1.1.1.5 root 447: if (vdev->binding->notify) {
448: vdev->binding->notify(vdev->binding_opaque, vector);
449: }
1.1 root 450: }
451:
1.1.1.5 root 452: void virtio_update_irq(VirtIODevice *vdev)
1.1 root 453: {
1.1.1.5 root 454: virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
1.1 root 455: }
456:
1.1.1.5 root 457: void virtio_reset(void *opaque)
1.1 root 458: {
459: VirtIODevice *vdev = opaque;
460: int i;
461:
1.1.1.7 root 462: virtio_set_status(vdev, 0);
463:
1.1 root 464: if (vdev->reset)
465: vdev->reset(vdev);
466:
1.1.1.7 root 467: vdev->guest_features = 0;
1.1 root 468: vdev->queue_sel = 0;
469: vdev->status = 0;
470: vdev->isr = 0;
1.1.1.5 root 471: vdev->config_vector = VIRTIO_NO_VECTOR;
472: virtio_notify_vector(vdev, vdev->config_vector);
1.1 root 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;
1.1.1.5 root 479: vdev->vq[i].pa = 0;
480: vdev->vq[i].vector = VIRTIO_NO_VECTOR;
1.1 root 481: }
482: }
483:
1.1.1.5 root 484: uint32_t virtio_config_readb(VirtIODevice *vdev, uint32_t addr)
1.1 root 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:
1.1.1.5 root 497: uint32_t virtio_config_readw(VirtIODevice *vdev, uint32_t addr)
1.1 root 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:
1.1.1.5 root 510: uint32_t virtio_config_readl(VirtIODevice *vdev, uint32_t addr)
1.1 root 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:
1.1.1.5 root 523: void virtio_config_writeb(VirtIODevice *vdev, uint32_t addr, uint32_t data)
1.1 root 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:
1.1.1.5 root 536: void virtio_config_writew(VirtIODevice *vdev, uint32_t addr, uint32_t data)
1.1 root 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:
1.1.1.5 root 549: void virtio_config_writel(VirtIODevice *vdev, uint32_t addr, uint32_t data)
1.1 root 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:
1.1.1.5 root 562: void virtio_queue_set_addr(VirtIODevice *vdev, int n, target_phys_addr_t addr)
1.1 root 563: {
1.1.1.5 root 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: }
1.1 root 572:
1.1.1.5 root 573: int virtio_queue_get_num(VirtIODevice *vdev, int n)
574: {
575: return vdev->vq[n].vring.num;
576: }
1.1 root 577:
1.1.1.8 ! root 578: void virtio_queue_notify_vq(VirtQueue *vq)
! 579: {
! 580: if (vq->vring.desc) {
! 581: VirtIODevice *vdev = vq->vdev;
! 582: trace_virtio_queue_notify(vdev, vq - vdev->vq, vq);
! 583: vq->handle_output(vdev, vq);
! 584: }
! 585: }
! 586:
1.1.1.5 root 587: void virtio_queue_notify(VirtIODevice *vdev, int n)
588: {
1.1.1.8 ! root 589: if (n < VIRTIO_PCI_QUEUE_MAX) {
! 590: virtio_queue_notify_vq(&vdev->vq[n]);
1.1 root 591: }
592: }
593:
1.1.1.5 root 594: uint16_t virtio_queue_vector(VirtIODevice *vdev, int n)
595: {
596: return n < VIRTIO_PCI_QUEUE_MAX ? vdev->vq[n].vector :
597: VIRTIO_NO_VECTOR;
598: }
599:
600: void virtio_queue_set_vector(VirtIODevice *vdev, int n, uint16_t vector)
601: {
602: if (n < VIRTIO_PCI_QUEUE_MAX)
603: vdev->vq[n].vector = vector;
604: }
605:
1.1 root 606: VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
607: void (*handle_output)(VirtIODevice *, VirtQueue *))
608: {
609: int i;
610:
611: for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
612: if (vdev->vq[i].vring.num == 0)
613: break;
614: }
615:
616: if (i == VIRTIO_PCI_QUEUE_MAX || queue_size > VIRTQUEUE_MAX_SIZE)
617: abort();
618:
619: vdev->vq[i].vring.num = queue_size;
620: vdev->vq[i].handle_output = handle_output;
621:
622: return &vdev->vq[i];
623: }
624:
1.1.1.7 root 625: void virtio_irq(VirtQueue *vq)
626: {
1.1.1.8 ! root 627: trace_virtio_irq(vq);
1.1.1.7 root 628: vq->vdev->isr |= 0x01;
629: virtio_notify_vector(vq->vdev, vq->vector);
630: }
631:
1.1 root 632: void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
633: {
1.1.1.2 root 634: /* Always notify when queue is empty (when feature acknowledge) */
635: if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
1.1.1.7 root 636: (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
1.1.1.2 root 637: (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
1.1 root 638: return;
639:
1.1.1.8 ! root 640: trace_virtio_notify(vdev, vq);
1.1 root 641: vdev->isr |= 0x01;
1.1.1.5 root 642: virtio_notify_vector(vdev, vq->vector);
1.1 root 643: }
644:
645: void virtio_notify_config(VirtIODevice *vdev)
646: {
647: if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))
648: return;
649:
650: vdev->isr |= 0x03;
1.1.1.5 root 651: virtio_notify_vector(vdev, vdev->config_vector);
1.1 root 652: }
653:
654: void virtio_save(VirtIODevice *vdev, QEMUFile *f)
655: {
656: int i;
657:
1.1.1.5 root 658: if (vdev->binding->save_config)
659: vdev->binding->save_config(vdev->binding_opaque, f);
1.1 root 660:
661: qemu_put_8s(f, &vdev->status);
662: qemu_put_8s(f, &vdev->isr);
663: qemu_put_be16s(f, &vdev->queue_sel);
1.1.1.7 root 664: qemu_put_be32s(f, &vdev->guest_features);
1.1 root 665: qemu_put_be32(f, vdev->config_len);
666: qemu_put_buffer(f, vdev->config, vdev->config_len);
667:
668: for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
669: if (vdev->vq[i].vring.num == 0)
670: break;
671: }
672:
673: qemu_put_be32(f, i);
674:
675: for (i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
676: if (vdev->vq[i].vring.num == 0)
677: break;
678:
679: qemu_put_be32(f, vdev->vq[i].vring.num);
1.1.1.5 root 680: qemu_put_be64(f, vdev->vq[i].pa);
1.1 root 681: qemu_put_be16s(f, &vdev->vq[i].last_avail_idx);
1.1.1.5 root 682: if (vdev->binding->save_queue)
683: vdev->binding->save_queue(vdev->binding_opaque, i, f);
1.1 root 684: }
685: }
686:
1.1.1.5 root 687: int virtio_load(VirtIODevice *vdev, QEMUFile *f)
1.1 root 688: {
1.1.1.5 root 689: int num, i, ret;
1.1.1.6 root 690: uint32_t features;
1.1.1.7 root 691: uint32_t supported_features =
1.1.1.6 root 692: vdev->binding->get_features(vdev->binding_opaque);
1.1 root 693:
1.1.1.5 root 694: if (vdev->binding->load_config) {
695: ret = vdev->binding->load_config(vdev->binding_opaque, f);
696: if (ret)
697: return ret;
698: }
1.1 root 699:
700: qemu_get_8s(f, &vdev->status);
701: qemu_get_8s(f, &vdev->isr);
702: qemu_get_be16s(f, &vdev->queue_sel);
1.1.1.6 root 703: qemu_get_be32s(f, &features);
704: if (features & ~supported_features) {
1.1.1.8 ! root 705: error_report("Features 0x%x unsupported. Allowed features: 0x%x",
! 706: features, supported_features);
1.1.1.6 root 707: return -1;
708: }
1.1.1.7 root 709: if (vdev->set_features)
710: vdev->set_features(vdev, features);
711: vdev->guest_features = features;
1.1 root 712: vdev->config_len = qemu_get_be32(f);
713: qemu_get_buffer(f, vdev->config, vdev->config_len);
714:
715: num = qemu_get_be32(f);
716:
717: for (i = 0; i < num; i++) {
718: vdev->vq[i].vring.num = qemu_get_be32(f);
1.1.1.5 root 719: vdev->vq[i].pa = qemu_get_be64(f);
1.1 root 720: qemu_get_be16s(f, &vdev->vq[i].last_avail_idx);
721:
1.1.1.5 root 722: if (vdev->vq[i].pa) {
1.1.1.8 ! root 723: uint16_t nheads;
1.1.1.5 root 724: virtqueue_init(&vdev->vq[i]);
1.1.1.8 ! root 725: nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx;
! 726: /* Check it isn't doing very strange things with descriptor numbers. */
! 727: if (nheads > vdev->vq[i].vring.num) {
! 728: error_report("VQ %d size 0x%x Guest index 0x%x "
! 729: "inconsistent with Host index 0x%x: delta 0x%x\n",
! 730: i, vdev->vq[i].vring.num,
! 731: vring_avail_idx(&vdev->vq[i]),
! 732: vdev->vq[i].last_avail_idx, nheads);
! 733: return -1;
! 734: }
! 735: } else if (vdev->vq[i].last_avail_idx) {
! 736: error_report("VQ %d address 0x0 "
! 737: "inconsistent with Host index 0x%x\n",
! 738: i, vdev->vq[i].last_avail_idx);
! 739: return -1;
! 740: }
1.1.1.5 root 741: if (vdev->binding->load_queue) {
742: ret = vdev->binding->load_queue(vdev->binding_opaque, i, f);
743: if (ret)
744: return ret;
1.1 root 745: }
746: }
747:
1.1.1.5 root 748: virtio_notify_vector(vdev, VIRTIO_NO_VECTOR);
749: return 0;
1.1 root 750: }
751:
1.1.1.4 root 752: void virtio_cleanup(VirtIODevice *vdev)
753: {
1.1.1.8 ! root 754: qemu_del_vm_change_state_handler(vdev->vmstate);
1.1.1.4 root 755: if (vdev->config)
756: qemu_free(vdev->config);
757: qemu_free(vdev->vq);
758: }
759:
1.1.1.8 ! root 760: static void virtio_vmstate_change(void *opaque, int running, int reason)
! 761: {
! 762: VirtIODevice *vdev = opaque;
! 763: bool backend_run = running && (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK);
! 764: vdev->vm_running = running;
! 765:
! 766: if (backend_run) {
! 767: virtio_set_status(vdev, vdev->status);
! 768: }
! 769:
! 770: if (vdev->binding->vmstate_change) {
! 771: vdev->binding->vmstate_change(vdev->binding_opaque, backend_run);
! 772: }
! 773:
! 774: if (!backend_run) {
! 775: virtio_set_status(vdev, vdev->status);
! 776: }
! 777: }
! 778:
1.1.1.5 root 779: VirtIODevice *virtio_common_init(const char *name, uint16_t device_id,
780: size_t config_size, size_t struct_size)
1.1 root 781: {
782: VirtIODevice *vdev;
1.1.1.6 root 783: int i;
1.1 root 784:
1.1.1.5 root 785: vdev = qemu_mallocz(struct_size);
1.1 root 786:
1.1.1.5 root 787: vdev->device_id = device_id;
1.1 root 788: vdev->status = 0;
789: vdev->isr = 0;
790: vdev->queue_sel = 0;
1.1.1.5 root 791: vdev->config_vector = VIRTIO_NO_VECTOR;
1.1 root 792: vdev->vq = qemu_mallocz(sizeof(VirtQueue) * VIRTIO_PCI_QUEUE_MAX);
1.1.1.7 root 793: for(i = 0; i < VIRTIO_PCI_QUEUE_MAX; i++) {
1.1.1.6 root 794: vdev->vq[i].vector = VIRTIO_NO_VECTOR;
1.1.1.7 root 795: vdev->vq[i].vdev = vdev;
796: }
1.1 root 797:
798: vdev->name = name;
799: vdev->config_len = config_size;
800: if (vdev->config_len)
801: vdev->config = qemu_mallocz(config_size);
802: else
803: vdev->config = NULL;
804:
1.1.1.8 ! root 805: vdev->vmstate = qemu_add_vm_change_state_handler(virtio_vmstate_change, vdev);
! 806:
1.1 root 807: return vdev;
808: }
1.1.1.5 root 809:
810: void virtio_bind_device(VirtIODevice *vdev, const VirtIOBindings *binding,
811: void *opaque)
812: {
813: vdev->binding = binding;
814: vdev->binding_opaque = opaque;
815: }
1.1.1.7 root 816:
817: target_phys_addr_t virtio_queue_get_desc_addr(VirtIODevice *vdev, int n)
818: {
819: return vdev->vq[n].vring.desc;
820: }
821:
822: target_phys_addr_t virtio_queue_get_avail_addr(VirtIODevice *vdev, int n)
823: {
824: return vdev->vq[n].vring.avail;
825: }
826:
827: target_phys_addr_t virtio_queue_get_used_addr(VirtIODevice *vdev, int n)
828: {
829: return vdev->vq[n].vring.used;
830: }
831:
832: target_phys_addr_t virtio_queue_get_ring_addr(VirtIODevice *vdev, int n)
833: {
834: return vdev->vq[n].vring.desc;
835: }
836:
837: target_phys_addr_t virtio_queue_get_desc_size(VirtIODevice *vdev, int n)
838: {
839: return sizeof(VRingDesc) * vdev->vq[n].vring.num;
840: }
841:
842: target_phys_addr_t virtio_queue_get_avail_size(VirtIODevice *vdev, int n)
843: {
844: return offsetof(VRingAvail, ring) +
845: sizeof(uint64_t) * vdev->vq[n].vring.num;
846: }
847:
848: target_phys_addr_t virtio_queue_get_used_size(VirtIODevice *vdev, int n)
849: {
850: return offsetof(VRingUsed, ring) +
851: sizeof(VRingUsedElem) * vdev->vq[n].vring.num;
852: }
853:
854: target_phys_addr_t virtio_queue_get_ring_size(VirtIODevice *vdev, int n)
855: {
856: return vdev->vq[n].vring.used - vdev->vq[n].vring.desc +
857: virtio_queue_get_used_size(vdev, n);
858: }
859:
860: uint16_t virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
861: {
862: return vdev->vq[n].last_avail_idx;
863: }
864:
865: void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n, uint16_t idx)
866: {
867: vdev->vq[n].last_avail_idx = idx;
868: }
869:
870: VirtQueue *virtio_get_queue(VirtIODevice *vdev, int n)
871: {
872: return vdev->vq + n;
873: }
874:
875: EventNotifier *virtio_queue_get_guest_notifier(VirtQueue *vq)
876: {
877: return &vq->guest_notifier;
878: }
879: EventNotifier *virtio_queue_get_host_notifier(VirtQueue *vq)
880: {
881: return &vq->host_notifier;
882: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.