Annotation of qemu/hw/virtio.c, revision 1.1.1.10

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.