On Sat, Aug 15, 2026 at 6:15 AM Feifan Qian <[email protected]> wrote: > > Each SHMEM_MAP request creates a separate RAM MemoryRegion that > consumes a KVM memory slot. Once all KVM slots are in use, processing > another SHMEM_MAP request would make the KVM memory listener fail while > registering the new region. > > Shared memory mappings are filtered out of the vhost memory table > (vhost_section() skips TYPE_VIRTIO_SHARED_MEMORY_MAPPING regions), so > they never count against the negotiated vhost-user slot limit; only > the KVM slot budget applies. Reject the request with ENOSPC before > changing the memory topology when KVM has no free slot left. > > Also validate each vhost memory table against the slot limit negotiated > with the backend before sending regions via SET_MEM_TABLE or > ADD_MEM_REG. > > Fixes: b52e1896e764 ("vhost-user: Add VirtIO Shared Memory map request") > Signed-off-by: Feifan Qian <[email protected]> > --- > Based-on: <[email protected]> > ("vhost-user-gpu: Add blob resource and shared memory support" v4, > which filters TYPE_VIRTIO_SHARED_MEMORY_MAPPING regions out of > vhost_section())
Reviewed-by: Albert Esteve <[email protected]> Thanks! > > v3: > - Rebased on Dorinda's series as suggested by Albert. > - SHMEM_MAP path now checks kvm_get_free_memslots() only; shmem > mappings no longer reach SET_MEM_TABLE/ADD_MEM_REG, so the precheck > no longer calls vhost_get_free_memslots() or uses reserved_memslots. > - Kept the set_mem_table check as a safety net for ADD_MEM_REG. > > Tested with an ASan/UBSan x86_64 build on top of the base series. > qtest-x86_64/qos-test passed all 141 subtests. > > hw/virtio/vhost-user.c | 18 ++++++++++++++++++ > 1 file changed, 18 insertions(+) > > diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c > index fac02a1ffc..f737a05d07 100644 > --- a/hw/virtio/vhost-user.c > +++ b/hw/virtio/vhost-user.c > @@ -1126,6 +1126,13 @@ static int vhost_user_set_mem_table(struct vhost_dev > *dev, > dev, VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS); > int ret; > > + if (mem->nregions > u->user->memory_slots) { > + error_report("vhost-user memory table has %u regions, " > + "but the backend supports only %d", > + mem->nregions, u->user->memory_slots); > + return -ENOSPC; > + } > + > if (do_postcopy) { > /* > * Postcopy has enough differences that it's best done in it's own > @@ -1980,6 +1987,17 @@ vhost_user_backend_handle_shmem_map(struct vhost_dev > *dev, > } > } > > + /* > + * Each SHMEM mapping becomes a separate RAM MemoryRegion and thus > + * consumes a KVM memory slot. Reject the request before changing the > + * memory topology if no slot is left. > + */ > + if (kvm_enabled() && !kvm_get_free_memslots()) { > + error_report("No free KVM memory slots for shared memory mapping"); > + ret = -ENOSPC; > + goto send_reply; > + } > + > /* Create VirtioSharedMemoryMapping object */ > VirtioSharedMemoryMapping *mapping = virtio_shared_memory_mapping_new( > vu_mmap->shmid, fd, vu_mmap->fd_offset, vu_mmap->shm_offset, > -- > 2.43.0 >
