On Fri, Jun 28, 2024 at 04:57:10PM +0200, Albert Esteve wrote:
> Implement function handlers for memory read and write
> operations.
>
> Signed-off-by: Albert Esteve <aesteve@redhat.com>
> ---
> hw/virtio/vhost-user.c | 34 ++++++++++++++++++++++++++++++----
> 1 file changed, 30 insertions(+), 4 deletions(-)
>
> diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
> index 18cacb2d68..79becbc87b 100644
> --- a/hw/virtio/vhost-user.c
> +++ b/hw/virtio/vhost-user.c
> @@ -1884,16 +1884,42 @@ static int
> vhost_user_backend_handle_mem_read(struct vhost_dev *dev,
> VhostUserMemRWMsg *mem_rw)
> {
> - /* TODO */
> - return -EPERM;
> + ram_addr_t offset;
> + int fd;
> + MemoryRegion *mr;
> +
> + mr = vhost_user_get_mr_data(mem_rw->guest_address, &offset, &fd);
> +
> + if (!mr) {
> + error_report("Failed to get memory region with address %" PRIx64,
> + mem_rw->guest_address);
> + return -EFAULT;
> + }
> +
> + memcpy(mem_rw->data, memory_region_get_ram_ptr(mr) + offset, mem_rw->size);
Don't try to write this from scratch. Use address_space_read/write(). It
supports corner cases like crossing MemoryRegions.
> +
> + return 0;
> }
>
> static int
> vhost_user_backend_handle_mem_write(struct vhost_dev *dev,
> VhostUserMemRWMsg *mem_rw)
> {
> - /* TODO */
> - return -EPERM;
> + ram_addr_t offset;
> + int fd;
> + MemoryRegion *mr;
> +
> + mr = vhost_user_get_mr_data(mem_rw->guest_address, &offset, &fd);
> +
> + if (!mr) {
> + error_report("Failed to get memory region with address %" PRIx64,
> + mem_rw->guest_address);
> + return -EFAULT;
> + }
> +
> + memcpy(memory_region_get_ram_ptr(mr) + offset, mem_rw->data, mem_rw->size);
> +
> + return 0;
> }
>
> static void close_backend_channel(struct vhost_user *u)
> --
> 2.45.2
>