[RFC PATCH v2 5/5] vhost_user: Implement mem_read/mem_write handlers

Albert Esteve posted 5 patches 6 months ago
[RFC PATCH v2 5/5] vhost_user: Implement mem_read/mem_write handlers
Posted by Albert Esteve 6 months ago
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);
+
+    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
Re: [RFC PATCH v2 5/5] vhost_user: Implement mem_read/mem_write handlers
Posted by Stefan Hajnoczi 5 months, 2 weeks ago
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
>