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>