@@ -241,42 +241,48 @@ static int bcm2712_iommu_map(struct iommu_domain *domain, unsigned long iova,
241
241
int prot , gfp_t gfp , size_t * mapped )
242
242
{
243
243
struct bcm2712_iommu * mmu = domain_to_mmu (domain );
244
-
245
- (void )gfp ;
246
- iova -= mmu -> dma_iova_offset ;
247
- if (iova >= APERTURE_BASE && iova + bytes <= APERTURE_TOP ) {
248
- unsigned int p ;
249
- u32 entry = MMMU_PTE_VALID | (pa >> MMU_PAGE_SHIFT );
250
- u32 align = (u32 )(iova | pa | bytes );
251
-
252
- /* large page and write enable flags */
253
- if (!(align & ((1 << HUGEPAGE_SHIFT ) - 1 )))
254
- entry |= FIELD_PREP (MMMU_PTE_PAGESIZE_MASK , 3 );
255
- else if (!(align & mmu -> superpage_mask ) && mmu -> superpage_mask )
256
- entry |= FIELD_PREP (MMMU_PTE_PAGESIZE_MASK , 2 );
257
- else if (!(align & mmu -> bigpage_mask ) && mmu -> bigpage_mask )
258
- entry |= FIELD_PREP (MMMU_PTE_PAGESIZE_MASK , 1 );
259
- if (prot & IOMMU_WRITE )
260
- entry |= MMMU_PTE_WRITEABLE ;
261
-
262
- /* Ensure tables are cache-coherent with CPU */
263
- if (!mmu -> dirty ) {
264
- dma_sync_sgtable_for_cpu (mmu -> dev , mmu -> sgt , DMA_TO_DEVICE );
265
- mmu -> dirty = true;
266
- }
267
-
268
- iova -= APERTURE_BASE ;
269
- for (p = iova >> MMU_PAGE_SHIFT ;
270
- p < (iova + bytes ) >> MMU_PAGE_SHIFT ; p ++ ) {
271
- mmu -> nmapped_pages += !(mmu -> tables [p ]);
272
- mmu -> tables [p ] = entry ++ ;
273
- }
274
- } else if (iova + bytes > APERTURE_BASE || iova != pa ) {
275
- dev_warn (mmu -> dev , "%s: iova=0x%lx pa=0x%llx size=0x%llx OUT OF RANGE!\n" ,
244
+ u32 entry = MMMU_PTE_VALID | (pa >> MMU_PAGE_SHIFT );
245
+ u32 align = (u32 )(iova | pa | bytes );
246
+ unsigned int p ;
247
+
248
+ /* Reject if at least the first page is not within our aperture */
249
+ if (iova < mmu -> dma_iova_offset + APERTURE_BASE ||
250
+ iova + bytes > mmu -> dma_iova_offset + APERTURE_TOP ) {
251
+ dev_warn (mmu -> dev , "%s: iova=0x%lx pa=0x%llx bytes=0x%lx OUT OF RANGE\n" ,
276
252
__func__ , iova ,
277
- (unsigned long long )pa , (unsigned long long )bytes );
253
+ (unsigned long long )pa , (unsigned long )bytes );
254
+ * mapped = 0 ;
255
+
278
256
return - EINVAL ;
279
257
}
258
+
259
+ /* large page and write enable flags */
260
+ if (!(align & ((1 << HUGEPAGE_SHIFT ) - 1 )))
261
+ entry |= FIELD_PREP (MMMU_PTE_PAGESIZE_MASK , 3 );
262
+ else if (!(align & mmu -> superpage_mask ) && mmu -> superpage_mask )
263
+ entry |= FIELD_PREP (MMMU_PTE_PAGESIZE_MASK , 2 );
264
+ else if (!(align & mmu -> bigpage_mask ) && mmu -> bigpage_mask )
265
+ entry |= FIELD_PREP (MMMU_PTE_PAGESIZE_MASK , 1 );
266
+ if (prot & IOMMU_WRITE )
267
+ entry |= MMMU_PTE_WRITEABLE ;
268
+
269
+ /* Ensure tables are cache-coherent with CPU */
270
+ if (!mmu -> dirty ) {
271
+ dma_sync_sgtable_for_cpu (mmu -> dev , mmu -> sgt , DMA_TO_DEVICE );
272
+ mmu -> dirty = true;
273
+ }
274
+
275
+ /* Make iova relative to table base; amalgamate count pages */
276
+ iova -= (mmu -> dma_iova_offset + APERTURE_BASE );
277
+ bytes = min (APERTURE_SIZE - iova , count * bytes );
278
+
279
+ /* Iterate over table by smallest native IOMMU page size */
280
+ for (p = iova >> MMU_PAGE_SHIFT ;
281
+ p < (iova + bytes ) >> MMU_PAGE_SHIFT ; p ++ ) {
282
+ mmu -> nmapped_pages += !(mmu -> tables [p ]);
283
+ mmu -> tables [p ] = entry ++ ;
284
+ }
285
+
280
286
* mapped = bytes ;
281
287
282
288
return 0 ;
@@ -287,42 +293,45 @@ static size_t bcm2712_iommu_unmap(struct iommu_domain *domain, unsigned long iov
287
293
struct iommu_iotlb_gather * gather )
288
294
{
289
295
struct bcm2712_iommu * mmu = domain_to_mmu (domain );
296
+ unsigned int p ;
290
297
291
- if (iova >= mmu -> dma_iova_offset + APERTURE_BASE &&
292
- iova + bytes <= mmu -> dma_iova_offset + APERTURE_TOP ) {
293
- unsigned int p ;
298
+ if (iova < mmu -> dma_iova_offset + APERTURE_BASE ||
299
+ iova + bytes > mmu -> dma_iova_offset + APERTURE_TOP )
300
+ return 0 ;
294
301
295
- /* Record just the lower and upper bounds in "gather" */
296
- if (gather ) {
297
- bool empty = (gather -> end <= gather -> start );
302
+ /* Record just the lower and upper bounds in "gather" */
303
+ if (gather ) {
304
+ bool empty = (gather -> end <= gather -> start );
298
305
299
- if (empty || gather -> start < iova )
300
- gather -> start = iova ;
301
- if (empty || gather -> end < iova + bytes )
302
- gather -> end = iova + bytes ;
303
- }
306
+ if (empty || gather -> start < iova )
307
+ gather -> start = iova ;
308
+ if (empty || gather -> end < iova + bytes )
309
+ gather -> end = iova + bytes ;
310
+ }
304
311
305
- /* Ensure tables are cache-coherent with CPU */
306
- if (!mmu -> dirty ) {
307
- dma_sync_sgtable_for_cpu (mmu -> dev , mmu -> sgt , DMA_TO_DEVICE );
308
- mmu -> dirty = true;
309
- }
312
+ /* Ensure tables are cache-coherent with CPU */
313
+ if (!mmu -> dirty ) {
314
+ dma_sync_sgtable_for_cpu (mmu -> dev , mmu -> sgt , DMA_TO_DEVICE );
315
+ mmu -> dirty = true;
316
+ }
310
317
311
- /* Clear table entries, this marks the addresses as illegal */
312
- iova -= (mmu -> dma_iova_offset + APERTURE_BASE );
313
- for (p = iova >> MMU_PAGE_SHIFT ;
314
- p < (iova + bytes ) >> MMU_PAGE_SHIFT ;
315
- p ++ ) {
316
- mmu -> nmapped_pages -= !!(mmu -> tables [p ]);
317
- mmu -> tables [p ] = 0 ;
318
- }
318
+ /* Make iova relative to table base; amalgamate count pages */
319
+ iova -= (mmu -> dma_iova_offset + APERTURE_BASE );
320
+ bytes = min (APERTURE_SIZE - iova , count * bytes );
321
+
322
+ /* Clear table entries, this marks the addresses as illegal */
323
+ for (p = iova >> MMU_PAGE_SHIFT ;
324
+ p < (iova + bytes ) >> MMU_PAGE_SHIFT ;
325
+ p ++ ) {
326
+ mmu -> nmapped_pages -= !!(mmu -> tables [p ]);
327
+ mmu -> tables [p ] = 0 ;
319
328
}
320
329
321
330
return bytes ;
322
331
}
323
332
324
333
static int bcm2712_iommu_sync_range (struct iommu_domain * domain ,
325
- unsigned long iova , size_t size )
334
+ unsigned long iova , size_t size )
326
335
{
327
336
struct bcm2712_iommu * mmu = domain_to_mmu (domain );
328
337
unsigned long iova_end ;
0 commit comments