in vhost.c [1138:1186]
ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
struct iov_iter *from)
{
struct vhost_iotlb_msg msg;
size_t offset;
int type, ret;
ret = copy_from_iter(&type, sizeof(type), from);
if (ret != sizeof(type)) {
ret = -EINVAL;
goto done;
}
switch (type) {
case VHOST_IOTLB_MSG:
/* There maybe a hole after type for V1 message type,
* so skip it here.
*/
offset = offsetof(struct vhost_msg, iotlb) - sizeof(int);
break;
case VHOST_IOTLB_MSG_V2:
offset = sizeof(__u32);
break;
default:
ret = -EINVAL;
goto done;
}
iov_iter_advance(from, offset);
ret = copy_from_iter(&msg, sizeof(msg), from);
if (ret != sizeof(msg)) {
ret = -EINVAL;
goto done;
}
if (dev->msg_handler)
ret = dev->msg_handler(dev, &msg);
else
ret = vhost_process_iotlb_msg(dev, &msg);
if (ret) {
ret = -EFAULT;
goto done;
}
ret = (type == VHOST_IOTLB_MSG) ? sizeof(struct vhost_msg) :
sizeof(struct vhost_msg_v2);
done:
return ret;
}