diff options
author | JaeMan Park <jaeman@google.com> | 2021-07-22 07:05:11 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-07-22 07:05:11 +0000 |
commit | 8fa82d5f89a05c196bf948c46e5b64055713b55d (patch) | |
tree | 194a72bf90ca9843d562b13cb924c2e224bfd286 /wmediumd | |
parent | 4451c99cfe39d7d8fb45f40b9b08bc24d8fbbf64 (diff) | |
parent | 7dca8ac4aeaca1507864c8b330b0a604c87633cf (diff) | |
download | wmediumd-8fa82d5f89a05c196bf948c46e5b64055713b55d.tar.gz |
Merge changes from topic "wmediumd_vhost"
* changes:
Fix translation of vring address to guest-physical
Fix assertion failure at usfstl_vhost_user_read_msg
Diffstat (limited to 'wmediumd')
-rw-r--r-- | wmediumd/inc/usfstl/vhost.h | 7 | ||||
-rw-r--r-- | wmediumd/lib/vhost.c | 37 |
2 files changed, 40 insertions, 4 deletions
diff --git a/wmediumd/inc/usfstl/vhost.h b/wmediumd/inc/usfstl/vhost.h index f07a33d..017d0b5 100644 --- a/wmediumd/inc/usfstl/vhost.h +++ b/wmediumd/inc/usfstl/vhost.h @@ -140,6 +140,13 @@ void usfstl_vhost_user_config_changed(struct usfstl_vhost_user_dev *dev); */ void *usfstl_vhost_user_to_va(struct usfstl_vhost_user_dev *dev, uint64_t addr); +/** + * usfstl_vhost_phys_to_va - translate address + * @dev: device to translate address for + * @addr: guest-side physical addr + */ +void *usfstl_vhost_phys_to_va(struct usfstl_vhost_user_dev *dev, uint64_t addr); + /* also some IOV helpers */ size_t iov_len(struct iovec *sg, unsigned int nsg); size_t iov_fill(struct iovec *sg, unsigned int nsg, diff --git a/wmediumd/lib/vhost.c b/wmediumd/lib/vhost.c index 0b9a571..ecb065d 100644 --- a/wmediumd/lib/vhost.c +++ b/wmediumd/lib/vhost.c @@ -141,7 +141,7 @@ usfstl_vhost_user_get_virtq_buf(struct usfstl_vhost_user_dev_int *dev, } addr = virtio_to_cpu64(dev, desc->addr); - vec->iov_base = usfstl_vhost_user_to_va(&dev->ext, addr); + vec->iov_base = usfstl_vhost_phys_to_va(&dev->ext, addr); vec->iov_len = virtio_to_cpu32(dev, desc->len); desc = &virtq->desc[virtio_to_cpu16(dev, desc->next)]; @@ -175,6 +175,8 @@ static int usfstl_vhost_user_read_msg(int fd, struct msghdr *msghdr) size_t i; size_t maxlen = 0; ssize_t len; + ssize_t prev_datalen; + size_t prev_iovlen; USFSTL_ASSERT(msghdr->msg_iovlen >= 1); USFSTL_ASSERT(msghdr->msg_iov[0].iov_len >= sizeof(*hdr)); @@ -199,18 +201,24 @@ static int usfstl_vhost_user_read_msg(int fd, struct msghdr *msghdr) if (!hdr->size) return 0; + prev_iovlen = msghdr->msg_iovlen; + msghdr->msg_iovlen = 1; + msghdr->msg_control = NULL; msghdr->msg_controllen = 0; msghdr->msg_iov[0].iov_base += sizeof(*hdr); - msghdr->msg_iov[0].iov_len -= sizeof(*hdr); + prev_datalen = msghdr->msg_iov[0].iov_len; + msghdr->msg_iov[0].iov_len = hdr->size; len = recvmsg(fd, msghdr, 0); /* restore just in case the user needs it */ msghdr->msg_iov[0].iov_base -= sizeof(*hdr); - msghdr->msg_iov[0].iov_len += sizeof(*hdr); + msghdr->msg_iov[0].iov_len = prev_datalen; msghdr->msg_control = hdr2.msg_control; msghdr->msg_controllen = hdr2.msg_controllen; + msghdr->msg_iovlen = prev_iovlen; + if (len < 0) return -errno; if (len == 0) @@ -831,7 +839,28 @@ void *usfstl_vhost_user_to_va(struct usfstl_vhost_user_dev *extdev, uint64_t add dev->regions[region].mmap_offset); } - USFSTL_ASSERT(0, "cannot translate address %"PRIx64"\n", addr); + USFSTL_ASSERT(0, "cannot translate user address %"PRIx64"\n", addr); + return NULL; +} + +void *usfstl_vhost_phys_to_va(struct usfstl_vhost_user_dev *extdev, uint64_t addr) +{ + struct usfstl_vhost_user_dev_int *dev; + unsigned int region; + + dev = container_of(extdev, struct usfstl_vhost_user_dev_int, ext); + + for (region = 0; region < dev->n_regions; region++) { + if (addr >= dev->regions[region].guest_phys_addr && + addr < dev->regions[region].guest_phys_addr + + dev->regions[region].size) + return (uint8_t *)dev->region_vaddr[region] + + (addr - + dev->regions[region].guest_phys_addr + + dev->regions[region].mmap_offset); + } + + USFSTL_ASSERT(0, "cannot translate physical address %"PRIx64"\n", addr); return NULL; } |