Skip to contentSkip to conversation

vhost-user fixes

PATCH In review Nikolay Nikolaev 2 participants 5 messages Jul 12, 2014

lore
Share & tools
lore
#0 lore raw

v2 cover vhost-user fixes

The latest vhost-user changes changed the VHOST_SET_MEM_TABLE handling. Now the memory regions are mapped from dev->mem. There is an error when calling qemu_get_ram_fd with reg->guest_phys_addr. The right approach is to find the ram_addr_t corresponding to the userspace_addr using qemu_ram_addr_from_host first.

Thanks to Paolo Bonzini for poinitng the real problem.

The related vhost-user qtest is also updated to reflect the changes in vhost-user message structures.

Changes since v1:
- dropped the patches 1 and 2 and just fixed the "real issue"

---

Nikolay Nikolaev (2):
vhost-user: Fix VHOST_SET_MEM_TABLE processing
qtest: Adapt vhost-user-test to latehs vhost-user changes

 hw/virtio/vhost-user.c  |    4 +++-
 tests/vhost-user-test.c |   11 +++++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

--
Signature

#1 lore raw

PATCH v2 1/2 vhost-user: Fix VHOST_SET_MEM_TABLE processing

qemu_get_ram_fd doesn't accept a guest physical address. ram_addr_t are opaque values that are assigned in qemu_ram_alloc.

Find the ram_addr_t corresponding to the userspace_addr using qemu_ram_addr_from_host, and then call qemu_get_ram_fd on it.

Thanks to Paolo Bonzini <[email protected]>

---
 hw/virtio/vhost-user.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
hw/virtio/vhost-user.c +3 -1
index 38e5806..d610aa4 100644
@@ -216,7 +216,9 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
     case VHOST_SET_MEM_TABLE:
         for (i = 0; i < dev->mem->nregions; ++i) {
             struct vhost_memory_region *reg = dev->mem->regions + i;
-            fd = qemu_get_ram_fd(reg->guest_phys_addr);
+            ram_addr_t ram_addr;
+            qemu_ram_addr_from_host((void*)reg->userspace_addr, &ram_addr);
+            fd = qemu_get_ram_fd(ram_addr);
             if (fd > 0) {
                 msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
                 msg.memory.regions[fd_num].memory_size  = reg->memory_size;
Reviewed-by on v2 1/2
#2 lore raw

Re: [Qemu-devel] [PATCH v2 1/2 for-2.1] vhost-user: Fix VHOST_SET_MEM_TABLE processing

Il 12/07/2014 03:42, Nikolay Nikolaev ha scritto:

Quoted 19 lines

qemu_get_ram_fd doesn't accept a guest physical address. ram_addr_t are opaque values that are assigned in qemu_ram_alloc.

Find the ram_addr_t corresponding to the userspace_addr using qemu_ram_addr_from_host, and then call qemu_get_ram_fd on it.

Thanks to Paolo Bonzini <[email protected]>

---
 hw/virtio/vhost-user.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
hw/virtio/vhost-user.c +0 -0
index 38e5806..d610aa4 100644

hw/virtio/vhost-user.c static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, · line 224

Quoted 10 lines
hw/virtio/vhost-user.c +3 -1
@@ -216,7 +216,9 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
     case VHOST_SET_MEM_TABLE:
         for (i = 0; i < dev->mem->nregions; ++i) {
             struct vhost_memory_region *reg = dev->mem->regions + i;
-            fd = qemu_get_ram_fd(reg->guest_phys_addr);
+            ram_addr_t ram_addr;
+            qemu_ram_addr_from_host((void*)reg->userspace_addr, &ram_addr);
+            fd = qemu_get_ram_fd(ram_addr);
             if (fd > 0) {
                 msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
                 msg.memory.regions[fd_num].memory_size  = reg->memory_size;
#3 lore raw

Re: [Qemu-devel] [PATCH v2 1/2 for-2.1] vhost-user: Fix VHOST_SET_MEM_TABLE processing

In reply to Nikolay Nikolaev
Quoted 19 lines · Nikolay Nikolaev

qemu_get_ram_fd doesn't accept a guest physical address. ram_addr_t are opaque values that are assigned in qemu_ram_alloc.

Find the ram_addr_t corresponding to the userspace_addr using qemu_ram_addr_from_host, and then call qemu_get_ram_fd on it.

Thanks to Paolo Bonzini <[email protected]>

---
 hw/virtio/vhost-user.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
hw/virtio/vhost-user.c +0 -0
index 38e5806..d610aa4 100644

hw/virtio/vhost-user.c static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, · line 220

Quoted 6 lines
hw/virtio/vhost-user.c +2 -1
@@ -216,7 +216,9 @@ static int vhost_user_call(struct vhost_dev *dev, unsigned long int request,
     case VHOST_SET_MEM_TABLE:
         for (i = 0; i < dev->mem->nregions; ++i) {
             struct vhost_memory_region *reg = dev->mem->regions + i;
-            fd = qemu_get_ram_fd(reg->guest_phys_addr);
+            ram_addr_t ram_addr;
+            qemu_ram_addr_from_host((void*)reg->userspace_addr, &ram_addr);

Forgot to checkpatch. Should have space after the void - (void *).

Michael, should I resend it?

Quoted 5 lines
hw/virtio/vhost-user.c +1 -0
+            fd = qemu_get_ram_fd(ram_addr);
             if (fd > 0) {
                 msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr;
                 msg.memory.regions[fd_num].memory_size  = reg->memory_size;
#4 lore raw

PATCH v2 2/2 qtest: Adapt vhost-user-test to latehs vhost-user changes

In reply to Nikolay Nikolaev

A new field mmap_offset was added in the vhost-user message, we need to reflect this change in the test too.

---
 tests/vhost-user-test.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
tests/vhost-user-test.c +9 -2
index 406ba70..75fedf0 100644
@@ -76,6 +76,7 @@ typedef struct VhostUserMemoryRegion {
     uint64_t guest_phys_addr;
     uint64_t memory_size;
     uint64_t userspace_addr;
+    uint64_t mmap_offset;
 } VhostUserMemoryRegion;
 
 typedef struct VhostUserMemory {
@@ -205,6 +206,7 @@ static void read_guest_mem(void)
     uint32_t *guest_mem;
     gint64 end_time;
     int i, j;
+    size_t size;
 
     g_mutex_lock(data_mutex);
 
@@ -231,8 +233,13 @@ static void read_guest_mem(void)
 
         g_assert_cmpint(memory.regions[i].memory_size, >, 1024);
 
-        guest_mem = mmap(0, memory.regions[i].memory_size,
-        PROT_READ | PROT_WRITE, MAP_SHARED, fds[i], 0);
+        size =  memory.regions[i].memory_size + memory.regions[i].mmap_offset;
+
+        guest_mem = mmap(0, size, PROT_READ | PROT_WRITE,
+                         MAP_SHARED, fds[i], 0);
+
+        g_assert(guest_mem != MAP_FAILED);
+        guest_mem += (memory.regions[i].mmap_offset / sizeof(*guest_mem));
 
         for (j = 0; j < 256; j++) {
             uint32_t a = readl(memory.regions[i].guest_phys_addr + j*4);