@@ -373,6 +373,12 @@ static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
373373 *
374374 * This function initializes the GPU SVM.
375375 *
376+ * Note: If only using the simple drm_gpusvm_pages API (get/unmap/free),
377+ * then only @gpusvm, @name, and @drm are expected. However, the same base
378+ * @gpusvm can also be used with both modes together in which case the full
379+ * setup is needed, where the core drm_gpusvm_pages API will simply never use
380+ * the other fields.
381+ *
376382 * Return: 0 on success, a negative error code on failure.
377383 */
378384int drm_gpusvm_init (struct drm_gpusvm * gpusvm ,
@@ -383,8 +389,16 @@ int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
383389 const struct drm_gpusvm_ops * ops ,
384390 const unsigned long * chunk_sizes , int num_chunks )
385391{
386- if (!ops -> invalidate || !num_chunks )
387- return - EINVAL ;
392+ if (mm ) {
393+ if (!ops -> invalidate || !num_chunks )
394+ return - EINVAL ;
395+ mmgrab (mm );
396+ } else {
397+ /* No full SVM mode, only core drm_gpusvm_pages API. */
398+ if (ops || num_chunks || mm_range || notifier_size ||
399+ device_private_page_owner )
400+ return - EINVAL ;
401+ }
388402
389403 gpusvm -> name = name ;
390404 gpusvm -> drm = drm ;
@@ -397,7 +411,6 @@ int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
397411 gpusvm -> chunk_sizes = chunk_sizes ;
398412 gpusvm -> num_chunks = num_chunks ;
399413
400- mmgrab (mm );
401414 gpusvm -> root = RB_ROOT_CACHED ;
402415 INIT_LIST_HEAD (& gpusvm -> notifier_list );
403416
@@ -489,7 +502,8 @@ void drm_gpusvm_fini(struct drm_gpusvm *gpusvm)
489502 drm_gpusvm_range_remove (gpusvm , range );
490503 }
491504
492- mmdrop (gpusvm -> mm );
505+ if (gpusvm -> mm )
506+ mmdrop (gpusvm -> mm );
493507 WARN_ON (!RB_EMPTY_ROOT (& gpusvm -> root .rb_root ));
494508}
495509EXPORT_SYMBOL_GPL (drm_gpusvm_fini );
@@ -1044,6 +1058,27 @@ static void __drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm,
10441058 }
10451059}
10461060
1061+ /**
1062+ * drm_gpusvm_free_pages() - Free dma-mapping associated with GPU SVM pages
1063+ * struct
1064+ * @gpusvm: Pointer to the GPU SVM structure
1065+ * @svm_pages: Pointer to the GPU SVM pages structure
1066+ * @npages: Number of mapped pages
1067+ *
1068+ * This function unmaps and frees the dma address array associated with a GPU
1069+ * SVM pages struct.
1070+ */
1071+ void drm_gpusvm_free_pages (struct drm_gpusvm * gpusvm ,
1072+ struct drm_gpusvm_pages * svm_pages ,
1073+ unsigned long npages )
1074+ {
1075+ drm_gpusvm_notifier_lock (gpusvm );
1076+ __drm_gpusvm_unmap_pages (gpusvm , svm_pages , npages );
1077+ __drm_gpusvm_free_pages (gpusvm , svm_pages );
1078+ drm_gpusvm_notifier_unlock (gpusvm );
1079+ }
1080+ EXPORT_SYMBOL_GPL (drm_gpusvm_free_pages );
1081+
10471082/**
10481083 * drm_gpusvm_range_remove() - Remove GPU SVM range
10491084 * @gpusvm: Pointer to the GPU SVM structure
@@ -1220,13 +1255,12 @@ static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm,
12201255 *
12211256 * Return: 0 on success, negative error code on failure.
12221257 */
1223- static int drm_gpusvm_get_pages (struct drm_gpusvm * gpusvm ,
1224- struct drm_gpusvm_pages * svm_pages ,
1225- struct mm_struct * mm ,
1226- struct mmu_interval_notifier * notifier ,
1227- unsigned long pages_start ,
1228- unsigned long pages_end ,
1229- const struct drm_gpusvm_ctx * ctx )
1258+ int drm_gpusvm_get_pages (struct drm_gpusvm * gpusvm ,
1259+ struct drm_gpusvm_pages * svm_pages ,
1260+ struct mm_struct * mm ,
1261+ struct mmu_interval_notifier * notifier ,
1262+ unsigned long pages_start , unsigned long pages_end ,
1263+ const struct drm_gpusvm_ctx * ctx )
12301264{
12311265 struct hmm_range hmm_range = {
12321266 .default_flags = HMM_PFN_REQ_FAULT | (ctx -> read_only ? 0 :
@@ -1415,6 +1449,7 @@ static int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
14151449 goto retry ;
14161450 return err ;
14171451}
1452+ EXPORT_SYMBOL_GPL (drm_gpusvm_get_pages );
14181453
14191454/**
14201455 * drm_gpusvm_range_get_pages() - Get pages for a GPU SVM range
@@ -1451,10 +1486,10 @@ EXPORT_SYMBOL_GPL(drm_gpusvm_range_get_pages);
14511486 * Must be called in the invalidate() callback of the corresponding notifier for
14521487 * IOMMU security model.
14531488 */
1454- static void drm_gpusvm_unmap_pages (struct drm_gpusvm * gpusvm ,
1455- struct drm_gpusvm_pages * svm_pages ,
1456- unsigned long npages ,
1457- const struct drm_gpusvm_ctx * ctx )
1489+ void drm_gpusvm_unmap_pages (struct drm_gpusvm * gpusvm ,
1490+ struct drm_gpusvm_pages * svm_pages ,
1491+ unsigned long npages ,
1492+ const struct drm_gpusvm_ctx * ctx )
14581493{
14591494 if (ctx -> in_notifier )
14601495 lockdep_assert_held_write (& gpusvm -> notifier_lock );
@@ -1466,6 +1501,7 @@ static void drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm,
14661501 if (!ctx -> in_notifier )
14671502 drm_gpusvm_notifier_unlock (gpusvm );
14681503}
1504+ EXPORT_SYMBOL_GPL (drm_gpusvm_unmap_pages );
14691505
14701506/**
14711507 * drm_gpusvm_range_unmap_pages() - Unmap pages associated with a GPU SVM range
0 commit comments