in vhost.c [1868:1905]
static int log_write_hva(struct vhost_virtqueue *vq, u64 hva, u64 len)
{
struct vhost_iotlb *umem = vq->umem;
struct vhost_iotlb_map *u;
u64 start, end, l, min;
int r;
bool hit = false;
while (len) {
min = len;
/* More than one GPAs can be mapped into a single HVA. So
* iterate all possible umems here to be safe.
*/
list_for_each_entry(u, &umem->list, link) {
if (u->addr > hva - 1 + len ||
u->addr - 1 + u->size < hva)
continue;
start = max(u->addr, hva);
end = min(u->addr - 1 + u->size, hva - 1 + len);
l = end - start + 1;
r = log_write(vq->log_base,
u->start + start - u->addr,
l);
if (r < 0)
return r;
hit = true;
min = min(l, min);
}
if (!hit)
return -EFAULT;
len -= min;
hva += min;
}
return 0;
}