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
@@ -165,44 +167,45 @@ static dart_iopte dart_install_table(dart_iopte *table,
165167 return old ;
166168}
167169
168- static int dart_get_table (struct dart_io_pgtable * data , unsigned long iova )
170+ static int dart_get_index (struct dart_io_pgtable * data , unsigned long iova , int level )
169171{
170- return (iova >> (3 * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
171- ((1 << data -> tbl_bits ) - 1 );
172+ return (iova >> (level * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
173+ ((1 << data -> bits_per_level ) - 1 );
172174}
173175
174- static int dart_get_l1_index (struct dart_io_pgtable * data , unsigned long iova )
175- {
176-
177- return (iova >> (2 * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
178- ((1 << data -> bits_per_level ) - 1 );
179- }
180-
181- static int dart_get_l2_index (struct dart_io_pgtable * data , unsigned long iova )
176+ static int dart_get_last_index (struct dart_io_pgtable * data , unsigned long iova )
182177{
183178
184179 return (iova >> (data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
185180 ((1 << data -> bits_per_level ) - 1 );
186181}
187182
188- static dart_iopte * dart_get_l2 (struct dart_io_pgtable * data , unsigned long iova )
183+ static dart_iopte * dart_get_last (struct dart_io_pgtable * data , unsigned long iova )
189184{
190185 dart_iopte pte , * ptep ;
191- int tbl = dart_get_table (data , iova );
186+ int level = data -> levels ;
187+ int tbl = dart_get_index (data , iova , level );
188+
189+ if (tbl > (1 << data -> tbl_bits ))
190+ return NULL ;
192191
193192 ptep = data -> pgd [tbl ];
194193 if (!ptep )
195194 return NULL ;
196195
197- ptep += dart_get_l1_index (data , iova );
198- pte = READ_ONCE (* ptep );
196+ while (-- level > 1 ) {
197+ ptep += dart_get_index (data , iova , level );
198+ pte = READ_ONCE (* ptep );
199199
200- /* Valid entry? */
201- if (!pte )
202- return NULL ;
200+ /* Valid entry? */
201+ if (!pte )
202+ return NULL ;
203203
204- /* Deref to get level 2 table */
205- return iopte_deref (pte , data );
204+ /* Deref to get next level table */
205+ ptep = iopte_deref (pte , data );
206+ }
207+
208+ return ptep ;
206209}
207210
208211static dart_iopte dart_prot_to_pte (struct dart_io_pgtable * data ,
@@ -238,6 +241,7 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
238241 int ret = 0 , tbl , num_entries , max_entries , map_idx_start ;
239242 dart_iopte pte , * cptep , * ptep ;
240243 dart_iopte prot ;
244+ int level = data -> levels ;
241245
242246 if (WARN_ON (pgsize != cfg -> pgsize_bitmap ))
243247 return - EINVAL ;
@@ -248,31 +252,36 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
248252 if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE )))
249253 return - EINVAL ;
250254
251- tbl = dart_get_table (data , iova );
255+ tbl = dart_get_index (data , iova , level );
256+
257+ if (tbl > (1 << data -> tbl_bits ))
258+ return - ENOMEM ;
252259
253260 ptep = data -> pgd [tbl ];
254- ptep += dart_get_l1_index (data , iova );
255- pte = READ_ONCE (* ptep );
261+ while (-- level > 1 ) {
262+ ptep += dart_get_index (data , iova , level );
263+ pte = READ_ONCE (* ptep );
256264
257- /* no L2 table present */
258- if (!pte ) {
259- cptep = __dart_alloc_pages (tblsz , gfp );
260- if (!cptep )
261- return - ENOMEM ;
265+ /* no table present */
266+ if (!pte ) {
267+ cptep = __dart_alloc_pages (tblsz , gfp );
268+ if (!cptep )
269+ return - ENOMEM ;
262270
263- pte = dart_install_table (cptep , ptep , 0 , data );
264- if (pte )
265- iommu_free_pages (cptep , get_order (tblsz ));
271+ pte = dart_install_table (cptep , ptep , 0 , data );
272+ if (pte )
273+ iommu_free_pages (cptep , get_order (tblsz ));
266274
267- /* L2 table is present (now) */
268- pte = READ_ONCE (* ptep );
269- }
275+ /* L2 table is present (now) */
276+ pte = READ_ONCE (* ptep );
277+ }
270278
271- ptep = iopte_deref (pte , data );
279+ ptep = iopte_deref (pte , data );
280+ }
272281
273282 /* install a leaf entries into L2 table */
274283 prot = dart_prot_to_pte (data , iommu_prot );
275- map_idx_start = dart_get_l2_index (data , iova );
284+ map_idx_start = dart_get_last_index (data , iova );
276285 max_entries = DART_PTES_PER_TABLE (data ) - map_idx_start ;
277286 num_entries = min_t (int , pgcount , max_entries );
278287 ptep += map_idx_start ;
@@ -301,13 +310,13 @@ static size_t dart_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
301310 if (WARN_ON (pgsize != cfg -> pgsize_bitmap || !pgcount ))
302311 return 0 ;
303312
304- ptep = dart_get_l2 (data , iova );
313+ ptep = dart_get_last (data , iova );
305314
306315 /* Valid L2 IOPTE pointer? */
307316 if (WARN_ON (!ptep ))
308317 return 0 ;
309318
310- unmap_idx_start = dart_get_l2_index (data , iova );
319+ unmap_idx_start = dart_get_last_index (data , iova );
311320 ptep += unmap_idx_start ;
312321
313322 max_entries = DART_PTES_PER_TABLE (data ) - unmap_idx_start ;
@@ -338,13 +347,13 @@ static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops,
338347 struct dart_io_pgtable * data = io_pgtable_ops_to_data (ops );
339348 dart_iopte pte , * ptep ;
340349
341- ptep = dart_get_l2 (data , iova );
350+ ptep = dart_get_last (data , iova );
342351
343352 /* Valid L2 IOPTE pointer? */
344353 if (!ptep )
345354 return 0 ;
346355
347- ptep += dart_get_l2_index (data , iova );
356+ ptep += dart_get_last_index (data , iova );
348357
349358 pte = READ_ONCE (* ptep );
350359 /* Found translation */
@@ -361,21 +370,37 @@ static struct dart_io_pgtable *
361370dart_alloc_pgtable (struct io_pgtable_cfg * cfg )
362371{
363372 struct dart_io_pgtable * data ;
364- int tbl_bits , bits_per_level , va_bits , pg_shift ;
373+ int levels , max_tbl_bits , tbl_bits , bits_per_level , va_bits , pg_shift ;
374+
375+ /*
376+ * Old 4K page DARTs can use up to 4 top-level tables.
377+ * Newer ones only ever use a maximum of 1.
378+ */
379+ if (cfg -> pgsize_bitmap == SZ_4K )
380+ max_tbl_bits = DART_MAX_TABLE_BITS ;
381+ else
382+ max_tbl_bits = 0 ;
365383
366384 pg_shift = __ffs (cfg -> pgsize_bitmap );
367385 bits_per_level = pg_shift - ilog2 (sizeof (dart_iopte ));
368386
369387 va_bits = cfg -> ias - pg_shift ;
370388
371- tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * DART_LEVELS ));
372- if ((1 << tbl_bits ) > DART_MAX_TABLES )
389+ levels = max_t (int , 2 , (va_bits - max_tbl_bits + bits_per_level - 1 ) / bits_per_level );
390+
391+ if (levels > (DART_MAX_LEVELS - 1 ))
392+ return NULL ;
393+
394+ tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * levels ));
395+
396+ if (tbl_bits > max_tbl_bits )
373397 return NULL ;
374398
375399 data = kzalloc (sizeof (* data ), GFP_KERNEL );
376400 if (!data )
377401 return NULL ;
378402
403+ data -> levels = levels + 1 ; /* Table level counts as one level */
379404 data -> tbl_bits = tbl_bits ;
380405 data -> bits_per_level = bits_per_level ;
381406
@@ -411,6 +436,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
411436 return NULL ;
412437
413438 cfg -> apple_dart_cfg .n_ttbrs = 1 << data -> tbl_bits ;
439+ cfg -> apple_dart_cfg .n_levels = data -> levels ;
414440
415441 for (i = 0 ; i < cfg -> apple_dart_cfg .n_ttbrs ; ++ i ) {
416442 data -> pgd [i ] = __dart_alloc_pages (DART_GRANULE (data ), GFP_KERNEL );
@@ -430,24 +456,32 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
430456 return NULL ;
431457}
432458
433- static void apple_dart_free_pgtable (struct io_pgtable * iop )
459+ static void apple_dart_free_pgtables (struct dart_io_pgtable * data , dart_iopte * ptep , int level )
434460{
435- struct dart_io_pgtable * data = io_pgtable_to_data (iop );
461+ dart_iopte * end ;
462+ dart_iopte * start = ptep ;
436463 int order = get_order (DART_GRANULE (data ));
437- dart_iopte * ptep , * end ;
438- int i ;
439464
440- for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
441- ptep = data -> pgd [i ];
465+ if (level > 1 ) {
442466 end = (void * )ptep + DART_GRANULE (data );
443467
444468 while (ptep != end ) {
445469 dart_iopte pte = * ptep ++ ;
446470
447471 if (pte )
448- iommu_free_pages ( iopte_deref (pte , data ), order );
472+ apple_dart_free_pgtables ( data , iopte_deref (pte , data ), level - 1 );
449473 }
450- iommu_free_pages (data -> pgd [i ], order );
474+ }
475+ iommu_free_pages (start , order );
476+ }
477+
478+ static void apple_dart_free_pgtable (struct io_pgtable * iop )
479+ {
480+ struct dart_io_pgtable * data = io_pgtable_to_data (iop );
481+ int i ;
482+
483+ for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
484+ apple_dart_free_pgtables (data , data -> pgd [i ], data -> levels - 1 );
451485 }
452486
453487 kfree (data );
0 commit comments