@@ -60,9 +60,11 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
6060{
6161 struct ib_device * dev = umem_odp -> umem .ibdev ;
6262 size_t page_size = 1UL << umem_odp -> page_shift ;
63+ struct hmm_dma_map * map ;
6364 unsigned long start ;
6465 unsigned long end ;
65- int ret ;
66+ size_t nr_entries ;
67+ int ret = 0 ;
6668
6769 umem_odp -> umem .is_odp = 1 ;
6870 mutex_init (& umem_odp -> umem_mutex );
@@ -75,9 +77,20 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
7577 if (unlikely (end < page_size ))
7678 return - EOVERFLOW ;
7779
78- ret = hmm_dma_map_alloc (dev -> dma_device , & umem_odp -> map ,
79- (end - start ) >> PAGE_SHIFT ,
80- 1 << umem_odp -> page_shift );
80+ nr_entries = (end - start ) >> PAGE_SHIFT ;
81+ if (!(nr_entries * PAGE_SIZE / page_size ))
82+ return - EINVAL ;
83+
84+ map = & umem_odp -> map ;
85+ if (ib_uses_virt_dma (dev )) {
86+ map -> pfn_list = kvcalloc (nr_entries , sizeof (* map -> pfn_list ),
87+ GFP_KERNEL | __GFP_NOWARN );
88+ if (!map -> pfn_list )
89+ ret = - ENOMEM ;
90+ } else
91+ ret = hmm_dma_map_alloc (dev -> dma_device , map ,
92+ (end - start ) >> PAGE_SHIFT ,
93+ 1 << umem_odp -> page_shift );
8194 if (ret )
8295 return ret ;
8396
@@ -90,7 +103,10 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp,
90103 return 0 ;
91104
92105out_free_map :
93- hmm_dma_map_free (dev -> dma_device , & umem_odp -> map );
106+ if (ib_uses_virt_dma (dev ))
107+ kfree (map -> pfn_list );
108+ else
109+ hmm_dma_map_free (dev -> dma_device , map );
94110 return ret ;
95111}
96112
@@ -259,7 +275,10 @@ static void ib_umem_odp_free(struct ib_umem_odp *umem_odp)
259275 ib_umem_end (umem_odp ));
260276 mutex_unlock (& umem_odp -> umem_mutex );
261277 mmu_interval_notifier_remove (& umem_odp -> notifier );
262- hmm_dma_map_free (dev -> dma_device , & umem_odp -> map );
278+ if (ib_uses_virt_dma (dev ))
279+ kfree (umem_odp -> map .pfn_list );
280+ else
281+ hmm_dma_map_free (dev -> dma_device , & umem_odp -> map );
263282}
264283
265284void ib_umem_odp_release (struct ib_umem_odp * umem_odp )
0 commit comments