2626
2727#define DART1_MAX_ADDR_BITS 36
2828
29- #define DART_MAX_TABLES 4
30- #define DART_LEVELS 2
29+ #define DART_MAX_TABLE_BITS 2
30+ #define DART_MAX_TABLES BIT(DART_MAX_TABLE_BITS)
31+ #define DART_MAX_LEVELS 4 /* Includes TTBR level */
3132
3233/* Struct accessors */
3334#define io_pgtable_to_data (x ) \
6768struct dart_io_pgtable {
6869 struct io_pgtable iop ;
6970
71+ int levels ;
7072 int tbl_bits ;
7173 int bits_per_level ;
7274
@@ -169,44 +171,45 @@ static dart_iopte dart_install_table(dart_iopte *table,
169171 return old ;
170172}
171173
172- static int dart_get_table (struct dart_io_pgtable * data , unsigned long iova )
174+ static int dart_get_index (struct dart_io_pgtable * data , unsigned long iova , int level )
173175{
174- return (iova >> (3 * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
175- ((1 << data -> tbl_bits ) - 1 );
176+ return (iova >> (level * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
177+ ((1 << data -> bits_per_level ) - 1 );
176178}
177179
178- static int dart_get_l1_index (struct dart_io_pgtable * data , unsigned long iova )
179- {
180-
181- return (iova >> (2 * data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
182- ((1 << data -> bits_per_level ) - 1 );
183- }
184-
185- static int dart_get_l2_index (struct dart_io_pgtable * data , unsigned long iova )
180+ static int dart_get_last_index (struct dart_io_pgtable * data , unsigned long iova )
186181{
187182
188183 return (iova >> (data -> bits_per_level + ilog2 (sizeof (dart_iopte )))) &
189184 ((1 << data -> bits_per_level ) - 1 );
190185}
191186
192- static dart_iopte * dart_get_l2 (struct dart_io_pgtable * data , unsigned long iova )
187+ static dart_iopte * dart_get_last (struct dart_io_pgtable * data , unsigned long iova )
193188{
194189 dart_iopte pte , * ptep ;
195- int tbl = dart_get_table (data , iova );
190+ int level = data -> levels ;
191+ int tbl = dart_get_index (data , iova , level );
192+
193+ if (tbl > (1 << data -> tbl_bits ))
194+ return NULL ;
196195
197196 ptep = data -> pgd [tbl ];
198197 if (!ptep )
199198 return NULL ;
200199
201- ptep += dart_get_l1_index (data , iova );
202- pte = READ_ONCE (* ptep );
200+ while (-- level > 1 ) {
201+ ptep += dart_get_index (data , iova , level );
202+ pte = READ_ONCE (* ptep );
203203
204- /* Valid entry? */
205- if (!pte )
206- return NULL ;
204+ /* Valid entry? */
205+ if (!pte )
206+ return NULL ;
207+
208+ /* Deref to get next level table */
209+ ptep = iopte_deref (pte , data );
210+ }
207211
208- /* Deref to get level 2 table */
209- return iopte_deref (pte , data );
212+ return ptep ;
210213}
211214
212215static dart_iopte dart_prot_to_pte (struct dart_io_pgtable * data ,
@@ -242,6 +245,7 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
242245 int ret = 0 , tbl , num_entries , max_entries , map_idx_start ;
243246 dart_iopte pte , * cptep , * ptep ;
244247 dart_iopte prot ;
248+ int level = data -> levels ;
245249
246250 if (WARN_ON (pgsize != cfg -> pgsize_bitmap ))
247251 return - EINVAL ;
@@ -253,31 +257,36 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
253257 if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE )))
254258 return 0 ;
255259
256- tbl = dart_get_table (data , iova );
260+ tbl = dart_get_index (data , iova , level );
261+
262+ if (tbl > (1 << data -> tbl_bits ))
263+ return - ENOMEM ;
257264
258265 ptep = data -> pgd [tbl ];
259- ptep += dart_get_l1_index (data , iova );
260- pte = READ_ONCE (* ptep );
266+ while (-- level > 1 ) {
267+ ptep += dart_get_index (data , iova , level );
268+ pte = READ_ONCE (* ptep );
261269
262- /* no L2 table present */
263- if (!pte ) {
264- cptep = __dart_alloc_pages (tblsz , gfp );
265- if (!cptep )
266- return - ENOMEM ;
270+ /* no table present */
271+ if (!pte ) {
272+ cptep = __dart_alloc_pages (tblsz , gfp );
273+ if (!cptep )
274+ return - ENOMEM ;
267275
268- pte = dart_install_table (cptep , ptep , 0 , data );
269- if (pte )
270- free_pages ((unsigned long )cptep , get_order (tblsz ));
276+ pte = dart_install_table (cptep , ptep , 0 , data );
277+ if (pte )
278+ free_pages ((unsigned long )cptep , get_order (tblsz ));
271279
272- /* L2 table is present (now) */
273- pte = READ_ONCE (* ptep );
274- }
280+ /* L2 table is present (now) */
281+ pte = READ_ONCE (* ptep );
282+ }
275283
276- ptep = iopte_deref (pte , data );
284+ ptep = iopte_deref (pte , data );
285+ }
277286
278287 /* install a leaf entries into L2 table */
279288 prot = dart_prot_to_pte (data , iommu_prot );
280- map_idx_start = dart_get_l2_index (data , iova );
289+ map_idx_start = dart_get_last_index (data , iova );
281290 max_entries = DART_PTES_PER_TABLE (data ) - map_idx_start ;
282291 num_entries = min_t (int , pgcount , max_entries );
283292 ptep += map_idx_start ;
@@ -306,13 +315,13 @@ static size_t dart_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
306315 if (WARN_ON (pgsize != cfg -> pgsize_bitmap || !pgcount ))
307316 return 0 ;
308317
309- ptep = dart_get_l2 (data , iova );
318+ ptep = dart_get_last (data , iova );
310319
311320 /* Valid L2 IOPTE pointer? */
312321 if (WARN_ON (!ptep ))
313322 return 0 ;
314323
315- unmap_idx_start = dart_get_l2_index (data , iova );
324+ unmap_idx_start = dart_get_last_index (data , iova );
316325 ptep += unmap_idx_start ;
317326
318327 max_entries = DART_PTES_PER_TABLE (data ) - unmap_idx_start ;
@@ -343,13 +352,13 @@ static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops,
343352 struct dart_io_pgtable * data = io_pgtable_ops_to_data (ops );
344353 dart_iopte pte , * ptep ;
345354
346- ptep = dart_get_l2 (data , iova );
355+ ptep = dart_get_last (data , iova );
347356
348357 /* Valid L2 IOPTE pointer? */
349358 if (!ptep )
350359 return 0 ;
351360
352- ptep += dart_get_l2_index (data , iova );
361+ ptep += dart_get_last_index (data , iova );
353362
354363 pte = READ_ONCE (* ptep );
355364 /* Found translation */
@@ -366,21 +375,37 @@ static struct dart_io_pgtable *
366375dart_alloc_pgtable (struct io_pgtable_cfg * cfg )
367376{
368377 struct dart_io_pgtable * data ;
369- int tbl_bits , bits_per_level , va_bits , pg_shift ;
378+ int levels , max_tbl_bits , tbl_bits , bits_per_level , va_bits , pg_shift ;
379+
380+ /*
381+ * Old 4K page DARTs can use up to 4 top-level tables.
382+ * Newer ones only ever use a maximum of 1.
383+ */
384+ if (cfg -> pgsize_bitmap == SZ_4K )
385+ max_tbl_bits = DART_MAX_TABLE_BITS ;
386+ else
387+ max_tbl_bits = 0 ;
370388
371389 pg_shift = __ffs (cfg -> pgsize_bitmap );
372390 bits_per_level = pg_shift - ilog2 (sizeof (dart_iopte ));
373391
374392 va_bits = cfg -> ias - pg_shift ;
375393
376- tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * DART_LEVELS ));
377- if ((1 << tbl_bits ) > DART_MAX_TABLES )
394+ levels = max_t (int , 2 , (va_bits - max_tbl_bits + bits_per_level - 1 ) / bits_per_level );
395+
396+ if (levels > (DART_MAX_LEVELS - 1 ))
397+ return NULL ;
398+
399+ tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * levels ));
400+
401+ if (tbl_bits > max_tbl_bits )
378402 return NULL ;
379403
380404 data = kzalloc (sizeof (* data ), GFP_KERNEL );
381405 if (!data )
382406 return NULL ;
383407
408+ data -> levels = levels + 1 ; /* Table level counts as one level */
384409 data -> tbl_bits = tbl_bits ;
385410 data -> bits_per_level = bits_per_level ;
386411
@@ -416,6 +441,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
416441 return NULL ;
417442
418443 cfg -> apple_dart_cfg .n_ttbrs = 1 << data -> tbl_bits ;
444+ cfg -> apple_dart_cfg .n_levels = data -> levels ;
419445
420446 for (i = 0 ; i < cfg -> apple_dart_cfg .n_ttbrs ; ++ i ) {
421447 data -> pgd [i ] = __dart_alloc_pages (DART_GRANULE (data ), GFP_KERNEL );
@@ -434,28 +460,32 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
434460 return NULL ;
435461}
436462
437- static void apple_dart_free_pgtable (struct io_pgtable * iop )
463+ static void apple_dart_free_pgtables (struct dart_io_pgtable * data , dart_iopte * ptep , int level )
438464{
439- struct dart_io_pgtable * data = io_pgtable_to_data (iop );
440- dart_iopte * ptep , * end ;
441- int i ;
465+ dart_iopte * end ;
442466
443- for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
444- ptep = data -> pgd [i ];
467+ if (level > 1 ) {
445468 end = (void * )ptep + DART_GRANULE (data );
446469
447470 while (ptep != end ) {
448471 dart_iopte pte = * ptep ++ ;
449472
450- if (pte ) {
451- unsigned long page =
452- (unsigned long )iopte_deref (pte , data );
453-
454- free_pages (page , get_order (DART_GRANULE (data )));
455- }
473+ if (pte )
474+ apple_dart_free_pgtables (data , iopte_deref (pte , data ), level - 1 );
456475 }
457- free_pages ((unsigned long )data -> pgd [i ],
458- get_order (DART_GRANULE (data )));
476+ }
477+ free_pages ((unsigned long )ptep , get_order (DART_GRANULE (data )));
478+ }
479+
480+ static void apple_dart_free_pgtable (struct io_pgtable * iop )
481+ {
482+ struct dart_io_pgtable * data = io_pgtable_to_data (iop );
483+ dart_iopte * ptep ;
484+ int i ;
485+
486+ for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
487+ ptep = data -> pgd [i ];
488+ apple_dart_free_pgtables (data , data -> pgd [i ], data -> levels - 1 );
459489 }
460490
461491 kfree (data );
0 commit comments