On Thu, 14 Aug 2025 17:34:19 +0200
Cédric Le Goater <c...@redhat.com> wrote:

> The VFIO IOMMU Type1 kernel driver enforces a default IOMMU mapping
> limit of 65535, which is configurable via the 'dma_max_mappings'
> module parameter. When this limit is reached, QEMU issues a warning
> and fails the mapping operation, but allows the VM to continue
> running, potentially causing issues later. This scenario occurs with
> SEV-SNP guests, which must update all IOMMU mappings during
> initialization.
> 
> To address this, update vfio_ram_discard_register_listener() to accept
> an 'Error **' parameter and propagate the error to the caller. This
> change will halt the VM immediately, at init time, with the same error
> message.
> 
> Additionally, the same behavior will be enforced at runtime. While
> this might be considered too brutal, the rarity of this case and the
> planned removal of the dma_max_mappings module parameter make it a
> reasonable approach.
> 
> Cc: Alex Williamson <alex.william...@redhat.com>
> Signed-off-by: Cédric Le Goater <c...@redhat.com>
> ---
>  hw/vfio/listener.c | 13 +++++++++----
>  1 file changed, 9 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/vfio/listener.c b/hw/vfio/listener.c
> index 
> 184c15e05fcb388cf0848e97e1eb283f17a50ad4..bc40ec8613c71a12b8c0dfdea497a14a446ac1fd
>  100644
> --- a/hw/vfio/listener.c
> +++ b/hw/vfio/listener.c
> @@ -250,8 +250,9 @@ int vfio_ram_discard_notify_populate(RamDiscardListener 
> *rdl,
>      return 0;
>  }
>  
> -static void vfio_ram_discard_register_listener(VFIOContainerBase *bcontainer,
> -                                               MemoryRegionSection *section)
> +static bool vfio_ram_discard_register_listener(VFIOContainerBase *bcontainer,
> +                                               MemoryRegionSection *section,
> +                                               Error **errp)
>  {
>      RamDiscardManager *rdm = 
> memory_region_get_ram_discard_manager(section->mr);
>      int target_page_size = qemu_target_page_size();
> @@ -316,13 +317,15 @@ static void 
> vfio_ram_discard_register_listener(VFIOContainerBase *bcontainer,
>  
>          if (vrdl_mappings + max_memslots - vrdl_count >
>              bcontainer->dma_max_mappings) {
> -            warn_report("%s: possibly running out of DMA mappings. E.g., try"
> +            error_setg(errp, "%s: possibly running out of DMA mappings. 
> E.g., try"
>                          " increasing the 'block-size' of virtio-mem devies."
>                          " Maximum possible DMA mappings: %d, Maximum 
> possible"
>                          " memslots: %d", __func__, 
> bcontainer->dma_max_mappings,
>                          max_memslots);
> +            return false;
>          }
>      }
> +    return true;
>  }
>  
>  static void vfio_ram_discard_unregister_listener(VFIOContainerBase 
> *bcontainer,
> @@ -576,7 +579,9 @@ void vfio_container_region_add(VFIOContainerBase 
> *bcontainer,
>       */
>      if (memory_region_has_ram_discard_manager(section->mr)) {
>          if (!cpr_remap) {
> -            vfio_ram_discard_register_listener(bcontainer, section);
> +            if (!vfio_ram_discard_register_listener(bcontainer, section, 
> &err)) {
> +                goto fail;
> +            }
>          } else if (!vfio_cpr_ram_discard_replay_populated(bcontainer,
>                                                             section)) {
>              error_setg(&err,

LGTM

Reviewed-by: Alex Williamson <alex.william...@redhat.com>


Reply via email to