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 ;
@@ -249,31 +253,36 @@ static int dart_map_pages(struct io_pgtable_ops *ops, unsigned long iova,
249253 if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE )))
250254 return 0 ;
251255
252- tbl = dart_get_table (data , iova );
256+ tbl = dart_get_index (data , iova , level );
257+
258+ if (tbl > (1 << data -> tbl_bits ))
259+ return - ENOMEM ;
253260
254261 ptep = data -> pgd [tbl ];
255- ptep += dart_get_l1_index (data , iova );
256- pte = READ_ONCE (* ptep );
262+ while (-- level > 1 ) {
263+ ptep += dart_get_index (data , iova , level );
264+ pte = READ_ONCE (* ptep );
257265
258- /* no L2 table present */
259- if (!pte ) {
260- cptep = __dart_alloc_pages (tblsz , gfp );
261- if (!cptep )
262- return - ENOMEM ;
266+ /* no table present */
267+ if (!pte ) {
268+ cptep = __dart_alloc_pages (tblsz , gfp );
269+ if (!cptep )
270+ return - ENOMEM ;
263271
264- pte = dart_install_table (cptep , ptep , 0 , data );
265- if (pte )
266- iommu_free_pages (cptep , get_order (tblsz ));
272+ pte = dart_install_table (cptep , ptep , 0 , data );
273+ if (pte )
274+ iommu_free_pages (cptep , get_order (tblsz ));
267275
268- /* L2 table is present (now) */
269- pte = READ_ONCE (* ptep );
270- }
276+ /* L2 table is present (now) */
277+ pte = READ_ONCE (* ptep );
278+ }
271279
272- ptep = iopte_deref (pte , data );
280+ ptep = iopte_deref (pte , data );
281+ }
273282
274283 /* install a leaf entries into L2 table */
275284 prot = dart_prot_to_pte (data , iommu_prot );
276- map_idx_start = dart_get_l2_index (data , iova );
285+ map_idx_start = dart_get_last_index (data , iova );
277286 max_entries = DART_PTES_PER_TABLE (data ) - map_idx_start ;
278287 num_entries = min_t (int , pgcount , max_entries );
279288 ptep += map_idx_start ;
@@ -302,13 +311,13 @@ static size_t dart_unmap_pages(struct io_pgtable_ops *ops, unsigned long iova,
302311 if (WARN_ON (pgsize != cfg -> pgsize_bitmap || !pgcount ))
303312 return 0 ;
304313
305- ptep = dart_get_l2 (data , iova );
314+ ptep = dart_get_last (data , iova );
306315
307316 /* Valid L2 IOPTE pointer? */
308317 if (WARN_ON (!ptep ))
309318 return 0 ;
310319
311- unmap_idx_start = dart_get_l2_index (data , iova );
320+ unmap_idx_start = dart_get_last_index (data , iova );
312321 ptep += unmap_idx_start ;
313322
314323 max_entries = DART_PTES_PER_TABLE (data ) - unmap_idx_start ;
@@ -339,13 +348,13 @@ static phys_addr_t dart_iova_to_phys(struct io_pgtable_ops *ops,
339348 struct dart_io_pgtable * data = io_pgtable_ops_to_data (ops );
340349 dart_iopte pte , * ptep ;
341350
342- ptep = dart_get_l2 (data , iova );
351+ ptep = dart_get_last (data , iova );
343352
344353 /* Valid L2 IOPTE pointer? */
345354 if (!ptep )
346355 return 0 ;
347356
348- ptep += dart_get_l2_index (data , iova );
357+ ptep += dart_get_last_index (data , iova );
349358
350359 pte = READ_ONCE (* ptep );
351360 /* Found translation */
@@ -362,21 +371,37 @@ static struct dart_io_pgtable *
362371dart_alloc_pgtable (struct io_pgtable_cfg * cfg )
363372{
364373 struct dart_io_pgtable * data ;
365- int tbl_bits , bits_per_level , va_bits , pg_shift ;
374+ int levels , max_tbl_bits , tbl_bits , bits_per_level , va_bits , pg_shift ;
375+
376+ /*
377+ * Old 4K page DARTs can use up to 4 top-level tables.
378+ * Newer ones only ever use a maximum of 1.
379+ */
380+ if (cfg -> pgsize_bitmap == SZ_4K )
381+ max_tbl_bits = DART_MAX_TABLE_BITS ;
382+ else
383+ max_tbl_bits = 0 ;
366384
367385 pg_shift = __ffs (cfg -> pgsize_bitmap );
368386 bits_per_level = pg_shift - ilog2 (sizeof (dart_iopte ));
369387
370388 va_bits = cfg -> ias - pg_shift ;
371389
372- tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * DART_LEVELS ));
373- if ((1 << tbl_bits ) > DART_MAX_TABLES )
390+ levels = max_t (int , 2 , (va_bits - max_tbl_bits + bits_per_level - 1 ) / bits_per_level );
391+
392+ if (levels > (DART_MAX_LEVELS - 1 ))
393+ return NULL ;
394+
395+ tbl_bits = max_t (int , 0 , va_bits - (bits_per_level * levels ));
396+
397+ if (tbl_bits > max_tbl_bits )
374398 return NULL ;
375399
376400 data = kzalloc (sizeof (* data ), GFP_KERNEL );
377401 if (!data )
378402 return NULL ;
379403
404+ data -> levels = levels + 1 ; /* Table level counts as one level */
380405 data -> tbl_bits = tbl_bits ;
381406 data -> bits_per_level = bits_per_level ;
382407
@@ -412,6 +437,7 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
412437 return NULL ;
413438
414439 cfg -> apple_dart_cfg .n_ttbrs = 1 << data -> tbl_bits ;
440+ cfg -> apple_dart_cfg .n_levels = data -> levels ;
415441
416442 for (i = 0 ; i < cfg -> apple_dart_cfg .n_ttbrs ; ++ i ) {
417443 data -> pgd [i ] = __dart_alloc_pages (DART_GRANULE (data ), GFP_KERNEL );
@@ -431,24 +457,32 @@ apple_dart_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
431457 return NULL ;
432458}
433459
434- static void apple_dart_free_pgtable (struct io_pgtable * iop )
460+ static void apple_dart_free_pgtables (struct dart_io_pgtable * data , dart_iopte * ptep , int level )
435461{
436- struct dart_io_pgtable * data = io_pgtable_to_data (iop );
462+ dart_iopte * end ;
463+ dart_iopte * start = ptep ;
437464 int order = get_order (DART_GRANULE (data ));
438- dart_iopte * ptep , * end ;
439- int i ;
440465
441- for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
442- ptep = data -> pgd [i ];
466+ if (level > 1 ) {
443467 end = (void * )ptep + DART_GRANULE (data );
444468
445469 while (ptep != end ) {
446470 dart_iopte pte = * ptep ++ ;
447471
448472 if (pte )
449- iommu_free_pages ( iopte_deref (pte , data ), order );
473+ apple_dart_free_pgtables ( data , iopte_deref (pte , data ), level - 1 );
450474 }
451- iommu_free_pages (data -> pgd [i ], order );
475+ }
476+ iommu_free_pages (start , order );
477+ }
478+
479+ static void apple_dart_free_pgtable (struct io_pgtable * iop )
480+ {
481+ struct dart_io_pgtable * data = io_pgtable_to_data (iop );
482+ int i ;
483+
484+ for (i = 0 ; i < (1 << data -> tbl_bits ) && data -> pgd [i ]; ++ i ) {
485+ apple_dart_free_pgtables (data , data -> pgd [i ], data -> levels - 1 );
452486 }
453487
454488 kfree (data );
0 commit comments