};
if (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) {
- error_report("VFIO_UNMAP_DMA: %d\n", -errno);
+ error_report("VFIO_UNMAP_DMA: %d", -errno);
return -errno;
}
/*
* Try the mapping, if it fails with EBUSY, unmap the region and try
* again. This shouldn't be necessary, but we sometimes see it in
- * the the VGA ROM space.
+ * the VGA ROM space.
*/
if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 ||
(errno == EBUSY && vfio_dma_unmap(container, iova, size) == 0 &&
return 0;
}
- error_report("VFIO_MAP_DMA: %d\n", -errno);
+ error_report("VFIO_MAP_DMA: %d", -errno);
return -errno;
}
* this IOMMU to its immediate target. We need to translate
* it the rest of the way through to memory.
*/
+ rcu_read_lock();
mr = address_space_translate(&address_space_memory,
iotlb->translated_addr,
&xlat, &len, iotlb->perm & IOMMU_WO);
if (!memory_region_is_ram(mr)) {
- error_report("iommu map to non memory area %"HWADDR_PRIx"\n",
+ error_report("iommu map to non memory area %"HWADDR_PRIx"",
xlat);
- return;
+ goto out;
}
/*
* Translation truncates length to the IOMMU page size,
* check that it did not truncate too much.
*/
if (len & iotlb->addr_mask) {
- error_report("iommu has granularity incompatible with target AS\n");
- return;
+ error_report("iommu has granularity incompatible with target AS");
+ goto out;
}
if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) {
iotlb->addr_mask + 1, ret);
}
}
+out:
+ rcu_read_unlock();
}
static void vfio_listener_region_add(MemoryListener *listener,
int ret = 0;
VFIODevice *vbasedev = region->vbasedev;
- if (vbasedev->allow_mmap && size && region->flags &
+ if (!vbasedev->no_mmap && size && region->flags &
VFIO_REGION_INFO_FLAG_MMAP) {
int prot = 0;
};
if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) {
- error_report("Failed to create KVM VFIO device: %m\n");
+ error_report("Failed to create KVM VFIO device: %m");
return;
}
if (QLIST_EMPTY(&container->group_list)) {
VFIOAddressSpace *space = container->space;
+ VFIOGuestIOMMU *giommu, *tmp;
if (container->iommu_data.release) {
container->iommu_data.release(container);
}
QLIST_REMOVE(container, next);
+
+ QLIST_FOREACH_SAFE(giommu, &container->giommu_list, giommu_next, tmp) {
+ memory_region_unregister_iommu_notifier(&giommu->n);
+ QLIST_REMOVE(giommu, giommu_next);
+ g_free(giommu);
+ }
+
trace_vfio_disconnect_container(container->fd);
close(container->fd);
g_free(container);
switch (req) {
case VFIO_CHECK_EXTENSION:
case VFIO_IOMMU_SPAPR_TCE_GET_INFO:
+ case VFIO_EEH_PE_OP:
break;
default:
/* Return an error on unknown requests */