in vringh.c [38:76]
static inline int __vringh_get_head(const struct vringh *vrh,
int (*getu16)(const struct vringh *vrh,
u16 *val, const __virtio16 *p),
u16 *last_avail_idx)
{
u16 avail_idx, i, head;
int err;
err = getu16(vrh, &avail_idx, &vrh->vring.avail->idx);
if (err) {
vringh_bad("Failed to access avail idx at %p",
&vrh->vring.avail->idx);
return err;
}
if (*last_avail_idx == avail_idx)
return vrh->vring.num;
/* Only get avail ring entries after they have been exposed by guest. */
virtio_rmb(vrh->weak_barriers);
i = *last_avail_idx & (vrh->vring.num - 1);
err = getu16(vrh, &head, &vrh->vring.avail->ring[i]);
if (err) {
vringh_bad("Failed to read head: idx %d address %p",
*last_avail_idx, &vrh->vring.avail->ring[i]);
return err;
}
if (head >= vrh->vring.num) {
vringh_bad("Guest says index %u > %u is available",
head, vrh->vring.num);
return -EINVAL;
}
(*last_avail_idx)++;
return head;
}