From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47635) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X0Uhm-0003LX-7I for qemu-devel@nongnu.org; Fri, 27 Jun 2014 07:52:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X0Uhe-00084k-NX for qemu-devel@nongnu.org; Fri, 27 Jun 2014 07:52:34 -0400 From: Alexander Graf Date: Fri, 27 Jun 2014 13:52:04 +0200 Message-Id: <1403869944-31927-13-git-send-email-agraf@suse.de> In-Reply-To: <1403869944-31927-1-git-send-email-agraf@suse.de> References: <1403869944-31927-1-git-send-email-agraf@suse.de> Subject: [Qemu-devel] [PULL 12/32] vfio: Enable for SPAPR List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-ppc@nongnu.org Cc: Alexey Kardashevskiy , peter.maydell@linaro.org, qemu-devel@nongnu.org From: Alexey Kardashevskiy This turns the sPAPR support on and enables VFIO container use in the kernel. This extends vfio_connect_container to support VFIO_SPAPR_TCE_IOMMU type in the host kernel. This registers a memory listener which sPAPR IOMMU will notify when executing H_PUT_TCE/etc DMA calls. The listener then will notify the host kernel about DMA map/unmap operation via VFIO_IOMMU_MAP_DMA/ VFIO_IOMMU_UNMAP_DMA ioctls. This executes VFIO_IOMMU_ENABLE ioctl to make sure that the IOMMU is free of mappings and can be exclusively given to the user. At the moment SPAPR is the only platform requiring this call to be implemented. Note that the host kernel function implementing VFIO_IOMMU_DISABLE is called automatically when container's fd is closed so there is no need to call it explicitly from QEMU. We may need to call VFIO_IOMMU_DISABLE explicitly in the future for some sort of dynamic reconfiguration (PCI hotplug or dynamic IOMMU group management). Signed-off-by: Alexey Kardashevskiy Acked-by: Alex Williamson Signed-off-by: Alexander Graf --- hw/misc/vfio.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c index bdd6e33..7b279c4 100644 --- a/hw/misc/vfio.c +++ b/hw/misc/vfio.c @@ -3650,6 +3650,39 @@ static int vfio_connect_container(VFIOGroup *group, AddressSpace *as) container->iommu_data.type1.initialized = true; + } else if (ioctl(fd, VFIO_CHECK_EXTENSION, VFIO_SPAPR_TCE_IOMMU)) { + ret = ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &fd); + if (ret) { + error_report("vfio: failed to set group container: %m"); + ret = -errno; + goto free_container_exit; + } + + ret = ioctl(fd, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU); + if (ret) { + error_report("vfio: failed to set iommu for container: %m"); + ret = -errno; + goto free_container_exit; + } + + /* + * The host kernel code implementing VFIO_IOMMU_DISABLE is called + * when container fd is closed so we do not call it explicitly + * in this file. + */ + ret = ioctl(fd, VFIO_IOMMU_ENABLE); + if (ret) { + error_report("vfio: failed to enable container: %m"); + ret = -errno; + goto free_container_exit; + } + + container->iommu_data.type1.listener = vfio_memory_listener; + container->iommu_data.release = vfio_listener_release; + + memory_listener_register(&container->iommu_data.type1.listener, + container->space->as); + } else { error_report("vfio: No available IOMMU models"); ret = -EINVAL; @@ -4352,6 +4385,9 @@ int vfio_container_ioctl(AddressSpace *as, int32_t groupid, { /* We allow only certain ioctls to the container */ switch (req) { + case VFIO_CHECK_EXTENSION: + case VFIO_IOMMU_SPAPR_TCE_GET_INFO: + break; default: /* Return an error on unknown requests */ error_report("vfio: unsupported ioctl %X", req); -- 1.8.1.4