aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2016-11-30 01:52:03 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2016-12-01 22:38:32 -0500
commitd9c728949ddc9de5734bf3b12ea906ca8a77f2a0 (patch)
treebe2f59c181c28e423b00f0908f0923617ec3c993
parent6f01cc692a16405235d5c34056455b182682123c (diff)
vfio/spapr: Postpone default window creation
We are going to allow the userspace to configure container in one memory context and pass container fd to another so we are postponing memory allocations accounted against the locked memory limit. One of previous patches took care of it_userspace. At the moment we create the default DMA window when the first group is attached to a container; this is done for the userspace which is not DDW-aware but familiar with the SPAPR TCE IOMMU v2 in the part of memory pre-registration - such client expects the default DMA window to exist. This postpones the default DMA window allocation till one of the folliwing happens: 1. first map/unmap request arrives; 2. new window is requested; This adds noop for the case when the userspace requested removal of the default window which has not been created yet. 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>
-rw-r--r--drivers/vfio/vfio_iommu_spapr_tce.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index a67bbfdd86d5..88622be0d6b5 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -97,6 +97,7 @@ struct tce_container {
97 struct mutex lock; 97 struct mutex lock;
98 bool enabled; 98 bool enabled;
99 bool v2; 99 bool v2;
100 bool def_window_pending;
100 unsigned long locked_pages; 101 unsigned long locked_pages;
101 struct iommu_table *tables[IOMMU_TABLE_GROUP_MAX_TABLES]; 102 struct iommu_table *tables[IOMMU_TABLE_GROUP_MAX_TABLES];
102 struct list_head group_list; 103 struct list_head group_list;
@@ -717,6 +718,9 @@ static long tce_iommu_create_default_window(struct tce_container *container)
717 struct tce_iommu_group *tcegrp; 718 struct tce_iommu_group *tcegrp;
718 struct iommu_table_group *table_group; 719 struct iommu_table_group *table_group;
719 720
721 if (!container->def_window_pending)
722 return 0;
723
720 if (!tce_groups_attached(container)) 724 if (!tce_groups_attached(container))
721 return -ENODEV; 725 return -ENODEV;
722 726
@@ -730,6 +734,9 @@ static long tce_iommu_create_default_window(struct tce_container *container)
730 table_group->tce32_size, 1, &start_addr); 734 table_group->tce32_size, 1, &start_addr);
731 WARN_ON_ONCE(!ret && start_addr); 735 WARN_ON_ONCE(!ret && start_addr);
732 736
737 if (!ret)
738 container->def_window_pending = false;
739
733 return ret; 740 return ret;
734} 741}
735 742
@@ -823,6 +830,10 @@ static long tce_iommu_ioctl(void *iommu_data,
823 VFIO_DMA_MAP_FLAG_WRITE)) 830 VFIO_DMA_MAP_FLAG_WRITE))
824 return -EINVAL; 831 return -EINVAL;
825 832
833 ret = tce_iommu_create_default_window(container);
834 if (ret)
835 return ret;
836
826 num = tce_iommu_find_table(container, param.iova, &tbl); 837 num = tce_iommu_find_table(container, param.iova, &tbl);
827 if (num < 0) 838 if (num < 0)
828 return -ENXIO; 839 return -ENXIO;
@@ -886,6 +897,10 @@ static long tce_iommu_ioctl(void *iommu_data,
886 if (param.flags) 897 if (param.flags)
887 return -EINVAL; 898 return -EINVAL;
888 899
900 ret = tce_iommu_create_default_window(container);
901 if (ret)
902 return ret;
903
889 num = tce_iommu_find_table(container, param.iova, &tbl); 904 num = tce_iommu_find_table(container, param.iova, &tbl);
890 if (num < 0) 905 if (num < 0)
891 return -ENXIO; 906 return -ENXIO;
@@ -1012,6 +1027,10 @@ static long tce_iommu_ioctl(void *iommu_data,
1012 1027
1013 mutex_lock(&container->lock); 1028 mutex_lock(&container->lock);
1014 1029
1030 ret = tce_iommu_create_default_window(container);
1031 if (ret)
1032 return ret;
1033
1015 ret = tce_iommu_create_window(container, create.page_shift, 1034 ret = tce_iommu_create_window(container, create.page_shift,
1016 create.window_size, create.levels, 1035 create.window_size, create.levels,
1017 &create.start_addr); 1036 &create.start_addr);
@@ -1044,6 +1063,11 @@ static long tce_iommu_ioctl(void *iommu_data,
1044 if (remove.flags) 1063 if (remove.flags)
1045 return -EINVAL; 1064 return -EINVAL;
1046 1065
1066 if (container->def_window_pending && !remove.start_addr) {
1067 container->def_window_pending = false;
1068 return 0;
1069 }
1070
1047 mutex_lock(&container->lock); 1071 mutex_lock(&container->lock);
1048 1072
1049 ret = tce_iommu_remove_window(container, remove.start_addr); 1073 ret = tce_iommu_remove_window(container, remove.start_addr);
@@ -1141,7 +1165,6 @@ static int tce_iommu_attach_group(void *iommu_data,
1141 struct tce_container *container = iommu_data; 1165 struct tce_container *container = iommu_data;
1142 struct iommu_table_group *table_group; 1166 struct iommu_table_group *table_group;
1143 struct tce_iommu_group *tcegrp = NULL; 1167 struct tce_iommu_group *tcegrp = NULL;
1144 bool create_default_window = false;
1145 1168
1146 mutex_lock(&container->lock); 1169 mutex_lock(&container->lock);
1147 1170
@@ -1189,25 +1212,12 @@ static int tce_iommu_attach_group(void *iommu_data,
1189 } else { 1212 } else {
1190 ret = tce_iommu_take_ownership_ddw(container, table_group); 1213 ret = tce_iommu_take_ownership_ddw(container, table_group);
1191 if (!tce_groups_attached(container) && !container->tables[0]) 1214 if (!tce_groups_attached(container) && !container->tables[0])
1192 create_default_window = true; 1215 container->def_window_pending = true;
1193 } 1216 }
1194 1217
1195 if (!ret) { 1218 if (!ret) {
1196 tcegrp->grp = iommu_group; 1219 tcegrp->grp = iommu_group;
1197 list_add(&tcegrp->next, &container->group_list); 1220 list_add(&tcegrp->next, &container->group_list);
1198 /*
1199 * If it the first group attached, check if there is
1200 * a default DMA window and create one if none as
1201 * the userspace expects it to exist.
1202 */
1203 if (create_default_window) {
1204 ret = tce_iommu_create_default_window(container);
1205 if (ret) {
1206 list_del(&tcegrp->next);
1207 tce_iommu_release_ownership_ddw(container,
1208 table_group);
1209 }
1210 }
1211 } 1221 }
1212 1222
1213unlock_exit: 1223unlock_exit: