cpr.saved_dma_map isn't initialized in source qemu which lead to vioc->dma_map assigned a NULL value, this will trigger SIGSEGV.
Fix it by save and restore vioc->dma_map locally. Fixes: eba1f657cbb1 ("vfio/container: recover from unmap-all-vaddr failure") Signed-off-by: Zhenzhong Duan <zhenzhong.d...@intel.com> --- include/hw/vfio/vfio-cpr.h | 8 +++++--- hw/vfio/cpr-legacy.c | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/include/hw/vfio/vfio-cpr.h b/include/hw/vfio/vfio-cpr.h index 8bf85b9f4e..aef542e93c 100644 --- a/include/hw/vfio/vfio-cpr.h +++ b/include/hw/vfio/vfio-cpr.h @@ -16,14 +16,16 @@ struct VFIOContainer; struct VFIOContainerBase; struct VFIOGroup; +typedef int (*DMA_MAP_FUNC)(const struct VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, void *vaddr, + bool readonly, MemoryRegion *mr); + typedef struct VFIOContainerCPR { Error *blocker; bool vaddr_unmapped; NotifierWithReturn transfer_notifier; MemoryListener remap_listener; - int (*saved_dma_map)(const struct VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly, MemoryRegion *mr); + DMA_MAP_FUNC saved_dma_map; } VFIOContainerCPR; typedef struct VFIODeviceCPR { diff --git a/hw/vfio/cpr-legacy.c b/hw/vfio/cpr-legacy.c index a84c3247b7..100a8db74d 100644 --- a/hw/vfio/cpr-legacy.c +++ b/hw/vfio/cpr-legacy.c @@ -148,6 +148,7 @@ static int vfio_cpr_fail_notifier(NotifierWithReturn *notifier, */ VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); + DMA_MAP_FUNC saved_dma_map = vioc->dma_map; vioc->dma_map = vfio_legacy_cpr_dma_map; container->cpr.remap_listener = (MemoryListener) { @@ -158,7 +159,7 @@ static int vfio_cpr_fail_notifier(NotifierWithReturn *notifier, bcontainer->space->as); memory_listener_unregister(&container->cpr.remap_listener); container->cpr.vaddr_unmapped = false; - vioc->dma_map = container->cpr.saved_dma_map; + vioc->dma_map = saved_dma_map; } return 0; } -- 2.34.1