Skip to content

Commit

Permalink
powerpc/vfio: Implement IOMMU driver for VFIO
Browse files Browse the repository at this point in the history
VFIO implements platform independent stuff such as
a PCI driver, BAR access (via read/write on a file descriptor
or direct mapping when possible) and IRQ signaling.

The platform dependent part includes IOMMU initialization
and handling.  This implements an IOMMU driver for VFIO
which does mapping/unmapping pages for the guest IO and
provides information about DMA window (required by a POWER
guest).

Cc: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Alexey Kardashevskiy authored and Benjamin Herrenschmidt committed Jun 20, 2013
1 parent 4e13c1a commit 5ffd229
Show file tree
Hide file tree
Showing 6 changed files with 482 additions and 0 deletions.
63 changes: 63 additions & 0 deletions Documentation/vfio.txt
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,69 @@ a direct pass through for VFIO_DEVICE_* ioctls. The read/write/mmap
interfaces implement the device region access defined by the device's
own VFIO_DEVICE_GET_REGION_INFO ioctl.


PPC64 sPAPR implementation note
-------------------------------------------------------------------------------

This implementation has some specifics:

1) Only one IOMMU group per container is supported as an IOMMU group
represents the minimal entity which isolation can be guaranteed for and
groups are allocated statically, one per a Partitionable Endpoint (PE)
(PE is often a PCI domain but not always).

2) The hardware supports so called DMA windows - the PCI address range
within which DMA transfer is allowed, any attempt to access address space
out of the window leads to the whole PE isolation.

3) PPC64 guests are paravirtualized but not fully emulated. There is an API
to map/unmap pages for DMA, and it normally maps 1..32 pages per call and
currently there is no way to reduce the number of calls. In order to make things
faster, the map/unmap handling has been implemented in real mode which provides
an excellent performance which has limitations such as inability to do
locked pages accounting in real time.

So 3 additional ioctls have been added:

VFIO_IOMMU_SPAPR_TCE_GET_INFO - returns the size and the start
of the DMA window on the PCI bus.

VFIO_IOMMU_ENABLE - enables the container. The locked pages accounting
is done at this point. This lets user first to know what
the DMA window is and adjust rlimit before doing any real job.

VFIO_IOMMU_DISABLE - disables the container.


The code flow from the example above should be slightly changed:

.....
/* Add the group to the container */
ioctl(group, VFIO_GROUP_SET_CONTAINER, &container);

/* Enable the IOMMU model we want */
ioctl(container, VFIO_SET_IOMMU, VFIO_SPAPR_TCE_IOMMU)

/* Get addition sPAPR IOMMU info */
vfio_iommu_spapr_tce_info spapr_iommu_info;
ioctl(container, VFIO_IOMMU_SPAPR_TCE_GET_INFO, &spapr_iommu_info);

if (ioctl(container, VFIO_IOMMU_ENABLE))
/* Cannot enable container, may be low rlimit */

/* Allocate some space and setup a DMA mapping */
dma_map.vaddr = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

dma_map.size = 1024 * 1024;
dma_map.iova = 0; /* 1MB starting at 0x0 from device view */
dma_map.flags = VFIO_DMA_MAP_FLAG_READ | VFIO_DMA_MAP_FLAG_WRITE;

/* Check here is .iova/.size are within DMA window from spapr_iommu_info */

ioctl(container, VFIO_IOMMU_MAP_DMA, &dma_map);
.....

-------------------------------------------------------------------------------

[1] VFIO was originally an acronym for "Virtual Function I/O" in its
Expand Down
6 changes: 6 additions & 0 deletions drivers/vfio/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ config VFIO_IOMMU_TYPE1
depends on VFIO
default n

config VFIO_IOMMU_SPAPR_TCE
tristate
depends on VFIO && SPAPR_TCE_IOMMU
default n

menuconfig VFIO
tristate "VFIO Non-Privileged userspace driver framework"
depends on IOMMU_API
select VFIO_IOMMU_TYPE1 if X86
select VFIO_IOMMU_SPAPR_TCE if PPC_POWERNV
help
VFIO provides a framework for secure userspace device drivers.
See Documentation/vfio.txt for more details.
Expand Down
1 change: 1 addition & 0 deletions drivers/vfio/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
obj-$(CONFIG_VFIO) += vfio.o
obj-$(CONFIG_VFIO_IOMMU_TYPE1) += vfio_iommu_type1.o
obj-$(CONFIG_VFIO_IOMMU_SPAPR_TCE) += vfio_iommu_spapr_tce.o
obj-$(CONFIG_VFIO_PCI) += pci/
1 change: 1 addition & 0 deletions drivers/vfio/vfio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1415,6 +1415,7 @@ static int __init vfio_init(void)
* drivers.
*/
request_module_nowait("vfio_iommu_type1");
request_module_nowait("vfio_iommu_spapr_tce");

return 0;

Expand Down
Loading

0 comments on commit 5ffd229

Please sign in to comment.