Skip to content

Commit 4fafedc

Browse files
raphael-nutanixmstsirkin
authored andcommitted
libvhost-user: handle removal of identical regions
Today if QEMU (or any other VMM) has sent multiple copies of the same region to a libvhost-user based backend and then attempts to remove the region, only one instance of the region will be removed, leaving stale copies of the region in dev->regions[]. This change resolves this by having vu_rem_mem_reg() iterate through all regions in dev->regions[] and delete all matching regions. Suggested-by: Stefan Hajnoczi <[email protected]> Signed-off-by: Raphael Norwitz <[email protected]> Message-Id: <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Reviewed-by: David Hildenbrand <[email protected]>
1 parent b906a23 commit 4fafedc

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

subprojects/libvhost-user/libvhost-user.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,7 @@ static bool
821821
vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
822822
VhostUserMemoryRegion m = vmsg->payload.memreg.region, *msg_region = &m;
823823
int i;
824+
bool found = false;
824825

825826
if (vmsg->fd_num != 1) {
826827
vmsg_close_fds(vmsg);
@@ -856,21 +857,24 @@ vu_rem_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
856857
munmap(m, r->size + r->mmap_offset);
857858
}
858859

859-
break;
860+
/*
861+
* Shift all affected entries by 1 to close the hole at index i and
862+
* zero out the last entry.
863+
*/
864+
memmove(dev->regions + i, dev->regions + i + 1,
865+
sizeof(VuDevRegion) * (dev->nregions - i - 1));
866+
memset(dev->regions + dev->nregions - 1, 0, sizeof(VuDevRegion));
867+
DPRINT("Successfully removed a region\n");
868+
dev->nregions--;
869+
i--;
870+
871+
found = true;
872+
873+
/* Continue the search for eventual duplicates. */
860874
}
861875
}
862876

863-
if (i < dev->nregions) {
864-
/*
865-
* Shift all affected entries by 1 to close the hole at index i and
866-
* zero out the last entry.
867-
*/
868-
memmove(dev->regions + i, dev->regions + i + 1,
869-
sizeof(VuDevRegion) * (dev->nregions - i - 1));
870-
memset(dev->regions + dev->nregions - 1, 0,
871-
sizeof(VuDevRegion));
872-
DPRINT("Successfully removed a region\n");
873-
dev->nregions--;
877+
if (found) {
874878
vmsg_set_reply_u64(vmsg, 0);
875879
} else {
876880
vu_panic(dev, "Specified region not found\n");

0 commit comments

Comments
 (0)