[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH for-2.5] vhost-user: don't merge regions where FDs differ,
Michael S. Tsirkin <=