2727
2828#define DART1_MAX_ADDR_BITS 36
2929
30- #define DART_MAX_TABLES 4
31- #define DART_LEVELS 2
30+ #define DART_MAX_TABLE_BITS 2
31+ #define DART_MAX_TABLES BIT(DART_MAX_TABLE_BITS)
32+ #define DART_MAX_LEVELS 4 /* Includes TTBR level */
3233
3334/* Struct accessors */
3435#define io_pgtable_to_data (x ) \
6869struct dart_io_pgtable {
6970 struct io_pgtable iop ;
7071
72+ int levels ;
7173 int tbl_bits ;
7274 int bits_per_level ;
7375
@@ -156,44 +158,45 @@ static dart_iopte dart_install_table(dart_iopte *table,
156158 return old ;
157159}
158160
159- static int dart_get_table (struct dart_io_pgtable * data , unsigned long iova )
161+ static int dart_get_index (struct dart_io_pgtable * data , unsigned long iova , int level )
160162{
161- return (iova >> (3 * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
162- ((1 << data -> tbl_bits ) - 1 );
163+ return (iova >> (level * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
164+ ((1 << data -> bits_per_level ) - 1 );
163165}
164166
165- static int dart_get_l1_index (struct dart_io_pgtable * data , unsigned long iova )
166- {
167-
168- return (iova >> (2 * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
169- ((1 << data -> bits_per_level ) - 1 );
170- }
171-
172- static int dart_get_l2_index (struct dart_io_pgtable * data , unsigned long iova )
167+ static int dart_get_last_index (struct dart_io_pgtable * data , unsigned long iova )
173168{
174169
175170 return (iova >> (data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
176171 ((1 << data -> bits_per_level ) - 1 );
177172}
178173
179- static dart_iopte * dart_get_l2 (struct dart_io_pgtable * data , unsigned long iova )
174+ static dart_iopte * dart_get_last (struct dart_io_pgtable * data , unsigned long iova )
180175{
181176 dart_iopte pte , * ptep ;
182- int tbl = dart_get_table (data , iova );
177+ int level = data -> levels ;
178+ int tbl = dart_get_index (data , iova , level );
179+
180+ if (tbl > (1 << data -> tbl_bits ))
181+ return NULL ;
183182
184183 ptep = data -> pgd [tbl ];
185184 if (!ptep )
186185 return NULL ;
187186
188- ptep += dart_get_l1_index (data , iova );
189- pte = READ_ONCE (* ptep );
187+ while (-- level > 1 ) {
188+ ptep += dart_get_index (data , iova , level );
189+ pte = READ_ONCE (* ptep );
190190
191- /* Valid entry? */
192- if (!pte )
193- return NULL ;
191+ /* Valid entry? */
192+ if (!pte )
193+ return NULL ;
194194
195- /* Deref to get level 2 table */
196- return iopte_deref (pte , data );
195+ /* Deref to get next level table */
196+ ptep = iopte_deref (pte , data );
197+ }
198+
199+ return ptep ;
197200}
198201
199202static dart_iopte dart_prot_to_pte (struct dart_io_pgtable * data ,
@@ -230,6 +233,7 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
230233 int ret = 0 , tbl , num_entries , max_entries , map_idx_start ;
231234 dart_iopte pte , * cptep , * ptep ;
232235 dart_iopte prot ;
236+ int level = data -> levels ;
233237
234238 if (WARN_ON (pgsize != cfg -> pgsize_bitmap ))
235239 return - EINVAL ;
@@ -240,31 +244,36 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
240244 if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE )))
241245 return - EINVAL ;
242246
243- tbl = dart_get_table (data , iova );
247+ tbl = dart_get_index (data , iova , level );
248+
249+ if (tbl > (1 << data -> tbl_bits ))
250+ return - ENOMEM ;
244251
245252 ptep = data -> pgd [tbl ];
246- ptep += dart_get_l1_index (data , iova );
247- pte = READ_ONCE (* ptep );
253+ while (-- level > 1 ) {
254+ ptep += dart_get_index (data , iova , level );
255+ pte = READ_ONCE (* ptep );
256+
257+ /* no table present */
258+ if (!pte ) {
259+ cptep = iommu_alloc_pages_sz (gfp , tblsz );
260+ if (!cptep )
261+ return - ENOMEM ;
248262
249- /* no L2 table present */
250- if (!pte ) {
251- cptep = iommu_alloc_pages_sz (gfp , tblsz );
252- if (!cptep )
253- return - ENOMEM ;
263+ pte = dart_install_table (cptep , ptep , 0 , data );
264+ if (pte )
265+ iommu_free_pages (cptep );
254266
255- pte = dart_install_table ( cptep , ptep , 0 , data );
256- if ( pte )
257- iommu_free_pages ( cptep );
267+ /* L2 table is present (now) */
268+ pte = READ_ONCE ( * ptep );
269+ }
258270
259- /* L2 table is present (now) */
260- pte = READ_ONCE (* ptep );
271+ ptep = iopte_deref (pte , data );
261272 }
262273
263- ptep = iopte_deref (pte , data );
264-
265274 /* install a leaf entries into L2 table */
266275 prot = dart_prot_to_pte (data , iommu_prot );
267- map_idx_start = dart_get_l2_index (data , iova );
276+ map_idx_start = dart_get_last_index (data , iova );
268277 max_entries = DART_PTES_PER_TABLE (data ) - map_idx_start ;
269278 num_entries = min_t (int , pgcount , max_entries );
270279 ptep += map_idx_start ;
@@ -293,13 +302,13 @@ static size_t dart_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
293302 if (WARN_ON (pgsize != cfg -> pgsize_bitmap || !pgcount ))
294303 return 0 ;
295304
296- ptep = dart_get_l2 (data , iova );
305+ ptep = dart_get_last (data , iova );
297306
298307 /* Valid L2 IOPTE pointer? */
299308 if (WARN_ON (!ptep ))
300309 return 0 ;
301310
302- unmap_idx_start = dart_get_l2_index (data , iova );
311+ unmap_idx_start = dart_get_last_index (data , iova );
303312 ptep += unmap_idx_start ;
304313
305314 max_entries = DART_PTES_PER_TABLE (data ) - unmap_idx_start ;
@@ -330,13 +339,13 @@ static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops,
330339 struct dart_io_pgtable * data = io_pgtable_ops_to_data (ops );
331340 dart_iopte pte , * ptep ;
332341
333- ptep = dart_get_l2 (data , iova );
342+ ptep = dart_get_last (data , iova );
334343
335344 /* Valid L2 IOPTE pointer? */
336345 if (!ptep )
337346 return 0 ;
338347
339- ptep += dart_get_l2_index (data , iova );
348+ ptep += dart_get_last_index (data , iova );
340349
341350 pte = READ_ONCE (* ptep );
342351 /* Found translation */
@@ -353,21 +362,37 @@ static struct dart_io_pgtable *
353362dart_alloc_pgtable (struct io_pgtable_cfg * cfg )
354363{
355364 struct dart_io_pgtable * data ;
356- int tbl_bits , bits_per_level , va_bits , pg_shift ;
365+ int levels , max_tbl_bits , tbl_bits , bits_per_level , va_bits , pg_shift ;
366+
367+ /*
368+ * Old 4K page DARTs can use up to 4 top-level tables.
369+ * Newer ones only ever use a maximum of 1.
370+ */
371+ if (cfg -> pgsize_bitmap == SZ_4K )
372+ max_tbl_bits = DART_MAX_TABLE_BITS ;
373+ else
374+ max_tbl_bits = 0 ;
357375
358376 pg_shift = __ffs (cfg -> pgsize_bitmap );
359377 bits_per_level = pg_shift - ilog2 (sizeof (dart_iopte ));
360378
361379 va_bits = cfg -> ias - pg_shift ;
362380
363- tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * DART_LEVELS ));
364- if ((1 << tbl_bits ) > DART_MAX_TABLES )
381+ levels = max_t (int , 2 , (va_bits - max_tbl_bits + bits_per_level - 1 ) / bits_per_level );
382+
383+ if (levels > (DART_MAX_LEVELS - 1 ))
384+ return NULL ;
385+
386+ tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * levels ));
387+
388+ if (tbl_bits > max_tbl_bits )
365389 return NULL ;
366390
367391 data = kzalloc (sizeof (* data ), GFP_KERNEL );
368392 if (!data )
369393 return NULL ;
370394
395+ data -> levels = levels + 1 ; /* Table level counts as one level */
371396 data -> tbl_bits = tbl_bits ;
372397 data -> bits_per_level = bits_per_level ;
373398
@@ -403,6 +428,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
403428 return NULL ;
404429
405430 cfg -> apple_dart_cfg .n_ttbrs = 1 << data -> tbl_bits ;
431+ cfg -> apple_dart_cfg .n_levels = data -> levels ;
406432
407433 for (i = 0 ; i < cfg -> apple_dart_cfg .n_ttbrs ; ++ i ) {
408434 data -> pgd [i ] =
@@ -422,23 +448,31 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
422448 return NULL ;
423449}
424450
425- static void apple_dart_free_pgtable (struct io_pgtable * iop )
451+ static void apple_dart_free_pgtables (struct dart_io_pgtable * data , dart_iopte * ptep , int level )
426452{
427- struct dart_io_pgtable * data = io_pgtable_to_data (iop );
428- dart_iopte * ptep , * end ;
429- int i ;
453+ dart_iopte * end ;
454+ dart_iopte * start = ptep ;
430455
431- for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
432- ptep = data -> pgd [i ];
456+ if (level > 1 ) {
433457 end = (void * )ptep + DART_GRANULE (data );
434458
435459 while (ptep != end ) {
436460 dart_iopte pte = * ptep ++ ;
437461
438462 if (pte )
439- iommu_free_pages ( iopte_deref (pte , data ));
463+ apple_dart_free_pgtables ( data , iopte_deref (pte , data ), level - 1 );
440464 }
441- iommu_free_pages (data -> pgd [i ]);
465+ }
466+ iommu_free_pages (start );
467+ }
468+
469+ static void apple_dart_free_pgtable (struct io_pgtable * iop )
470+ {
471+ struct dart_io_pgtable * data = io_pgtable_to_data (iop );
472+ int i ;
473+
474+ for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
475+ apple_dart_free_pgtables (data , data -> pgd [i ], data -> levels - 1 );
442476 }
443477
444478 kfree (data );
0 commit comments