@@ -221,10 +221,8 @@ static int vfio_dma_unmap(VFIOContainer *container,
* @iova: base IOVA of the MSI region
* @size: size of the MSI IOVA region
*/
-int vfio_register_msi_iova(VFIOContainer *container, hwaddr iova,
- ram_addr_t size);
-int vfio_register_msi_iova(VFIOContainer *container, hwaddr iova,
- ram_addr_t size)
+static int vfio_register_msi_iova(VFIOContainer *container, hwaddr iova,
+ ram_addr_t size)
{
int ret;
struct vfio_iommu_type1_dma_map map = {
@@ -313,6 +311,7 @@ static int vfio_host_win_del(VFIOContainer *container, hwaddr min_iova,
static bool vfio_listener_skipped_section(MemoryRegionSection *section)
{
return (!memory_region_is_ram(section->mr) &&
+ !memory_region_is_reserved_iova(section->mr) &&
!memory_region_is_iommu(section->mr)) ||
/*
* Sizing an enabled 64-bit BAR can cause spurious mappings to
@@ -396,7 +395,7 @@ static void vfio_listener_region_add(MemoryListener *listener,
hwaddr iova, end;
Int128 llend, llsize;
void *vaddr;
- int ret;
+ int ret = -1;
VFIOHostDMAWindow *hostwin;
bool hostwin_found;
@@ -492,27 +491,38 @@ static void vfio_listener_region_add(MemoryListener *listener,
return;
}
- /* Here we assume that memory_region_is_ram(section->mr)==true */
+ /* Here we assume that the memory region is ram or reserved iova */
- vaddr = memory_region_get_ram_ptr(section->mr) +
- section->offset_within_region +
- (iova - section->offset_within_address_space);
+ if (memory_region_is_ram(section->mr)) {
+ vaddr = memory_region_get_ram_ptr(section->mr) +
+ section->offset_within_region +
+ (iova - section->offset_within_address_space);
- trace_vfio_listener_region_add_ram(iova, end, vaddr);
+ trace_vfio_listener_region_add_ram(iova, end, vaddr);
- llsize = int128_sub(llend, int128_make64(iova));
+ llsize = int128_sub(llend, int128_make64(iova));
- ret = vfio_dma_map(container, iova, int128_get64(llsize),
+ ret = vfio_dma_map(container, iova, int128_get64(llsize),
vaddr, section->readonly);
- if (ret) {
- error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
- "0x%"HWADDR_PRIx", %p) = %d (%m)",
- container, iova, int128_get64(llsize), vaddr, ret);
- goto fail;
+ if (ret) {
+ error_report("vfio_dma_map(%p, 0x%"HWADDR_PRIx", "
+ "0x%"HWADDR_PRIx", %p) = %d (%m)",
+ container, iova, int128_get64(llsize), vaddr, ret);
+ goto fail;
+ }
+ return;
+ } else if (memory_region_is_reserved_iova(section->mr)) {
+ llsize = int128_sub(llend, int128_make64(iova));
+ ret = vfio_register_msi_iova(container, iova, int128_get64(llsize));
+ if (ret) {
+ error_report("vfio_register_msi_iova(%p, 0x%"HWADDR_PRIx", "
+ "0x%"HWADDR_PRIx") = %d (%m)",
+ container, iova, int128_get64(llsize), ret);
+ goto fail;
+ }
+ return;
}
- return;
-
fail:
/*
* On the initfn path, store the first error in the container so we
In case of reserved iova region, let's declare this region to the kernel so that it can use it for IOVA/HPA bindings. Signed-off-by: Eric Auger <eric.auger@redhat.com> --- hw/vfio/common.c | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-)