@@ -94,6 +94,7 @@ struct gvt_dma {
9494 struct rb_node dma_addr_node ;
9595 gfn_t gfn ;
9696 dma_addr_t dma_addr ;
97+ unsigned long size ;
9798 struct kref ref ;
9899};
99100
@@ -106,45 +107,103 @@ static int kvmgt_guest_init(struct mdev_device *mdev);
106107static void intel_vgpu_release_work (struct work_struct * work );
107108static bool kvmgt_guest_exit (struct kvmgt_guest_info * info );
108109
110+ static void gvt_unpin_guest_page (struct intel_vgpu * vgpu , unsigned long gfn ,
111+ unsigned long size )
112+ {
113+ int total_pages ;
114+ int npage ;
115+ int ret ;
116+
117+ total_pages = roundup (size , PAGE_SIZE ) / PAGE_SIZE ;
118+
119+ for (npage = 0 ; npage < total_pages ; npage ++ ) {
120+ unsigned long cur_gfn = gfn + npage ;
121+
122+ ret = vfio_unpin_pages (mdev_dev (vgpu -> vdev .mdev ), & cur_gfn , 1 );
123+ WARN_ON (ret != 1 );
124+ }
125+ }
126+
127+ /* Pin a normal or compound guest page for dma. */
128+ static int gvt_pin_guest_page (struct intel_vgpu * vgpu , unsigned long gfn ,
129+ unsigned long size , struct page * * page )
130+ {
131+ unsigned long base_pfn = 0 ;
132+ int total_pages ;
133+ int npage ;
134+ int ret ;
135+
136+ total_pages = roundup (size , PAGE_SIZE ) / PAGE_SIZE ;
137+ /*
138+ * We pin the pages one-by-one to avoid allocating a big arrary
139+ * on stack to hold pfns.
140+ */
141+ for (npage = 0 ; npage < total_pages ; npage ++ ) {
142+ unsigned long cur_gfn = gfn + npage ;
143+ unsigned long pfn ;
144+
145+ ret = vfio_pin_pages (mdev_dev (vgpu -> vdev .mdev ), & cur_gfn , 1 ,
146+ IOMMU_READ | IOMMU_WRITE , & pfn );
147+ if (ret != 1 ) {
148+ gvt_vgpu_err ("vfio_pin_pages failed for gfn 0x%lx, ret %d\n" ,
149+ cur_gfn , ret );
150+ goto err ;
151+ }
152+
153+ if (!pfn_valid (pfn )) {
154+ gvt_vgpu_err ("pfn 0x%lx is not mem backed\n" , pfn );
155+ npage ++ ;
156+ ret = - EFAULT ;
157+ goto err ;
158+ }
159+
160+ if (npage == 0 )
161+ base_pfn = pfn ;
162+ else if (base_pfn + npage != pfn ) {
163+ gvt_vgpu_err ("The pages are not continuous\n" );
164+ ret = - EINVAL ;
165+ npage ++ ;
166+ goto err ;
167+ }
168+ }
169+
170+ * page = pfn_to_page (base_pfn );
171+ return 0 ;
172+ err :
173+ gvt_unpin_guest_page (vgpu , gfn , npage * PAGE_SIZE );
174+ return ret ;
175+ }
176+
109177static int gvt_dma_map_page (struct intel_vgpu * vgpu , unsigned long gfn ,
110- dma_addr_t * dma_addr )
178+ dma_addr_t * dma_addr , unsigned long size )
111179{
112180 struct device * dev = & vgpu -> gvt -> dev_priv -> drm .pdev -> dev ;
113- struct page * page ;
114- unsigned long pfn ;
181+ struct page * page = NULL ;
115182 int ret ;
116183
117- /* Pin the page first. */
118- ret = vfio_pin_pages (mdev_dev (vgpu -> vdev .mdev ), & gfn , 1 ,
119- IOMMU_READ | IOMMU_WRITE , & pfn );
120- if (ret != 1 ) {
121- gvt_vgpu_err ("vfio_pin_pages failed for gfn 0x%lx: %d\n" ,
122- gfn , ret );
123- return - EINVAL ;
124- }
184+ ret = gvt_pin_guest_page (vgpu , gfn , size , & page );
185+ if (ret )
186+ return ret ;
125187
126188 /* Setup DMA mapping. */
127- page = pfn_to_page (pfn );
128- * dma_addr = dma_map_page (dev , page , 0 , PAGE_SIZE ,
129- PCI_DMA_BIDIRECTIONAL );
130- if (dma_mapping_error (dev , * dma_addr )) {
131- gvt_vgpu_err ("DMA mapping failed for gfn 0x%lx\n" , gfn );
132- vfio_unpin_pages (mdev_dev (vgpu -> vdev .mdev ), & gfn , 1 );
133- return - ENOMEM ;
189+ * dma_addr = dma_map_page (dev , page , 0 , size , PCI_DMA_BIDIRECTIONAL );
190+ ret = dma_mapping_error (dev , * dma_addr );
191+ if (ret ) {
192+ gvt_vgpu_err ("DMA mapping failed for pfn 0x%lx, ret %d\n" ,
193+ page_to_pfn (page ), ret );
194+ gvt_unpin_guest_page (vgpu , gfn , size );
134195 }
135196
136- return 0 ;
197+ return ret ;
137198}
138199
139200static void gvt_dma_unmap_page (struct intel_vgpu * vgpu , unsigned long gfn ,
140- dma_addr_t dma_addr )
201+ dma_addr_t dma_addr , unsigned long size )
141202{
142203 struct device * dev = & vgpu -> gvt -> dev_priv -> drm .pdev -> dev ;
143- int ret ;
144204
145- dma_unmap_page (dev , dma_addr , PAGE_SIZE , PCI_DMA_BIDIRECTIONAL );
146- ret = vfio_unpin_pages (mdev_dev (vgpu -> vdev .mdev ), & gfn , 1 );
147- WARN_ON (ret != 1 );
205+ dma_unmap_page (dev , dma_addr , size , PCI_DMA_BIDIRECTIONAL );
206+ gvt_unpin_guest_page (vgpu , gfn , size );
148207}
149208
150209static struct gvt_dma * __gvt_cache_find_dma_addr (struct intel_vgpu * vgpu ,
@@ -185,7 +244,7 @@ static struct gvt_dma *__gvt_cache_find_gfn(struct intel_vgpu *vgpu, gfn_t gfn)
185244}
186245
187246static int __gvt_cache_add (struct intel_vgpu * vgpu , gfn_t gfn ,
188- dma_addr_t dma_addr )
247+ dma_addr_t dma_addr , unsigned long size )
189248{
190249 struct gvt_dma * new , * itr ;
191250 struct rb_node * * link , * parent = NULL ;
@@ -197,6 +256,7 @@ static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn,
197256 new -> vgpu = vgpu ;
198257 new -> gfn = gfn ;
199258 new -> dma_addr = dma_addr ;
259+ new -> size = size ;
200260 kref_init (& new -> ref );
201261
202262 /* gfn_cache maps gfn to struct gvt_dma. */
@@ -254,7 +314,7 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu)
254314 break ;
255315 }
256316 dma = rb_entry (node , struct gvt_dma , gfn_node );
257- gvt_dma_unmap_page (vgpu , dma -> gfn , dma -> dma_addr );
317+ gvt_dma_unmap_page (vgpu , dma -> gfn , dma -> dma_addr , dma -> size );
258318 __gvt_cache_remove_entry (vgpu , dma );
259319 mutex_unlock (& vgpu -> vdev .cache_lock );
260320 }
@@ -509,7 +569,8 @@ static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
509569 if (!entry )
510570 continue ;
511571
512- gvt_dma_unmap_page (vgpu , entry -> gfn , entry -> dma_addr );
572+ gvt_dma_unmap_page (vgpu , entry -> gfn , entry -> dma_addr ,
573+ entry -> size );
513574 __gvt_cache_remove_entry (vgpu , entry );
514575 }
515576 mutex_unlock (& vgpu -> vdev .cache_lock );
@@ -1616,7 +1677,7 @@ static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn)
16161677}
16171678
16181679int kvmgt_dma_map_guest_page (unsigned long handle , unsigned long gfn ,
1619- dma_addr_t * dma_addr )
1680+ unsigned long size , dma_addr_t * dma_addr )
16201681{
16211682 struct kvmgt_guest_info * info ;
16221683 struct intel_vgpu * vgpu ;
@@ -1633,11 +1694,11 @@ int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
16331694
16341695 entry = __gvt_cache_find_gfn (info -> vgpu , gfn );
16351696 if (!entry ) {
1636- ret = gvt_dma_map_page (vgpu , gfn , dma_addr );
1697+ ret = gvt_dma_map_page (vgpu , gfn , dma_addr , size );
16371698 if (ret )
16381699 goto err_unlock ;
16391700
1640- ret = __gvt_cache_add (info -> vgpu , gfn , * dma_addr );
1701+ ret = __gvt_cache_add (info -> vgpu , gfn , * dma_addr , size );
16411702 if (ret )
16421703 goto err_unmap ;
16431704 } else {
@@ -1649,7 +1710,7 @@ int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
16491710 return 0 ;
16501711
16511712err_unmap :
1652- gvt_dma_unmap_page (vgpu , gfn , * dma_addr );
1713+ gvt_dma_unmap_page (vgpu , gfn , * dma_addr , size );
16531714err_unlock :
16541715 mutex_unlock (& info -> vgpu -> vdev .cache_lock );
16551716 return ret ;
@@ -1659,7 +1720,8 @@ static void __gvt_dma_release(struct kref *ref)
16591720{
16601721 struct gvt_dma * entry = container_of (ref , typeof (* entry ), ref );
16611722
1662- gvt_dma_unmap_page (entry -> vgpu , entry -> gfn , entry -> dma_addr );
1723+ gvt_dma_unmap_page (entry -> vgpu , entry -> gfn , entry -> dma_addr ,
1724+ entry -> size );
16631725 __gvt_cache_remove_entry (entry -> vgpu , entry );
16641726}
16651727
0 commit comments