| From foo@baz Mon Mar 20 11:41:01 CET 2017 |
| From: alexander.levin@verizon.com |
| Date: Fri, 17 Mar 2017 00:48:26 +0000 |
| Subject: vfio/spapr: Postpone allocation of userspace version of TCE table |
| To: "gregkh@linuxfoundation.org" <gregkh@linuxfoundation.org> |
| Cc: "stable@vger.kernel.org" <stable@vger.kernel.org> |
| Message-ID: <20170317004812.26960-21-alexander.levin@verizon.com> |
| |
| From: Alexey Kardashevskiy <aik@ozlabs.ru> |
| |
| [ Upstream commit 39701e56f5f16ea0cf8fc9e8472e645f8de91d23 ] |
| |
| The iommu_table struct manages a hardware TCE table and a vmalloc'd |
| table with corresponding userspace addresses. Both are allocated when |
| the default DMA window is created and this happens when the very first |
| group is attached to a container. |
| |
| As we are going to allow the userspace to configure container in one |
| memory context and pas container fd to another, we have to postpones |
| such allocations till a container fd is passed to the destination |
| user process so we would account locked memory limit against the actual |
| container user constrainsts. |
| |
| This postpones the it_userspace array allocation till it is used first |
| time for mapping. The unmapping patch already checks if the array is |
| allocated. |
| |
| Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> |
| Reviewed-by: David Gibson <david@gibson.dropbear.id.au> |
| Acked-by: Alex Williamson <alex.williamson@redhat.com> |
| Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> |
| Signed-off-by: Sasha Levin <alexander.levin@verizon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/vfio/vfio_iommu_spapr_tce.c | 20 +++++++------------- |
| 1 file changed, 7 insertions(+), 13 deletions(-) |
| |
| --- a/drivers/vfio/vfio_iommu_spapr_tce.c |
| +++ b/drivers/vfio/vfio_iommu_spapr_tce.c |
| @@ -509,6 +509,12 @@ static long tce_iommu_build_v2(struct tc |
| unsigned long hpa; |
| enum dma_data_direction dirtmp; |
| |
| + if (!tbl->it_userspace) { |
| + ret = tce_iommu_userspace_view_alloc(tbl); |
| + if (ret) |
| + return ret; |
| + } |
| + |
| for (i = 0; i < pages; ++i) { |
| struct mm_iommu_table_group_mem_t *mem = NULL; |
| unsigned long *pua = IOMMU_TABLE_USERSPACE_ENTRY(tbl, |
| @@ -582,15 +588,6 @@ static long tce_iommu_create_table(struc |
| WARN_ON(!ret && !(*ptbl)->it_ops->free); |
| WARN_ON(!ret && ((*ptbl)->it_allocated_size != table_size)); |
| |
| - if (!ret && container->v2) { |
| - ret = tce_iommu_userspace_view_alloc(*ptbl); |
| - if (ret) |
| - (*ptbl)->it_ops->free(*ptbl); |
| - } |
| - |
| - if (ret) |
| - decrement_locked_vm(table_size >> PAGE_SHIFT); |
| - |
| return ret; |
| } |
| |
| @@ -1062,10 +1059,7 @@ static int tce_iommu_take_ownership(stru |
| if (!tbl || !tbl->it_map) |
| continue; |
| |
| - rc = tce_iommu_userspace_view_alloc(tbl); |
| - if (!rc) |
| - rc = iommu_take_ownership(tbl); |
| - |
| + rc = iommu_take_ownership(tbl); |
| if (rc) { |
| for (j = 0; j < i; ++j) |
| iommu_release_ownership( |