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
>


Reply via email to