@@ -241,42 +241,48 @@ static int bcm2712_iommu_map(struct iommu_domain *domain, unsigned long iova,
241241 int prot , gfp_t gfp , size_t * mapped )
242242{
243243 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" ,
276252 __func__ , iova ,
277- (unsigned long long )pa , (unsigned long long )bytes );
253+ (unsigned long long )pa , (unsigned long )bytes );
254+ * mapped = 0 ;
255+
278256 return - EINVAL ;
279257 }
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+
280286 * mapped = bytes ;
281287
282288 return 0 ;
@@ -287,42 +293,45 @@ static size_t bcm2712_iommu_unmap(struct iommu_domain *domain, unsigned long iov
287293 struct iommu_iotlb_gather * gather )
288294{
289295 struct bcm2712_iommu * mmu = domain_to_mmu (domain );
296+ unsigned int p ;
290297
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 ;
294301
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 );
298305
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+ }
304311
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+ }
310317
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 ;
319328 }
320329
321330 return bytes ;
322331}
323332
324333static int bcm2712_iommu_sync_range (struct iommu_domain * domain ,
325- unsigned long iova , size_t size )
334+ unsigned long iova , size_t size )
326335{
327336 struct bcm2712_iommu * mmu = domain_to_mmu (domain );
328337 unsigned long iova_end ;
0 commit comments