@@ -468,134 +468,133 @@ static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr,
468468 }
469469}
470470
471- phys_addr_t swiotlb_tbl_map_single (struct device * hwdev , phys_addr_t orig_addr ,
472- size_t mapping_size , size_t alloc_size ,
473- enum dma_data_direction dir , unsigned long attrs )
474- {
475- dma_addr_t tbl_dma_addr = phys_to_dma_unencrypted (hwdev , io_tlb_start );
476- unsigned long flags ;
477- phys_addr_t tlb_addr ;
478- unsigned int nslots , stride , index , wrap ;
479- int i ;
480- unsigned long mask ;
481- unsigned long offset_slots ;
482- unsigned long max_slots ;
483- unsigned long tmp_io_tlb_used ;
484-
485- if (no_iotlb_memory )
486- panic ("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer" );
487-
488- if (mem_encrypt_active ())
489- pr_warn_once ("Memory encryption is active and system is using DMA bounce buffers\n" );
471+ #define slot_addr (start , idx ) ((start) + ((idx) << IO_TLB_SHIFT))
490472
491- if (mapping_size > alloc_size ) {
492- dev_warn_once (hwdev , "Invalid sizes (mapping: %zd bytes, alloc: %zd bytes)" ,
493- mapping_size , alloc_size );
494- return (phys_addr_t )DMA_MAPPING_ERROR ;
495- }
496-
497- mask = dma_get_seg_boundary (hwdev );
473+ /*
474+ * Carefully handle integer overflow which can occur when boundary_mask == ~0UL.
475+ */
476+ static inline unsigned long get_max_slots (unsigned long boundary_mask )
477+ {
478+ if (boundary_mask == ~0UL )
479+ return 1UL << (BITS_PER_LONG - IO_TLB_SHIFT );
480+ return nr_slots (boundary_mask + 1 );
481+ }
498482
499- tbl_dma_addr &= mask ;
483+ static unsigned int wrap_index (unsigned int index )
484+ {
485+ if (index >= io_tlb_nslabs )
486+ return 0 ;
487+ return index ;
488+ }
500489
501- offset_slots = nr_slots (tbl_dma_addr );
490+ /*
491+ * Find a suitable number of IO TLB entries size that will fit this request and
492+ * allocate a buffer from that IO TLB pool.
493+ */
494+ static int find_slots (struct device * dev , size_t alloc_size )
495+ {
496+ unsigned long boundary_mask = dma_get_seg_boundary (dev );
497+ dma_addr_t tbl_dma_addr =
498+ phys_to_dma_unencrypted (dev , io_tlb_start ) & boundary_mask ;
499+ unsigned long max_slots = get_max_slots (boundary_mask );
500+ unsigned int nslots = nr_slots (alloc_size ), stride = 1 ;
501+ unsigned int index , wrap , count = 0 , i ;
502+ unsigned long flags ;
502503
503- /*
504- * Carefully handle integer overflow which can occur when mask == ~0UL.
505- */
506- max_slots = mask + 1
507- ? nr_slots (mask + 1 )
508- : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT );
504+ BUG_ON (!nslots );
509505
510506 /*
511507 * For mappings greater than or equal to a page, we limit the stride
512508 * (and hence alignment) to a page size.
513509 */
514- nslots = nr_slots (alloc_size );
515510 if (alloc_size >= PAGE_SIZE )
516- stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT ));
517- else
518- stride = 1 ;
511+ stride <<= (PAGE_SHIFT - IO_TLB_SHIFT );
519512
520- BUG_ON (!nslots );
521-
522- /*
523- * Find suitable number of IO TLB entries size that will fit this
524- * request and allocate a buffer from that IO TLB pool.
525- */
526513 spin_lock_irqsave (& io_tlb_lock , flags );
527-
528514 if (unlikely (nslots > io_tlb_nslabs - io_tlb_used ))
529515 goto not_found ;
530516
531- index = ALIGN (io_tlb_index , stride );
532- if (index >= io_tlb_nslabs )
533- index = 0 ;
534- wrap = index ;
535-
517+ index = wrap = wrap_index (ALIGN (io_tlb_index , stride ));
536518 do {
537- while (iommu_is_span_boundary (index , nslots , offset_slots ,
538- max_slots )) {
539- index += stride ;
540- if (index >= io_tlb_nslabs )
541- index = 0 ;
542- if (index == wrap )
543- goto not_found ;
544- }
545-
546519 /*
547520 * If we find a slot that indicates we have 'nslots' number of
548521 * contiguous buffers, we allocate the buffers from that slot
549522 * and mark the entries as '0' indicating unavailable.
550523 */
551- if (io_tlb_list [index ] >= nslots ) {
552- int count = 0 ;
553-
554- for (i = index ; i < (int ) (index + nslots ); i ++ )
555- io_tlb_list [i ] = 0 ;
556- for (i = index - 1 ;
557- io_tlb_offset (i ) != IO_TLB_SEGSIZE - 1 &&
558- io_tlb_list [i ]; i -- )
559- io_tlb_list [i ] = ++ count ;
560- tlb_addr = io_tlb_start + (index << IO_TLB_SHIFT );
561-
562- /*
563- * Update the indices to avoid searching in the next
564- * round.
565- */
566- io_tlb_index = ((index + nslots ) < io_tlb_nslabs
567- ? (index + nslots ) : 0 );
568-
569- goto found ;
524+ if (!iommu_is_span_boundary (index , nslots ,
525+ nr_slots (tbl_dma_addr ),
526+ max_slots )) {
527+ if (io_tlb_list [index ] >= nslots )
528+ goto found ;
570529 }
571- index += stride ;
572- if (index >= io_tlb_nslabs )
573- index = 0 ;
530+ index = wrap_index (index + stride );
574531 } while (index != wrap );
575532
576533not_found :
577- tmp_io_tlb_used = io_tlb_used ;
578-
579534 spin_unlock_irqrestore (& io_tlb_lock , flags );
580- if (!(attrs & DMA_ATTR_NO_WARN ) && printk_ratelimit ())
581- dev_warn (hwdev , "swiotlb buffer is full (sz: %zd bytes), total %lu (slots), used %lu (slots)\n" ,
582- alloc_size , io_tlb_nslabs , tmp_io_tlb_used );
583- return (phys_addr_t )DMA_MAPPING_ERROR ;
535+ return -1 ;
536+
584537found :
538+ for (i = index ; i < index + nslots ; i ++ )
539+ io_tlb_list [i ] = 0 ;
540+ for (i = index - 1 ;
541+ io_tlb_offset (i ) != IO_TLB_SEGSIZE - 1 &&
542+ io_tlb_list [i ]; i -- )
543+ io_tlb_list [i ] = ++ count ;
544+
545+ /*
546+ * Update the indices to avoid searching in the next round.
547+ */
548+ if (index + nslots < io_tlb_nslabs )
549+ io_tlb_index = index + nslots ;
550+ else
551+ io_tlb_index = 0 ;
585552 io_tlb_used += nslots ;
553+
586554 spin_unlock_irqrestore (& io_tlb_lock , flags );
555+ return index ;
556+ }
557+
558+ phys_addr_t swiotlb_tbl_map_single (struct device * dev , phys_addr_t orig_addr ,
559+ size_t mapping_size , size_t alloc_size ,
560+ enum dma_data_direction dir , unsigned long attrs )
561+ {
562+ unsigned int index , i ;
563+ phys_addr_t tlb_addr ;
564+
565+ if (no_iotlb_memory )
566+ panic ("Can not allocate SWIOTLB buffer earlier and can't now provide you with the DMA bounce buffer" );
567+
568+ if (mem_encrypt_active ())
569+ pr_warn_once ("Memory encryption is active and system is using DMA bounce buffers\n" );
570+
571+ if (mapping_size > alloc_size ) {
572+ dev_warn_once (dev , "Invalid sizes (mapping: %zd bytes, alloc: %zd bytes)" ,
573+ mapping_size , alloc_size );
574+ return (phys_addr_t )DMA_MAPPING_ERROR ;
575+ }
576+
577+ index = find_slots (dev , alloc_size );
578+ if (index == -1 ) {
579+ if (!(attrs & DMA_ATTR_NO_WARN ))
580+ dev_warn_ratelimited (dev ,
581+ "swiotlb buffer is full (sz: %zd bytes), total %lu (slots), used %lu (slots)\n" ,
582+ alloc_size , io_tlb_nslabs , io_tlb_used );
583+ return (phys_addr_t )DMA_MAPPING_ERROR ;
584+ }
587585
588586 /*
589587 * Save away the mapping from the original address to the DMA address.
590588 * This is needed when we sync the memory. Then we sync the buffer if
591589 * needed.
592590 */
593- for (i = 0 ; i < nslots ; i ++ )
594- io_tlb_orig_addr [index + i ] = orig_addr + (i << IO_TLB_SHIFT );
591+ for (i = 0 ; i < nr_slots (alloc_size ); i ++ )
592+ io_tlb_orig_addr [index + i ] = slot_addr (orig_addr , i );
593+
594+ tlb_addr = slot_addr (io_tlb_start , index );
595595 if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC ) &&
596596 (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL ))
597597 swiotlb_bounce (orig_addr , tlb_addr , mapping_size , DMA_TO_DEVICE );
598-
599598 return tlb_addr ;
600599}
601600
0 commit comments