@@ -1146,20 +1146,35 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm,
11461146 };
11471147 bool use_iova = dma_use_iova (& svm_pages -> state );
11481148
1149- if (use_iova )
1150- dma_iova_destroy (dev , & svm_pages -> state ,
1151- svm_pages -> state_offset ,
1152- svm_pages -> dma_addr [0 ].dir , 0 );
1149+ /*
1150+ * IOVA is reserved for the whole range but only the linked
1151+ * system pages (state_offset bytes) need unlinking; free the
1152+ * entire reservation to avoid leaking the device-page part.
1153+ * On the error path state_offset is 0, so just free it.
1154+ */
1155+ if (use_iova ) {
1156+ if (svm_pages -> state_offset )
1157+ dma_iova_unlink (dev , & svm_pages -> state , 0 ,
1158+ svm_pages -> state_offset ,
1159+ svm_pages -> dma_addr [0 ].dir , 0 );
1160+ dma_iova_free (dev , & svm_pages -> state );
1161+ }
11531162
11541163 for (i = 0 , j = 0 ; i < npages ; j ++ ) {
11551164 struct drm_pagemap_addr * addr = & svm_pages -> dma_addr [j ];
11561165
1157- if (!use_iova && addr -> proto == DRM_INTERCONNECT_SYSTEM )
1158- dma_unmap_page (dev ,
1159- addr -> addr ,
1160- PAGE_SIZE << addr -> order ,
1161- addr -> dir );
1162- else if (dpagemap && dpagemap -> ops -> device_unmap )
1166+ if (addr -> proto == DRM_INTERCONNECT_SYSTEM ) {
1167+ /*
1168+ * Linked IOVA pages were already torn down by
1169+ * the dma_iova_unlink()/dma_iova_free() above;
1170+ * only the non-IOVA mappings need unmap here.
1171+ */
1172+ if (!use_iova )
1173+ dma_unmap_page (dev ,
1174+ addr -> addr ,
1175+ PAGE_SIZE << addr -> order ,
1176+ addr -> dir );
1177+ } else if (dpagemap && dpagemap -> ops -> device_unmap )
11631178 dpagemap -> ops -> device_unmap (dpagemap ,
11641179 dev , addr );
11651180 i += 1 << addr -> order ;
@@ -1486,7 +1501,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
14861501 /* Unlock and restart mapping to allocate memory. */
14871502 drm_gpusvm_notifier_unlock (gpusvm );
14881503 svm_pages -> dma_addr =
1489- kvmalloc_objs (* svm_pages -> dma_addr , npages );
1504+ kvzalloc_objs (* svm_pages -> dma_addr , npages );
14901505 if (!svm_pages -> dma_addr ) {
14911506 err = - ENOMEM ;
14921507 goto err_free ;
@@ -1529,6 +1544,16 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
15291544 err = - EAGAIN ;
15301545 goto err_unmap ;
15311546 }
1547+
1548+ /*
1549+ * Set the dpagemap as soon as the first
1550+ * device page is mapped so the err_unmap path
1551+ * can device_unmap() the device mappings that
1552+ * have already been created.
1553+ */
1554+ drm_pagemap_get (dpagemap );
1555+ drm_pagemap_put (svm_pages -> dpagemap );
1556+ svm_pages -> dpagemap = dpagemap ;
15321557 }
15331558 svm_pages -> dma_addr [j ] =
15341559 dpagemap -> ops -> device_map (dpagemap ,
@@ -1596,12 +1621,8 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
15961621 goto err_unmap ;
15971622 }
15981623
1599- if (pagemap ) {
1624+ if (pagemap )
16001625 flags .has_devmem_pages = true;
1601- drm_pagemap_get (dpagemap );
1602- drm_pagemap_put (svm_pages -> dpagemap );
1603- svm_pages -> dpagemap = dpagemap ;
1604- }
16051626
16061627 /* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
16071628 WRITE_ONCE (svm_pages -> flags .__flags , flags .__flags );
0 commit comments