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

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: }

unix.superglobalmegacorp.com

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