From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53400) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3nnX-0005LC-Vc for qemu-devel@nongnu.org; Tue, 01 Dec 2015 11:29:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a3nnU-0000pL-Fu for qemu-devel@nongnu.org; Tue, 01 Dec 2015 11:28:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34755) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3nnU-0000ox-8u for qemu-devel@nongnu.org; Tue, 01 Dec 2015 11:28:56 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 09C7231A0FE for ; Tue, 1 Dec 2015 16:28:56 +0000 (UTC) Date: Tue, 1 Dec 2015 18:28:53 +0200 From: "Michael S. Tsirkin" Message-ID: <1448987302-30676-1-git-send-email-mst@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH for-2.5] vhost-user: don't merge regions where FDs differ List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Victor Kaplansky 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 Signed-off-by: Michael S. Tsirkin --- 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