static int virtqueue_num_heads(VirtQueue *vq, unsigned int idx) { uint16_t num_heads = vring_avail_idx(vq) - idx; /* Check it isn't doing very strange things with descriptor numbers. */ if (num_heads > vq->vring.num) { fprintf(stderr, "Guest moved used index from %u to %u", idx, vring_avail_idx(vq)); exit(1); } return num_heads; }
void virtio_queue_set_notification(VirtQueue *vq, int enable) { vq->notification = enable; if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { vring_avail_event(vq, vring_avail_idx(vq)); } else if (enable) { vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY); } else { vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY); } }
void virtio_queue_set_notification(VirtQueue *vq, int enable) { vq->notification = enable; if (bUsePublishedIndices) { vring_avail_event(vq, vring_avail_idx(vq)); } else if (enable) { vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY); } else { vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY); } }
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) { /* Always notify when queue is empty (when feature acknowledge) */ if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) && (!(vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) || (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx))) return; vdev->isr |= 0x01; virtio_notify_vector(vdev, vq->vector); }
/* Fetch avail_idx from VQ memory only when we really need to know if * guest has added some buffers. */ bool vu_queue_empty(VuDev *dev, VuVirtq *vq) { if (unlikely(dev->broken) || unlikely(!vq->vring.avail)) { return true; } if (vq->shadow_avail_idx != vq->last_avail_idx) { return false; } return vring_avail_idx(vq) == vq->last_avail_idx; }
void virtio_queue_set_notification(VirtQueue *vq, int enable) { vq->notification = enable; if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { vring_avail_event(vq, vring_avail_idx(vq)); } else if (enable) { vring_used_flags_unset_bit(vq, VRING_USED_F_NO_NOTIFY); } else { vring_used_flags_set_bit(vq, VRING_USED_F_NO_NOTIFY); } if (enable) { /* Expose avail event/used flags before caller checks the avail idx. */ smp_mb(); } }
static int virtqueue_num_heads(VuDev *dev, VuVirtq *vq, unsigned int idx) { uint16_t num_heads = vring_avail_idx(vq) - idx; /* Check it isn't doing very strange things with descriptor numbers. */ if (num_heads > vq->vring.num) { vu_panic(dev, "Guest moved used index from %u to %u", idx, vq->shadow_avail_idx); return -1; } if (num_heads) { /* On success, callers read a descriptor at vq->last_avail_idx. * Make sure descriptor read does not bypass avail index read. */ smp_rmb(); } return num_heads; }
static bool vring_notify(PVOID unused, VirtQueue *vq) { uint16_t old, _new; bool v; /* Always notify when queue is empty (when feature acknowledge) */ //if (((vdev->guest_features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) && if ((bVirtioF_NotifyOnEmpty && !vq->inuse && vring_avail_idx(vq) == vq->last_avail_idx)) { return TRUE; } //if (!(vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX))) { if (!bUsePublishedIndices) { return !(vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT); } v = vq->signalled_used_valid; vq->signalled_used_valid = TRUE; old = vq->signalled_used; _new = vq->signalled_used = vring_used_idx(vq); return !v || vring_need_event(vring_used_event(vq), _new, old); }
int virtio_queue_empty(VirtQueue *vq) { return vring_avail_idx(vq) == vq->last_avail_idx; }