static void vring_kick(struct virtqueue *_vq)
{
	u16 prev_avail_idx;
	struct vring_virtqueue *vq = to_vvq(_vq);

	/* Descriptors and available array need to be set before we expose the
	 * new available array entries. */
	mb();

	prev_avail_idx = vq->vring.avail->idx - (u16) vq->num_added;
	DPrintf(4, ("%s>>> vq->vring.avail->idx %d\n", __FUNCTION__, vq->vring.avail->idx));
	vq->num_added = 0;

	/* Need to update avail index before checking if we should notify */
	mb();

	if(vq->use_published_indices) {
		if(vring_need_event(vring_last_avail(&vq->vring),
			                vq->vring.avail->idx,
							prev_avail_idx))
			vq->notify(&vq->vq);
	} else {
		if (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY))
			/* Prod other side to tell it about changes. */
			vq->notify(&vq->vq);
	}
}
Esempio n. 2
0
void call_used(void)
{
	/* Flush in previous flags write */
	/* Barrier D (for pairing) */
	smp_mb();
	if (!vring_need_event(vring_used_event(&ring),
			      host.used_idx,
			      host.called_used_idx))
		return;

	host.called_used_idx = host.used_idx;
	call();
}
Esempio n. 3
0
void kick_available(void)
{
	/* Flush in previous flags write */
	/* Barrier C (for pairing) */
	smp_mb();
	if (!vring_need_event(vring_avail_event(&ring),
			      guest.avail_idx,
			      guest.kicked_avail_idx))
		return;

	guest.kicked_avail_idx = guest.avail_idx;
	kick();
}
Esempio n. 4
0
/**
 *
 * vq_ring_must_notify_host
 *
 */
static int vq_ring_must_notify_host(struct virtqueue *vq)
{
	uint16_t new_idx, prev_idx, event_idx;

	if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {
		new_idx = vq->vq_ring.avail->idx;
		prev_idx = new_idx - vq->vq_queued_cnt;
		event_idx = vring_avail_event(&vq->vq_ring);

		return (vring_need_event(event_idx, new_idx, prev_idx) != 0);
	}

	return ((vq->vq_ring.used->flags & VRING_USED_F_NO_NOTIFY) == 0);
}
Esempio n. 5
0
bool virtio_queue_should_signal(struct virtio_queue *vq)
{
	u16 old_idx, new_idx, event_idx;

	if (!vq->addr) {
		return FALSE;
	}

	old_idx         = vq->last_used_signalled;
	new_idx         = vq->vring.used->idx;
	event_idx       = vring_used_event(&vq->vring);

	if (vring_need_event(event_idx, new_idx, old_idx)) {
		vq->last_used_signalled = new_idx;
		return TRUE;
	}

	return FALSE;
}
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);
}