@@ -232,20 +232,23 @@ static void __arm_lpae_free_pages(void *pages, size_t size,
232232 free_pages ((unsigned long )pages , get_order (size ));
233233}
234234
235- static void __arm_lpae_sync_pte (arm_lpae_iopte * ptep ,
235+ static void __arm_lpae_sync_pte (arm_lpae_iopte * ptep , int num_entries ,
236236 struct io_pgtable_cfg * cfg )
237237{
238238 dma_sync_single_for_device (cfg -> iommu_dev , __arm_lpae_dma_addr (ptep ),
239- sizeof (* ptep ), DMA_TO_DEVICE );
239+ sizeof (* ptep ) * num_entries , DMA_TO_DEVICE );
240240}
241241
242242static void __arm_lpae_set_pte (arm_lpae_iopte * ptep , arm_lpae_iopte pte ,
243- struct io_pgtable_cfg * cfg )
243+ int num_entries , struct io_pgtable_cfg * cfg )
244244{
245- * ptep = pte ;
245+ int i ;
246+
247+ for (i = 0 ; i < num_entries ; i ++ )
248+ ptep [i ] = pte ;
246249
247250 if (!cfg -> coherent_walk )
248- __arm_lpae_sync_pte (ptep , cfg );
251+ __arm_lpae_sync_pte (ptep , num_entries , cfg );
249252}
250253
251254static size_t __arm_lpae_unmap (struct arm_lpae_io_pgtable * data ,
@@ -255,47 +258,54 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
255258
256259static void __arm_lpae_init_pte (struct arm_lpae_io_pgtable * data ,
257260 phys_addr_t paddr , arm_lpae_iopte prot ,
258- int lvl , arm_lpae_iopte * ptep )
261+ int lvl , int num_entries , arm_lpae_iopte * ptep )
259262{
260263 arm_lpae_iopte pte = prot ;
264+ struct io_pgtable_cfg * cfg = & data -> iop .cfg ;
265+ size_t sz = ARM_LPAE_BLOCK_SIZE (lvl , data );
266+ int i ;
261267
262268 if (data -> iop .fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1 )
263269 pte |= ARM_LPAE_PTE_TYPE_PAGE ;
264270 else
265271 pte |= ARM_LPAE_PTE_TYPE_BLOCK ;
266272
267- pte |= paddr_to_iopte (paddr , data );
273+ for (i = 0 ; i < num_entries ; i ++ )
274+ ptep [i ] = pte | paddr_to_iopte (paddr + i * sz , data );
268275
269- __arm_lpae_set_pte (ptep , pte , & data -> iop .cfg );
276+ if (!cfg -> coherent_walk )
277+ __arm_lpae_sync_pte (ptep , num_entries , cfg );
270278}
271279
272280static int arm_lpae_init_pte (struct arm_lpae_io_pgtable * data ,
273281 unsigned long iova , phys_addr_t paddr ,
274- arm_lpae_iopte prot , int lvl ,
282+ arm_lpae_iopte prot , int lvl , int num_entries ,
275283 arm_lpae_iopte * ptep )
276284{
277- arm_lpae_iopte pte = * ptep ;
278-
279- if (iopte_leaf (pte , lvl , data -> iop .fmt )) {
280- /* We require an unmap first */
281- WARN_ON (!selftest_running );
282- return - EEXIST ;
283- } else if (iopte_type (pte ) == ARM_LPAE_PTE_TYPE_TABLE ) {
284- /*
285- * We need to unmap and free the old table before
286- * overwriting it with a block entry.
287- */
288- arm_lpae_iopte * tblp ;
289- size_t sz = ARM_LPAE_BLOCK_SIZE (lvl , data );
290-
291- tblp = ptep - ARM_LPAE_LVL_IDX (iova , lvl , data );
292- if (__arm_lpae_unmap (data , NULL , iova , sz , lvl , tblp ) != sz ) {
293- WARN_ON (1 );
294- return - EINVAL ;
285+ int i ;
286+
287+ for (i = 0 ; i < num_entries ; i ++ )
288+ if (iopte_leaf (ptep [i ], lvl , data -> iop .fmt )) {
289+ /* We require an unmap first */
290+ WARN_ON (!selftest_running );
291+ return - EEXIST ;
292+ } else if (iopte_type (ptep [i ]) == ARM_LPAE_PTE_TYPE_TABLE ) {
293+ /*
294+ * We need to unmap and free the old table before
295+ * overwriting it with a block entry.
296+ */
297+ arm_lpae_iopte * tblp ;
298+ size_t sz = ARM_LPAE_BLOCK_SIZE (lvl , data );
299+
300+ tblp = ptep - ARM_LPAE_LVL_IDX (iova , lvl , data );
301+ if (__arm_lpae_unmap (data , NULL , iova + i * sz , sz ,
302+ lvl , tblp ) != sz ) {
303+ WARN_ON (1 );
304+ return - EINVAL ;
305+ }
295306 }
296- }
297307
298- __arm_lpae_init_pte (data , paddr , prot , lvl , ptep );
308+ __arm_lpae_init_pte (data , paddr , prot , lvl , num_entries , ptep );
299309 return 0 ;
300310}
301311
@@ -323,7 +333,7 @@ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table,
323333 return old ;
324334
325335 /* Even if it's not ours, there's no point waiting; just kick it */
326- __arm_lpae_sync_pte (ptep , cfg );
336+ __arm_lpae_sync_pte (ptep , 1 , cfg );
327337 if (old == curr )
328338 WRITE_ONCE (* ptep , new | ARM_LPAE_PTE_SW_SYNC );
329339
@@ -344,7 +354,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
344354
345355 /* If we can install a leaf entry at this level, then do so */
346356 if (size == block_size )
347- return arm_lpae_init_pte (data , iova , paddr , prot , lvl , ptep );
357+ return arm_lpae_init_pte (data , iova , paddr , prot , lvl , 1 , ptep );
348358
349359 /* We can't allocate tables at the final level */
350360 if (WARN_ON (lvl >= ARM_LPAE_MAX_LEVELS - 1 ))
@@ -361,7 +371,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova,
361371 if (pte )
362372 __arm_lpae_free_pages (cptep , tblsz , cfg );
363373 } else if (!cfg -> coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC )) {
364- __arm_lpae_sync_pte (ptep , cfg );
374+ __arm_lpae_sync_pte (ptep , 1 , cfg );
365375 }
366376
367377 if (pte && !iopte_leaf (pte , lvl , data -> iop .fmt )) {
@@ -543,7 +553,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
543553 if (i == unmap_idx )
544554 continue ;
545555
546- __arm_lpae_init_pte (data , blk_paddr , pte , lvl , & tablep [i ]);
556+ __arm_lpae_init_pte (data , blk_paddr , pte , lvl , 1 , & tablep [i ]);
547557 }
548558
549559 pte = arm_lpae_install_table (tablep , ptep , blk_pte , cfg );
@@ -585,7 +595,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
585595
586596 /* If the size matches this level, we're in the right place */
587597 if (size == ARM_LPAE_BLOCK_SIZE (lvl , data )) {
588- __arm_lpae_set_pte (ptep , 0 , & iop -> cfg );
598+ __arm_lpae_set_pte (ptep , 0 , 1 , & iop -> cfg );
589599
590600 if (!iopte_leaf (pte , lvl , iop -> fmt )) {
591601 /* Also flush any partial walks */
0 commit comments