The vfio_memory_listener is registered for PCI address space. On Type1 IOMMU that falls back to @address_space_memory and the listener is called on RAM blocks. On sPAPR IOMMU is guest visible and the listener is called on DMA windows. Therefore Type1 IOMMU only handled RAM regions and sPAPR IOMMU only handled IOMMU regions.
With the memory preregistration, there is need to handle RAM regions in the listener for sPAPR IOMMU too. To make next patches simpler/nicer, this moves DMA mapping/unmapping code to a case in a switch. This should cause no change in behavior. Signed-off-by: Alexey Kardashevskiy <a...@ozlabs.ru> --- hw/vfio/common.c | 63 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/hw/vfio/common.c b/hw/vfio/common.c index 788c87a..77b5ab0 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/common.c @@ -397,26 +397,36 @@ static void vfio_listener_region_add(MemoryListener *listener, section->offset_within_region + (iova - section->offset_within_address_space); - trace_vfio_listener_region_add_ram(iova, end - 1, vaddr); + switch (container->iommu_data.type) { + case VFIO_TYPE1_IOMMU: + case VFIO_TYPE1v2_IOMMU: + trace_vfio_listener_region_add_ram(iova, end - 1, vaddr); - ret = vfio_dma_map(container, iova, end - iova, vaddr, section->readonly); - if (ret) { - error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx", %p) = %d (%m)", - container, iova, end - iova, vaddr, ret); + ret = vfio_dma_map(container, iova, end - iova, vaddr, section->readonly); + if (ret) { + error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", " + "0x%"HWADDR_PRIx", %p) = %d (%m)", + container, iova, end - iova, vaddr, ret); + goto error_exit; + } + break; + } + + return; + +error_exit: - /* - * On the initfn path, store the first error in the container so we - * can gracefully fail. Runtime, there's not much we can do other - * than throw a hardware error. - */ - if (!container->iommu_data.type1.initialized) { - if (!container->iommu_data.type1.error) { - container->iommu_data.type1.error = ret; - } - } else { - hw_error("vfio: DMA mapping failed, unable to continue"); + /* + * On the initfn path, store the first error in the container so we + * can gracefully fail. Runtime, there's not much we can do other + * than throw a hardware error. + */ + if (!container->iommu_data.type1.initialized) { + if (!container->iommu_data.type1.error) { + container->iommu_data.type1.error = ret; } + } else { + hw_error("vfio: DMA mapping failed, unable to continue"); } } @@ -474,14 +484,19 @@ static void vfio_listener_region_del(MemoryListener *listener, return; } - trace_vfio_listener_region_del(iova, end - 1); + switch (container->iommu_data.type) { + case VFIO_TYPE1_IOMMU: + case VFIO_TYPE1v2_IOMMU: + trace_vfio_listener_region_del(iova, end - 1); - ret = vfio_dma_unmap(container, iova, end - iova); - memory_region_unref(section->mr); - if (ret) { - error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%m)", - container, iova, end - iova, ret); + ret = vfio_dma_unmap(container, iova, end - iova); + memory_region_unref(section->mr); + if (ret) { + error_report("vfio_dma_unmap(%p, 0x%"HWADDR_PRIx", " + "0x%"HWADDR_PRIx") = %d (%m)", + container, iova, end - iova, ret); + } + break; } } -- 2.4.0.rc3.8.gfb3e7d5