in vringh.c [687:733]
int vringh_getdesc_user(struct vringh *vrh,
struct vringh_iov *riov,
struct vringh_iov *wiov,
bool (*getrange)(struct vringh *vrh,
u64 addr, struct vringh_range *r),
u16 *head)
{
int err;
*head = vrh->vring.num;
err = __vringh_get_head(vrh, getu16_user, &vrh->last_avail_idx);
if (err < 0)
return err;
/* Empty... */
if (err == vrh->vring.num)
return 0;
/* We need the layouts to be the identical for this to work */
BUILD_BUG_ON(sizeof(struct vringh_kiov) != sizeof(struct vringh_iov));
BUILD_BUG_ON(offsetof(struct vringh_kiov, iov) !=
offsetof(struct vringh_iov, iov));
BUILD_BUG_ON(offsetof(struct vringh_kiov, i) !=
offsetof(struct vringh_iov, i));
BUILD_BUG_ON(offsetof(struct vringh_kiov, used) !=
offsetof(struct vringh_iov, used));
BUILD_BUG_ON(offsetof(struct vringh_kiov, max_num) !=
offsetof(struct vringh_iov, max_num));
BUILD_BUG_ON(sizeof(struct iovec) != sizeof(struct kvec));
BUILD_BUG_ON(offsetof(struct iovec, iov_base) !=
offsetof(struct kvec, iov_base));
BUILD_BUG_ON(offsetof(struct iovec, iov_len) !=
offsetof(struct kvec, iov_len));
BUILD_BUG_ON(sizeof(((struct iovec *)NULL)->iov_base)
!= sizeof(((struct kvec *)NULL)->iov_base));
BUILD_BUG_ON(sizeof(((struct iovec *)NULL)->iov_len)
!= sizeof(((struct kvec *)NULL)->iov_len));
*head = err;
err = __vringh_iov(vrh, *head, (struct vringh_kiov *)riov,
(struct vringh_kiov *)wiov,
range_check, getrange, GFP_KERNEL, copydesc_user);
if (err)
return err;
return 1;
}