qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH for-2.5] vhost-user: don't merge regions where FDs d


From: Michael S. Tsirkin
Subject: [Qemu-devel] [PATCH for-2.5] vhost-user: don't merge regions where FDs differ
Date: Tue, 1 Dec 2015 18:28:53 +0200

vhost would happily merge regions where userspace addresses happen to
match.  This breaks vhost-user as these are mapped from unrelated FDs.
Check the backend before merging regions.

Reported-by: Victor Kaplansky <address@hidden>
Signed-off-by: Michael S. Tsirkin <address@hidden>
---
 hw/virtio/vhost.c | 79 ++++++++++++++++++++++++++++++-------------------------
 1 file changed, 43 insertions(+), 36 deletions(-)

diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index de29968..44e0199 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -233,45 +233,52 @@ static void vhost_dev_assign_memory(struct vhost_dev *dev,
                                     uint64_t size,
                                     uint64_t uaddr)
 {
-    int from, to;
+    int to;
     struct vhost_memory_region *merged = NULL;
-    for (from = 0, to = 0; from < dev->mem->nregions; ++from, ++to) {
-        struct vhost_memory_region *reg = dev->mem->regions + to;
-        uint64_t prlast, urlast;
-        uint64_t pmlast, umlast;
-        uint64_t s, e, u;
 
-        /* clone old region */
-        if (to != from) {
-            memcpy(reg, dev->mem->regions + from, sizeof *reg);
-        }
-        prlast = range_get_last(reg->guest_phys_addr, reg->memory_size);
-        pmlast = range_get_last(start_addr, size);
-        urlast = range_get_last(reg->userspace_addr, reg->memory_size);
-        umlast = range_get_last(uaddr, size);
-
-        /* check for overlapping regions: should never happen. */
-        assert(prlast < start_addr || pmlast < reg->guest_phys_addr);
-        /* Not an adjacent or overlapping region - do not merge. */
-        if ((prlast + 1 != start_addr || urlast + 1 != uaddr) &&
-            (pmlast + 1 != reg->guest_phys_addr ||
-             umlast + 1 != reg->userspace_addr)) {
-            continue;
-        }
-
-        if (merged) {
-            --to;
-            assert(to >= 0);
-        } else {
-            merged = reg;
+    if (dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER) {
+        to = dev->mem->nregions;
+    } else {
+        int from;
+
+        for (from = 0, to = 0; from < dev->mem->nregions; ++from, ++to) {
+            struct vhost_memory_region *reg = dev->mem->regions + to;
+            uint64_t prlast, urlast;
+            uint64_t pmlast, umlast;
+            uint64_t s, e, u;
+
+            /* clone old region */
+            if (to != from) {
+                memcpy(reg, dev->mem->regions + from, sizeof *reg);
+            }
+            prlast = range_get_last(reg->guest_phys_addr, reg->memory_size);
+            pmlast = range_get_last(start_addr, size);
+            urlast = range_get_last(reg->userspace_addr, reg->memory_size);
+            umlast = range_get_last(uaddr, size);
+
+            /* check for overlapping regions: should never happen. */
+            assert(prlast < start_addr || pmlast < reg->guest_phys_addr);
+            /* Not an adjacent or overlapping region - do not merge. */
+            if ((prlast + 1 != start_addr || urlast + 1 != uaddr) &&
+                (pmlast + 1 != reg->guest_phys_addr ||
+                 umlast + 1 != reg->userspace_addr)) {
+                continue;
+            }
+
+            if (merged) {
+                --to;
+                assert(to >= 0);
+            } else {
+                merged = reg;
+            }
+            u = MIN(uaddr, reg->userspace_addr);
+            s = MIN(start_addr, reg->guest_phys_addr);
+            e = MAX(pmlast, prlast);
+            uaddr = merged->userspace_addr = u;
+            start_addr = merged->guest_phys_addr = s;
+            size = merged->memory_size = e - s + 1;
+            assert(merged->memory_size);
         }
-        u = MIN(uaddr, reg->userspace_addr);
-        s = MIN(start_addr, reg->guest_phys_addr);
-        e = MAX(pmlast, prlast);
-        uaddr = merged->userspace_addr = u;
-        start_addr = merged->guest_phys_addr = s;
-        size = merged->memory_size = e - s + 1;
-        assert(merged->memory_size);
     }
 
     if (!merged) {
-- 
MST



reply via email to

[Prev in Thread] Current Thread [Next in Thread]