--- v6
+++ v4
@@ -15,16 +15,13 @@
Dynamic DMA window and in-kernel acceleration will require memory to
be preregistered in order to work.
-The accounting is done per VFIO container. When support for
-multiple groups per container is added, we will have more accurate locked_vm
+The accounting is done per VFIO container. When the support of
+multiple groups per container is added, we will have accurate locked_vm
accounting.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
Changes:
-v6:
-* tce_get_hva_cached() returns hva via a pointer
-
v4:
* updated docs
* s/kzmalloc/vzalloc/
@@ -34,9 +31,9 @@
and removed duplicating vfio_iommu_spapr_register_memory
---
Documentation/vfio.txt | 19 +++
- drivers/vfio/vfio_iommu_spapr_tce.c | 275 +++++++++++++++++++++++++++++++++++-
+ drivers/vfio/vfio_iommu_spapr_tce.c | 274 +++++++++++++++++++++++++++++++++++-
include/uapi/linux/vfio.h | 25 ++++
- 3 files changed, 313 insertions(+), 6 deletions(-)
+ 3 files changed, 312 insertions(+), 6 deletions(-)
diff --git a/Documentation/vfio.txt b/Documentation/vfio.txt
index 96978ec..791e85c 100644
@@ -69,7 +66,7 @@
[1] VFIO was originally an acronym for "Virtual Function I/O" in its
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
-index be693ca..838123e 100644
+index 7fd60f9..9b884e0 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -21,6 +21,7 @@
@@ -276,8 +273,8 @@
+
static bool tce_page_is_contained(struct page *page, unsigned page_shift)
{
- /*
-@@ -145,12 +334,14 @@ static int tce_iommu_enable(struct tce_container *container)
+ unsigned shift;
+@@ -151,12 +340,14 @@ static int tce_iommu_enable(struct tce_container *container)
* as this information is only available from KVM and VFIO is
* KVM agnostic.
*/
@@ -297,7 +294,7 @@
container->enabled = true;
-@@ -184,6 +375,7 @@ static void *tce_iommu_open(unsigned long arg)
+@@ -190,6 +381,7 @@ static void *tce_iommu_open(unsigned long arg)
return ERR_PTR(-ENOMEM);
mutex_init(&container->lock);
@@ -305,15 +302,17 @@
return container;
}
-@@ -206,6 +398,7 @@ static void tce_iommu_release(void *iommu_data)
+@@ -212,6 +404,9 @@ static void tce_iommu_release(void *iommu_data)
+ if (tbl->it_group)
tce_iommu_detach_group(iommu_data, tbl->it_group);
}
-
++
+ tce_mem_unregister_all(container);
- tce_iommu_disable(container);
-
++
mutex_destroy(&container->lock);
-@@ -235,6 +428,9 @@ static void tce_iommu_unuse_page(struct tce_container *container,
+
+ kfree(container);
+@@ -230,6 +425,9 @@ static void tce_iommu_unuse_page(struct tce_container *container,
if (oldtce & TCE_PCI_WRITE)
SetPageDirty(page);
@@ -323,12 +322,12 @@
put_page(page);
}
-@@ -270,6 +466,24 @@ static int tce_get_hva(struct tce_container *container,
- return 0;
+@@ -280,6 +478,22 @@ static unsigned long tce_get_hva(struct tce_container *container,
+ return hva;
}
-+static int tce_get_hva_cached(struct tce_container *container,
-+ unsigned page_shift, unsigned long tce, unsigned long *hva)
++static unsigned long tce_get_hva_cached(struct tce_container *container,
++ unsigned page_shift, unsigned long tce)
+{
+ struct tce_memory *mem;
+ unsigned long gfn;
@@ -336,33 +335,30 @@
+ tce &= PAGE_MASK;
+ mem = tce_pinned_desc(container, tce, 1ULL << page_shift);
+ if (!mem)
-+ return -EFAULT;
++ return -1;
+
+ gfn = (tce - mem->vaddr) >> PAGE_SHIFT;
+
-+ *hva = (unsigned long) __va(mem->hpas[gfn]);
-+
-+ return 0;
++ return (unsigned long) __va(mem->hpas[gfn]);
+}
+
static long tce_iommu_build(struct tce_container *container,
struct iommu_table *tbl,
unsigned long entry, unsigned long tce, unsigned long pages)
-@@ -280,7 +494,12 @@ static long tce_iommu_build(struct tce_container *container,
- enum dma_data_direction direction = iommu_tce_direction(tce);
+@@ -290,7 +504,11 @@ static long tce_iommu_build(struct tce_container *container,
+ enum dma_data_direction direction = tce_iommu_direction(tce);
for (i = 0; i < pages; ++i) {
-- ret = tce_get_hva(container, tbl->it_page_shift, tce, &hva);
+- hva = tce_get_hva(container, tbl->it_page_shift, tce);
+ if (tce_preregistered(container))
-+ ret = tce_get_hva_cached(container, tbl->it_page_shift,
-+ tce, &hva);
++ hva = tce_get_hva_cached(container, tbl->it_page_shift,
++ tce);
+ else
-+ ret = tce_get_hva(container, tbl->it_page_shift,
-+ tce, &hva);
- if (ret)
++ hva = tce_get_hva(container, tbl->it_page_shift, tce);
+ if (hva == -1) {
+ ret = -EFAULT;
break;
-
-@@ -441,6 +660,50 @@ static long tce_iommu_ioctl(void *iommu_data,
+@@ -455,6 +673,50 @@ static long tce_iommu_ioctl(void *iommu_data,
return ret;
}
@@ -414,10 +410,10 @@
mutex_lock(&container->lock);
ret = tce_iommu_enable(container);
diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
-index 82889c3..b17e120 100644
+index 29715d2..0f55c08 100644
--- a/include/uapi/linux/vfio.h
+++ b/include/uapi/linux/vfio.h
-@@ -493,6 +493,31 @@ struct vfio_eeh_pe_op {
+@@ -492,6 +492,31 @@ struct vfio_eeh_pe_op {
#define VFIO_EEH_PE_OP _IO(VFIO_TYPE, VFIO_BASE + 21)