xref: /linux/drivers/gpu/drm/drm_gpusvm.c (revision c06b6cde2a1c3bcbb561bd57bb6f34eae9030921)
1 // SPDX-License-Identifier: GPL-2.0-only OR MIT
2 /*
3  * Copyright © 2024 Intel Corporation
4  *
5  * Authors:
6  *     Matthew Brost <matthew.brost@intel.com>
7  */
8 
9 #include <linux/dma-mapping.h>
10 #include <linux/export.h>
11 #include <linux/hmm.h>
12 #include <linux/hugetlb_inline.h>
13 #include <linux/memremap.h>
14 #include <linux/mm_types.h>
15 #include <linux/slab.h>
16 
17 #include <drm/drm_device.h>
18 #include <drm/drm_gpusvm.h>
19 #include <drm/drm_pagemap.h>
20 #include <drm/drm_print.h>
21 
22 /**
23  * DOC: Overview
24  *
25  * GPU Shared Virtual Memory (GPU SVM) layer for the Direct Rendering Manager (DRM)
26  * is a component of the DRM framework designed to manage shared virtual memory
27  * between the CPU and GPU. It enables efficient data exchange and processing
28  * for GPU-accelerated applications by allowing memory sharing and
29  * synchronization between the CPU's and GPU's virtual address spaces.
30  *
31  * Key GPU SVM Components:
32  *
33  * - Notifiers:
34  *	Used for tracking memory intervals and notifying the GPU of changes,
35  *	notifiers are sized based on a GPU SVM initialization parameter, with a
36  *	recommendation of 512M or larger. They maintain a Red-BlacK tree and a
37  *	list of ranges that fall within the notifier interval.  Notifiers are
38  *	tracked within a GPU SVM Red-BlacK tree and list and are dynamically
39  *	inserted or removed as ranges within the interval are created or
40  *	destroyed.
41  * - Ranges:
42  *	Represent memory ranges mapped in a DRM device and managed by GPU SVM.
43  *	They are sized based on an array of chunk sizes, which is a GPU SVM
44  *	initialization parameter, and the CPU address space.  Upon GPU fault,
45  *	the largest aligned chunk that fits within the faulting CPU address
46  *	space is chosen for the range size. Ranges are expected to be
47  *	dynamically allocated on GPU fault and removed on an MMU notifier UNMAP
48  *	event. As mentioned above, ranges are tracked in a notifier's Red-Black
49  *	tree.
50  *
51  * - Operations:
52  *	Define the interface for driver-specific GPU SVM operations such as
53  *	range allocation, notifier allocation, and invalidations.
54  *
55  * - Device Memory Allocations:
56  *	Embedded structure containing enough information for GPU SVM to migrate
57  *	to / from device memory.
58  *
59  * - Device Memory Operations:
60  *	Define the interface for driver-specific device memory operations
61  *	release memory, populate pfns, and copy to / from device memory.
62  *
63  * This layer provides interfaces for allocating, mapping, migrating, and
64  * releasing memory ranges between the CPU and GPU. It handles all core memory
65  * management interactions (DMA mapping, HMM, and migration) and provides
66  * driver-specific virtual functions (vfuncs). This infrastructure is sufficient
67  * to build the expected driver components for an SVM implementation as detailed
68  * below.
69  *
70  * Expected Driver Components:
71  *
72  * - GPU page fault handler:
73  *	Used to create ranges and notifiers based on the fault address,
74  *	optionally migrate the range to device memory, and create GPU bindings.
75  *
76  * - Garbage collector:
77  *	Used to unmap and destroy GPU bindings for ranges.  Ranges are expected
78  *	to be added to the garbage collector upon a MMU_NOTIFY_UNMAP event in
79  *	notifier callback.
80  *
81  * - Notifier callback:
82  *	Used to invalidate and DMA unmap GPU bindings for ranges.
83  */
84 
85 /**
86  * DOC: Locking
87  *
88  * GPU SVM handles locking for core MM interactions, i.e., it locks/unlocks the
89  * mmap lock as needed.
90  *
91  * GPU SVM introduces a global notifier lock, which safeguards the notifier's
92  * range RB tree and list, as well as the range's DMA mappings and sequence
93  * number. GPU SVM manages all necessary locking and unlocking operations,
94  * except for the recheck range's pages being valid
95  * (drm_gpusvm_range_pages_valid) when the driver is committing GPU bindings.
96  * This lock corresponds to the ``driver->update`` lock mentioned in
97  * Documentation/mm/hmm.rst. Future revisions may transition from a GPU SVM
98  * global lock to a per-notifier lock if finer-grained locking is deemed
99  * necessary.
100  *
101  * In addition to the locking mentioned above, the driver should implement a
102  * lock to safeguard core GPU SVM function calls that modify state, such as
103  * drm_gpusvm_range_find_or_insert and drm_gpusvm_range_remove. This lock is
104  * denoted as 'driver_svm_lock' in code examples. Finer grained driver side
105  * locking should also be possible for concurrent GPU fault processing within a
106  * single GPU SVM. The 'driver_svm_lock' can be via drm_gpusvm_driver_set_lock
107  * to add annotations to GPU SVM.
108  */
109 
110 /**
111  * DOC: Partial Unmapping of Ranges
112  *
113  * Partial unmapping of ranges (e.g., 1M out of 2M is unmapped by CPU resulting
114  * in MMU_NOTIFY_UNMAP event) presents several challenges, with the main one
115  * being that a subset of the range still has CPU and GPU mappings. If the
116  * backing store for the range is in device memory, a subset of the backing
117  * store has references. One option would be to split the range and device
118  * memory backing store, but the implementation for this would be quite
119  * complicated. Given that partial unmappings are rare and driver-defined range
120  * sizes are relatively small, GPU SVM does not support splitting of ranges.
121  *
122  * With no support for range splitting, upon partial unmapping of a range, the
123  * driver is expected to invalidate and destroy the entire range. If the range
124  * has device memory as its backing, the driver is also expected to migrate any
125  * remaining pages back to RAM.
126  */
127 
128 /**
129  * DOC: Examples
130  *
131  * This section provides three examples of how to build the expected driver
132  * components: the GPU page fault handler, the garbage collector, and the
133  * notifier callback.
134  *
135  * The generic code provided does not include logic for complex migration
136  * policies, optimized invalidations, fined grained driver locking, or other
137  * potentially required driver locking (e.g., DMA-resv locks).
138  *
139  * 1) GPU page fault handler
140  *
141  * .. code-block:: c
142  *
143  *	int driver_bind_range(struct drm_gpusvm *gpusvm, struct drm_gpusvm_range *range)
144  *	{
145  *		int err = 0;
146  *
147  *		driver_alloc_and_setup_memory_for_bind(gpusvm, range);
148  *
149  *		drm_gpusvm_notifier_lock(gpusvm);
150  *		if (drm_gpusvm_range_pages_valid(range))
151  *			driver_commit_bind(gpusvm, range);
152  *		else
153  *			err = -EAGAIN;
154  *		drm_gpusvm_notifier_unlock(gpusvm);
155  *
156  *		return err;
157  *	}
158  *
159  *	int driver_gpu_fault(struct drm_gpusvm *gpusvm, unsigned long fault_addr,
160  *			     unsigned long gpuva_start, unsigned long gpuva_end)
161  *	{
162  *		struct drm_gpusvm_ctx ctx = {};
163  *		int err;
164  *
165  *		driver_svm_lock();
166  *	retry:
167  *		// Always process UNMAPs first so view of GPU SVM ranges is current
168  *		driver_garbage_collector(gpusvm);
169  *
170  *		range = drm_gpusvm_range_find_or_insert(gpusvm, fault_addr,
171  *							gpuva_start, gpuva_end,
172  *						        &ctx);
173  *		if (IS_ERR(range)) {
174  *			err = PTR_ERR(range);
175  *			goto unlock;
176  *		}
177  *
178  *		if (driver_migration_policy(range)) {
179  *			err = drm_pagemap_populate_mm(driver_choose_drm_pagemap(),
180  *						      gpuva_start, gpuva_end, gpusvm->mm,
181  *						      ctx->timeslice_ms);
182  *			if (err)	// CPU mappings may have changed
183  *				goto retry;
184  *		}
185  *
186  *		err = drm_gpusvm_range_get_pages(gpusvm, range, &ctx);
187  *		if (err == -EOPNOTSUPP || err == -EFAULT || err == -EPERM) {	// CPU mappings changed
188  *			if (err == -EOPNOTSUPP)
189  *				drm_gpusvm_range_evict(gpusvm, range);
190  *			goto retry;
191  *		} else if (err) {
192  *			goto unlock;
193  *		}
194  *
195  *		err = driver_bind_range(gpusvm, range);
196  *		if (err == -EAGAIN)	// CPU mappings changed
197  *			goto retry
198  *
199  *	unlock:
200  *		driver_svm_unlock();
201  *		return err;
202  *	}
203  *
204  * 2) Garbage Collector
205  *
206  * .. code-block:: c
207  *
208  *	void __driver_garbage_collector(struct drm_gpusvm *gpusvm,
209  *					struct drm_gpusvm_range *range)
210  *	{
211  *		assert_driver_svm_locked(gpusvm);
212  *
213  *		// Partial unmap, migrate any remaining device memory pages back to RAM
214  *		if (range->flags.partial_unmap)
215  *			drm_gpusvm_range_evict(gpusvm, range);
216  *
217  *		driver_unbind_range(range);
218  *		drm_gpusvm_range_remove(gpusvm, range);
219  *	}
220  *
221  *	void driver_garbage_collector(struct drm_gpusvm *gpusvm)
222  *	{
223  *		assert_driver_svm_locked(gpusvm);
224  *
225  *		for_each_range_in_garbage_collector(gpusvm, range)
226  *			__driver_garbage_collector(gpusvm, range);
227  *	}
228  *
229  * 3) Notifier callback
230  *
231  * .. code-block:: c
232  *
233  *	void driver_invalidation(struct drm_gpusvm *gpusvm,
234  *				 struct drm_gpusvm_notifier *notifier,
235  *				 const struct mmu_notifier_range *mmu_range)
236  *	{
237  *		struct drm_gpusvm_ctx ctx = { .in_notifier = true, };
238  *		struct drm_gpusvm_range *range = NULL;
239  *
240  *		driver_invalidate_device_pages(gpusvm, mmu_range->start, mmu_range->end);
241  *
242  *		drm_gpusvm_for_each_range(range, notifier, mmu_range->start,
243  *					  mmu_range->end) {
244  *			drm_gpusvm_range_unmap_pages(gpusvm, range, &ctx);
245  *
246  *			if (mmu_range->event != MMU_NOTIFY_UNMAP)
247  *				continue;
248  *
249  *			drm_gpusvm_range_set_unmapped(range, mmu_range);
250  *			driver_garbage_collector_add(gpusvm, range);
251  *		}
252  *	}
253  */
254 
255 /**
256  * npages_in_range() - Calculate the number of pages in a given range
257  * @start: The start address of the range
258  * @end: The end address of the range
259  *
260  * This macro calculates the number of pages in a given memory range,
261  * specified by the start and end addresses. It divides the difference
262  * between the end and start addresses by the page size (PAGE_SIZE) to
263  * determine the number of pages in the range.
264  *
265  * Return: The number of pages in the specified range.
266  */
267 static unsigned long
268 npages_in_range(unsigned long start, unsigned long end)
269 {
270 	return (end - start) >> PAGE_SHIFT;
271 }
272 
273 /**
274  * drm_gpusvm_notifier_find() - Find GPU SVM notifier from GPU SVM
275  * @gpusvm: Pointer to the GPU SVM structure.
276  * @start: Start address of the notifier
277  * @end: End address of the notifier
278  *
279  * Return: A pointer to the drm_gpusvm_notifier if found or NULL
280  */
281 struct drm_gpusvm_notifier *
282 drm_gpusvm_notifier_find(struct drm_gpusvm *gpusvm, unsigned long start,
283 			 unsigned long end)
284 {
285 	struct interval_tree_node *itree;
286 
287 	itree = interval_tree_iter_first(&gpusvm->root, start, end - 1);
288 
289 	if (itree)
290 		return container_of(itree, struct drm_gpusvm_notifier, itree);
291 	else
292 		return NULL;
293 }
294 EXPORT_SYMBOL_GPL(drm_gpusvm_notifier_find);
295 
296 /**
297  * drm_gpusvm_range_find() - Find GPU SVM range from GPU SVM notifier
298  * @notifier: Pointer to the GPU SVM notifier structure.
299  * @start: Start address of the range
300  * @end: End address of the range
301  *
302  * Return: A pointer to the drm_gpusvm_range if found or NULL
303  */
304 struct drm_gpusvm_range *
305 drm_gpusvm_range_find(struct drm_gpusvm_notifier *notifier, unsigned long start,
306 		      unsigned long end)
307 {
308 	struct interval_tree_node *itree;
309 
310 	itree = interval_tree_iter_first(&notifier->root, start, end - 1);
311 
312 	if (itree)
313 		return container_of(itree, struct drm_gpusvm_range, itree);
314 	else
315 		return NULL;
316 }
317 EXPORT_SYMBOL_GPL(drm_gpusvm_range_find);
318 
319 /**
320  * drm_gpusvm_notifier_invalidate() - Invalidate a GPU SVM notifier.
321  * @mni: Pointer to the mmu_interval_notifier structure.
322  * @mmu_range: Pointer to the mmu_notifier_range structure.
323  * @cur_seq: Current sequence number.
324  *
325  * This function serves as a generic MMU notifier for GPU SVM. It sets the MMU
326  * notifier sequence number and calls the driver invalidate vfunc under
327  * gpusvm->notifier_lock.
328  *
329  * Return: true if the operation succeeds, false otherwise.
330  */
331 static bool
332 drm_gpusvm_notifier_invalidate(struct mmu_interval_notifier *mni,
333 			       const struct mmu_notifier_range *mmu_range,
334 			       unsigned long cur_seq)
335 {
336 	struct drm_gpusvm_notifier *notifier =
337 		container_of(mni, typeof(*notifier), notifier);
338 	struct drm_gpusvm *gpusvm = notifier->gpusvm;
339 
340 	if (!mmu_notifier_range_blockable(mmu_range))
341 		return false;
342 
343 	down_write(&gpusvm->notifier_lock);
344 	mmu_interval_set_seq(mni, cur_seq);
345 	gpusvm->ops->invalidate(gpusvm, notifier, mmu_range);
346 	up_write(&gpusvm->notifier_lock);
347 
348 	return true;
349 }
350 
351 /*
352  * drm_gpusvm_notifier_ops - MMU interval notifier operations for GPU SVM
353  */
354 static const struct mmu_interval_notifier_ops drm_gpusvm_notifier_ops = {
355 	.invalidate = drm_gpusvm_notifier_invalidate,
356 };
357 
358 /**
359  * drm_gpusvm_init() - Initialize the GPU SVM.
360  * @gpusvm: Pointer to the GPU SVM structure.
361  * @name: Name of the GPU SVM.
362  * @drm: Pointer to the DRM device structure.
363  * @mm: Pointer to the mm_struct for the address space.
364  * @mm_start: Start address of GPU SVM.
365  * @mm_range: Range of the GPU SVM.
366  * @notifier_size: Size of individual notifiers.
367  * @ops: Pointer to the operations structure for GPU SVM.
368  * @chunk_sizes: Pointer to the array of chunk sizes used in range allocation.
369  *               Entries should be powers of 2 in descending order with last
370  *               entry being SZ_4K.
371  * @num_chunks: Number of chunks.
372  *
373  * This function initializes the GPU SVM.
374  *
375  * Note: If only using the simple drm_gpusvm_pages API (get/unmap/free),
376  * then only @gpusvm, @name, and @drm are expected. However, the same base
377  * @gpusvm can also be used with both modes together in which case the full
378  * setup is needed, where the core drm_gpusvm_pages API will simply never use
379  * the other fields.
380  *
381  * Return: 0 on success, a negative error code on failure.
382  */
383 int drm_gpusvm_init(struct drm_gpusvm *gpusvm,
384 		    const char *name, struct drm_device *drm,
385 		    struct mm_struct *mm,
386 		    unsigned long mm_start, unsigned long mm_range,
387 		    unsigned long notifier_size,
388 		    const struct drm_gpusvm_ops *ops,
389 		    const unsigned long *chunk_sizes, int num_chunks)
390 {
391 	if (mm) {
392 		if (!ops->invalidate || !num_chunks)
393 			return -EINVAL;
394 		mmgrab(mm);
395 	} else {
396 		/* No full SVM mode, only core drm_gpusvm_pages API. */
397 		if (ops || num_chunks || mm_range || notifier_size)
398 			return -EINVAL;
399 	}
400 
401 	gpusvm->name = name;
402 	gpusvm->drm = drm;
403 	gpusvm->mm = mm;
404 	gpusvm->mm_start = mm_start;
405 	gpusvm->mm_range = mm_range;
406 	gpusvm->notifier_size = notifier_size;
407 	gpusvm->ops = ops;
408 	gpusvm->chunk_sizes = chunk_sizes;
409 	gpusvm->num_chunks = num_chunks;
410 
411 	gpusvm->root = RB_ROOT_CACHED;
412 	INIT_LIST_HEAD(&gpusvm->notifier_list);
413 
414 	init_rwsem(&gpusvm->notifier_lock);
415 
416 	fs_reclaim_acquire(GFP_KERNEL);
417 	might_lock(&gpusvm->notifier_lock);
418 	fs_reclaim_release(GFP_KERNEL);
419 
420 #ifdef CONFIG_LOCKDEP
421 	gpusvm->lock_dep_map = NULL;
422 #endif
423 
424 	return 0;
425 }
426 EXPORT_SYMBOL_GPL(drm_gpusvm_init);
427 
428 /**
429  * to_drm_gpusvm_notifier() - retrieve the container struct for a given rbtree node
430  * @node: a pointer to the rbtree node embedded within a drm_gpusvm_notifier struct
431  *
432  * Return: A pointer to the containing drm_gpusvm_notifier structure.
433  */
434 static struct drm_gpusvm_notifier *to_drm_gpusvm_notifier(struct rb_node *node)
435 {
436 	return container_of(node, struct drm_gpusvm_notifier, itree.rb);
437 }
438 
439 /**
440  * drm_gpusvm_notifier_insert() - Insert GPU SVM notifier
441  * @gpusvm: Pointer to the GPU SVM structure
442  * @notifier: Pointer to the GPU SVM notifier structure
443  *
444  * This function inserts the GPU SVM notifier into the GPU SVM RB tree and list.
445  */
446 static void drm_gpusvm_notifier_insert(struct drm_gpusvm *gpusvm,
447 				       struct drm_gpusvm_notifier *notifier)
448 {
449 	struct rb_node *node;
450 	struct list_head *head;
451 
452 	interval_tree_insert(&notifier->itree, &gpusvm->root);
453 
454 	node = rb_prev(&notifier->itree.rb);
455 	if (node)
456 		head = &(to_drm_gpusvm_notifier(node))->entry;
457 	else
458 		head = &gpusvm->notifier_list;
459 
460 	list_add(&notifier->entry, head);
461 }
462 
463 /**
464  * drm_gpusvm_notifier_remove() - Remove GPU SVM notifier
465  * @gpusvm: Pointer to the GPU SVM tructure
466  * @notifier: Pointer to the GPU SVM notifier structure
467  *
468  * This function removes the GPU SVM notifier from the GPU SVM RB tree and list.
469  */
470 static void drm_gpusvm_notifier_remove(struct drm_gpusvm *gpusvm,
471 				       struct drm_gpusvm_notifier *notifier)
472 {
473 	interval_tree_remove(&notifier->itree, &gpusvm->root);
474 	list_del(&notifier->entry);
475 }
476 
477 /**
478  * drm_gpusvm_fini() - Finalize the GPU SVM.
479  * @gpusvm: Pointer to the GPU SVM structure.
480  *
481  * This function finalizes the GPU SVM by cleaning up any remaining ranges and
482  * notifiers, and dropping a reference to struct MM.
483  */
484 void drm_gpusvm_fini(struct drm_gpusvm *gpusvm)
485 {
486 	struct drm_gpusvm_notifier *notifier, *next;
487 
488 	drm_gpusvm_for_each_notifier_safe(notifier, next, gpusvm, 0, LONG_MAX) {
489 		struct drm_gpusvm_range *range, *__next;
490 
491 		/*
492 		 * Remove notifier first to avoid racing with any invalidation
493 		 */
494 		mmu_interval_notifier_remove(&notifier->notifier);
495 		notifier->flags.removed = true;
496 
497 		drm_gpusvm_for_each_range_safe(range, __next, notifier, 0,
498 					       LONG_MAX)
499 			drm_gpusvm_range_remove(gpusvm, range);
500 	}
501 
502 	if (gpusvm->mm)
503 		mmdrop(gpusvm->mm);
504 	WARN_ON(!RB_EMPTY_ROOT(&gpusvm->root.rb_root));
505 }
506 EXPORT_SYMBOL_GPL(drm_gpusvm_fini);
507 
508 /**
509  * drm_gpusvm_notifier_alloc() - Allocate GPU SVM notifier
510  * @gpusvm: Pointer to the GPU SVM structure
511  * @fault_addr: Fault address
512  *
513  * This function allocates and initializes the GPU SVM notifier structure.
514  *
515  * Return: Pointer to the allocated GPU SVM notifier on success, ERR_PTR() on failure.
516  */
517 static struct drm_gpusvm_notifier *
518 drm_gpusvm_notifier_alloc(struct drm_gpusvm *gpusvm, unsigned long fault_addr)
519 {
520 	struct drm_gpusvm_notifier *notifier;
521 
522 	if (gpusvm->ops->notifier_alloc)
523 		notifier = gpusvm->ops->notifier_alloc();
524 	else
525 		notifier = kzalloc_obj(*notifier);
526 
527 	if (!notifier)
528 		return ERR_PTR(-ENOMEM);
529 
530 	notifier->gpusvm = gpusvm;
531 	notifier->itree.start = ALIGN_DOWN(fault_addr, gpusvm->notifier_size);
532 	notifier->itree.last = ALIGN(fault_addr + 1, gpusvm->notifier_size) - 1;
533 	INIT_LIST_HEAD(&notifier->entry);
534 	notifier->root = RB_ROOT_CACHED;
535 	INIT_LIST_HEAD(&notifier->range_list);
536 
537 	return notifier;
538 }
539 
540 /**
541  * drm_gpusvm_notifier_free() - Free GPU SVM notifier
542  * @gpusvm: Pointer to the GPU SVM structure
543  * @notifier: Pointer to the GPU SVM notifier structure
544  *
545  * This function frees the GPU SVM notifier structure.
546  */
547 static void drm_gpusvm_notifier_free(struct drm_gpusvm *gpusvm,
548 				     struct drm_gpusvm_notifier *notifier)
549 {
550 	WARN_ON(!RB_EMPTY_ROOT(&notifier->root.rb_root));
551 
552 	if (gpusvm->ops->notifier_free)
553 		gpusvm->ops->notifier_free(notifier);
554 	else
555 		kfree(notifier);
556 }
557 
558 /**
559  * to_drm_gpusvm_range() - retrieve the container struct for a given rbtree node
560  * @node: a pointer to the rbtree node embedded within a drm_gpusvm_range struct
561  *
562  * Return: A pointer to the containing drm_gpusvm_range structure.
563  */
564 static struct drm_gpusvm_range *to_drm_gpusvm_range(struct rb_node *node)
565 {
566 	return container_of(node, struct drm_gpusvm_range, itree.rb);
567 }
568 
569 /**
570  * drm_gpusvm_range_insert() - Insert GPU SVM range
571  * @notifier: Pointer to the GPU SVM notifier structure
572  * @range: Pointer to the GPU SVM range structure
573  *
574  * This function inserts the GPU SVM range into the notifier RB tree and list.
575  */
576 static void drm_gpusvm_range_insert(struct drm_gpusvm_notifier *notifier,
577 				    struct drm_gpusvm_range *range)
578 {
579 	struct rb_node *node;
580 	struct list_head *head;
581 
582 	drm_gpusvm_notifier_lock(notifier->gpusvm);
583 	interval_tree_insert(&range->itree, &notifier->root);
584 
585 	node = rb_prev(&range->itree.rb);
586 	if (node)
587 		head = &(to_drm_gpusvm_range(node))->entry;
588 	else
589 		head = &notifier->range_list;
590 
591 	list_add(&range->entry, head);
592 	drm_gpusvm_notifier_unlock(notifier->gpusvm);
593 }
594 
595 /**
596  * __drm_gpusvm_range_remove() - Remove GPU SVM range
597  * @notifier: Pointer to the GPU SVM notifier structure
598  * @range: Pointer to the GPU SVM range structure
599  *
600  * This macro removes the GPU SVM range from the notifier RB tree and list.
601  */
602 static void __drm_gpusvm_range_remove(struct drm_gpusvm_notifier *notifier,
603 				      struct drm_gpusvm_range *range)
604 {
605 	interval_tree_remove(&range->itree, &notifier->root);
606 	list_del(&range->entry);
607 }
608 
609 /**
610  * drm_gpusvm_range_alloc() - Allocate GPU SVM range
611  * @gpusvm: Pointer to the GPU SVM structure
612  * @notifier: Pointer to the GPU SVM notifier structure
613  * @fault_addr: Fault address
614  * @chunk_size: Chunk size
615  * @migrate_devmem: Flag indicating whether to migrate device memory
616  *
617  * This function allocates and initializes the GPU SVM range structure.
618  *
619  * Return: Pointer to the allocated GPU SVM range on success, ERR_PTR() on failure.
620  */
621 static struct drm_gpusvm_range *
622 drm_gpusvm_range_alloc(struct drm_gpusvm *gpusvm,
623 		       struct drm_gpusvm_notifier *notifier,
624 		       unsigned long fault_addr, unsigned long chunk_size,
625 		       bool migrate_devmem)
626 {
627 	struct drm_gpusvm_range *range;
628 
629 	if (gpusvm->ops->range_alloc)
630 		range = gpusvm->ops->range_alloc(gpusvm);
631 	else
632 		range = kzalloc_obj(*range);
633 
634 	if (!range)
635 		return ERR_PTR(-ENOMEM);
636 
637 	kref_init(&range->refcount);
638 	range->gpusvm = gpusvm;
639 	range->notifier = notifier;
640 	range->itree.start = ALIGN_DOWN(fault_addr, chunk_size);
641 	range->itree.last = ALIGN(fault_addr + 1, chunk_size) - 1;
642 	INIT_LIST_HEAD(&range->entry);
643 	range->pages.notifier_seq = LONG_MAX;
644 	range->pages.flags.migrate_devmem = migrate_devmem ? 1 : 0;
645 
646 	return range;
647 }
648 
649 /**
650  * drm_gpusvm_hmm_pfn_to_order() - Get the largest CPU mapping order.
651  * @hmm_pfn: The current hmm_pfn.
652  * @hmm_pfn_index: Index of the @hmm_pfn within the pfn array.
653  * @npages: Number of pages within the pfn array i.e the hmm range size.
654  *
655  * To allow skipping PFNs with the same flags (like when they belong to
656  * the same huge PTE) when looping over the pfn array, take a given a hmm_pfn,
657  * and return the largest order that will fit inside the CPU PTE, but also
658  * crucially accounting for the original hmm range boundaries.
659  *
660  * Return: The largest order that will safely fit within the size of the hmm_pfn
661  * CPU PTE.
662  */
663 static unsigned int drm_gpusvm_hmm_pfn_to_order(unsigned long hmm_pfn,
664 						unsigned long hmm_pfn_index,
665 						unsigned long npages)
666 {
667 	unsigned long size;
668 
669 	size = 1UL << hmm_pfn_to_map_order(hmm_pfn);
670 	size -= (hmm_pfn & ~HMM_PFN_FLAGS) & (size - 1);
671 	hmm_pfn_index += size;
672 	if (hmm_pfn_index > npages)
673 		size -= (hmm_pfn_index - npages);
674 
675 	return ilog2(size);
676 }
677 
678 /**
679  * drm_gpusvm_check_pages() - Check pages
680  * @gpusvm: Pointer to the GPU SVM structure
681  * @notifier: Pointer to the GPU SVM notifier structure
682  * @start: Start address
683  * @end: End address
684  * @dev_private_owner: The device private page owner
685  *
686  * Check if pages between start and end have been faulted in on the CPU. Use to
687  * prevent migration of pages without CPU backing store.
688  *
689  * Return: True if pages have been faulted into CPU, False otherwise
690  */
691 static bool drm_gpusvm_check_pages(struct drm_gpusvm *gpusvm,
692 				   struct drm_gpusvm_notifier *notifier,
693 				   unsigned long start, unsigned long end,
694 				   void *dev_private_owner)
695 {
696 	struct hmm_range hmm_range = {
697 		.default_flags = 0,
698 		.notifier = &notifier->notifier,
699 		.start = start,
700 		.end = end,
701 		.dev_private_owner = dev_private_owner,
702 	};
703 	unsigned long timeout =
704 		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
705 	unsigned long *pfns;
706 	unsigned long npages = npages_in_range(start, end);
707 	int err, i;
708 
709 	mmap_assert_locked(gpusvm->mm);
710 
711 	pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL);
712 	if (!pfns)
713 		return false;
714 
715 	hmm_range.notifier_seq = mmu_interval_read_begin(&notifier->notifier);
716 	hmm_range.hmm_pfns = pfns;
717 
718 	while (true) {
719 		err = hmm_range_fault(&hmm_range);
720 		if (err == -EBUSY) {
721 			if (time_after(jiffies, timeout))
722 				break;
723 
724 			hmm_range.notifier_seq =
725 				mmu_interval_read_begin(&notifier->notifier);
726 			continue;
727 		}
728 		break;
729 	}
730 	if (err)
731 		goto err_free;
732 
733 	for (i = 0; i < npages;) {
734 		if (!(pfns[i] & HMM_PFN_VALID)) {
735 			err = -EFAULT;
736 			goto err_free;
737 		}
738 		i += 0x1 << drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
739 	}
740 
741 err_free:
742 	kvfree(pfns);
743 	return err ? false : true;
744 }
745 
746 /**
747  * drm_gpusvm_scan_mm() - Check the migration state of a drm_gpusvm_range
748  * @range: Pointer to the struct drm_gpusvm_range to check.
749  * @dev_private_owner: The struct dev_private_owner to use to determine
750  * compatible device-private pages.
751  * @pagemap: The struct dev_pagemap pointer to use for pagemap-specific
752  * checks.
753  *
754  * Scan the CPU address space corresponding to @range and return the
755  * current migration state. Note that the result may be invalid as
756  * soon as the function returns. It's an advisory check.
757  *
758  * TODO: Bail early and call hmm_range_fault() for subranges.
759  *
760  * Return: See &enum drm_gpusvm_scan_result.
761  */
762 enum drm_gpusvm_scan_result drm_gpusvm_scan_mm(struct drm_gpusvm_range *range,
763 					       void *dev_private_owner,
764 					       const struct dev_pagemap *pagemap)
765 {
766 	struct mmu_interval_notifier *notifier = &range->notifier->notifier;
767 	unsigned long start = drm_gpusvm_range_start(range);
768 	unsigned long end = drm_gpusvm_range_end(range);
769 	struct hmm_range hmm_range = {
770 		.default_flags = 0,
771 		.notifier = notifier,
772 		.start = start,
773 		.end = end,
774 		.dev_private_owner = dev_private_owner,
775 	};
776 	unsigned long timeout =
777 		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
778 	enum drm_gpusvm_scan_result state = DRM_GPUSVM_SCAN_UNPOPULATED, new_state;
779 	unsigned long *pfns;
780 	unsigned long npages = npages_in_range(start, end);
781 	const struct dev_pagemap *other = NULL;
782 	int err, i;
783 
784 	pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL);
785 	if (!pfns)
786 		return DRM_GPUSVM_SCAN_UNPOPULATED;
787 
788 	hmm_range.hmm_pfns = pfns;
789 
790 retry:
791 	hmm_range.notifier_seq = mmu_interval_read_begin(notifier);
792 	mmap_read_lock(range->gpusvm->mm);
793 
794 	while (true) {
795 		err = hmm_range_fault(&hmm_range);
796 		if (err == -EBUSY) {
797 			if (time_after(jiffies, timeout))
798 				break;
799 
800 			hmm_range.notifier_seq =
801 				mmu_interval_read_begin(notifier);
802 			continue;
803 		}
804 		break;
805 	}
806 	mmap_read_unlock(range->gpusvm->mm);
807 	if (err)
808 		goto err_free;
809 
810 	drm_gpusvm_notifier_lock(range->gpusvm);
811 	if (mmu_interval_read_retry(notifier, hmm_range.notifier_seq)) {
812 		drm_gpusvm_notifier_unlock(range->gpusvm);
813 		goto retry;
814 	}
815 
816 	for (i = 0; i < npages;) {
817 		struct page *page;
818 		const struct dev_pagemap *cur = NULL;
819 
820 		if (!(pfns[i] & HMM_PFN_VALID)) {
821 			state = DRM_GPUSVM_SCAN_UNPOPULATED;
822 			break;
823 		}
824 
825 		page = hmm_pfn_to_page(pfns[i]);
826 		if (is_device_private_page(page) ||
827 		    is_device_coherent_page(page))
828 			cur = page_pgmap(page);
829 
830 		if (cur == pagemap) {
831 			new_state = DRM_GPUSVM_SCAN_EQUAL;
832 		} else if (cur && (cur == other || !other)) {
833 			new_state = DRM_GPUSVM_SCAN_OTHER;
834 			other = cur;
835 		} else if (cur) {
836 			new_state = DRM_GPUSVM_SCAN_MIXED_DEVICE;
837 		} else {
838 			new_state = DRM_GPUSVM_SCAN_SYSTEM;
839 		}
840 
841 		/*
842 		 * TODO: Could use an array for state
843 		 * transitions, and caller might want it
844 		 * to bail early for some results.
845 		 */
846 		if (state == DRM_GPUSVM_SCAN_UNPOPULATED) {
847 			state = new_state;
848 		} else if (state != new_state) {
849 			if (new_state == DRM_GPUSVM_SCAN_SYSTEM ||
850 			    state == DRM_GPUSVM_SCAN_SYSTEM)
851 				state = DRM_GPUSVM_SCAN_MIXED;
852 			else if (state != DRM_GPUSVM_SCAN_MIXED)
853 				state = DRM_GPUSVM_SCAN_MIXED_DEVICE;
854 		}
855 
856 		i += 1ul << drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
857 	}
858 
859 	drm_gpusvm_notifier_unlock(range->gpusvm);
860 
861 err_free:
862 	kvfree(pfns);
863 	return state;
864 }
865 EXPORT_SYMBOL(drm_gpusvm_scan_mm);
866 
867 /**
868  * drm_gpusvm_range_chunk_size() - Determine chunk size for GPU SVM range
869  * @gpusvm: Pointer to the GPU SVM structure
870  * @notifier: Pointer to the GPU SVM notifier structure
871  * @vas: Pointer to the virtual memory area structure
872  * @fault_addr: Fault address
873  * @gpuva_start: Start address of GPUVA which mirrors CPU
874  * @gpuva_end: End address of GPUVA which mirrors CPU
875  * @check_pages_threshold: Check CPU pages for present threshold
876  * @dev_private_owner: The device private page owner
877  *
878  * This function determines the chunk size for the GPU SVM range based on the
879  * fault address, GPU SVM chunk sizes, existing GPU SVM ranges, and the virtual
880  * memory area boundaries.
881  *
882  * Return: Chunk size on success, LONG_MAX on failure.
883  */
884 static unsigned long
885 drm_gpusvm_range_chunk_size(struct drm_gpusvm *gpusvm,
886 			    struct drm_gpusvm_notifier *notifier,
887 			    struct vm_area_struct *vas,
888 			    unsigned long fault_addr,
889 			    unsigned long gpuva_start,
890 			    unsigned long gpuva_end,
891 			    unsigned long check_pages_threshold,
892 			    void *dev_private_owner)
893 {
894 	unsigned long start, end;
895 	int i = 0;
896 
897 retry:
898 	for (; i < gpusvm->num_chunks; ++i) {
899 		start = ALIGN_DOWN(fault_addr, gpusvm->chunk_sizes[i]);
900 		end = ALIGN(fault_addr + 1, gpusvm->chunk_sizes[i]);
901 
902 		if (start >= vas->vm_start && end <= vas->vm_end &&
903 		    start >= drm_gpusvm_notifier_start(notifier) &&
904 		    end <= drm_gpusvm_notifier_end(notifier) &&
905 		    start >= gpuva_start && end <= gpuva_end)
906 			break;
907 	}
908 
909 	if (i == gpusvm->num_chunks)
910 		return LONG_MAX;
911 
912 	/*
913 	 * If allocation more than page, ensure not to overlap with existing
914 	 * ranges.
915 	 */
916 	if (end - start != SZ_4K) {
917 		struct drm_gpusvm_range *range;
918 
919 		range = drm_gpusvm_range_find(notifier, start, end);
920 		if (range) {
921 			++i;
922 			goto retry;
923 		}
924 
925 		/*
926 		 * XXX: Only create range on pages CPU has faulted in. Without
927 		 * this check, or prefault, on BMG 'xe_exec_system_allocator --r
928 		 * process-many-malloc' fails. In the failure case, each process
929 		 * mallocs 16k but the CPU VMA is ~128k which results in 64k SVM
930 		 * ranges. When migrating the SVM ranges, some processes fail in
931 		 * drm_pagemap_migrate_to_devmem with 'migrate.cpages != npages'
932 		 * and then upon drm_gpusvm_range_get_pages device pages from
933 		 * other processes are collected + faulted in which creates all
934 		 * sorts of problems. Unsure exactly how this happening, also
935 		 * problem goes away if 'xe_exec_system_allocator --r
936 		 * process-many-malloc' mallocs at least 64k at a time.
937 		 */
938 		if (end - start <= check_pages_threshold &&
939 		    !drm_gpusvm_check_pages(gpusvm, notifier, start, end, dev_private_owner)) {
940 			++i;
941 			goto retry;
942 		}
943 	}
944 
945 	return end - start;
946 }
947 
948 #ifdef CONFIG_LOCKDEP
949 /**
950  * drm_gpusvm_driver_lock_held() - Assert GPU SVM driver lock is held
951  * @gpusvm: Pointer to the GPU SVM structure.
952  *
953  * Ensure driver lock is held.
954  */
955 static void drm_gpusvm_driver_lock_held(struct drm_gpusvm *gpusvm)
956 {
957 	if ((gpusvm)->lock_dep_map)
958 		lockdep_assert(lock_is_held_type((gpusvm)->lock_dep_map, 0));
959 }
960 #else
961 static void drm_gpusvm_driver_lock_held(struct drm_gpusvm *gpusvm)
962 {
963 }
964 #endif
965 
966 /**
967  * drm_gpusvm_find_vma_start() - Find start address for first VMA in range
968  * @gpusvm: Pointer to the GPU SVM structure
969  * @start: The inclusive start user address.
970  * @end: The exclusive end user address.
971  *
972  * Returns: The start address of first VMA within the provided range,
973  * ULONG_MAX otherwise. Assumes start_addr < end_addr.
974  */
975 unsigned long
976 drm_gpusvm_find_vma_start(struct drm_gpusvm *gpusvm,
977 			  unsigned long start,
978 			  unsigned long end)
979 {
980 	struct mm_struct *mm = gpusvm->mm;
981 	struct vm_area_struct *vma;
982 	unsigned long addr = ULONG_MAX;
983 
984 	if (!mmget_not_zero(mm))
985 		return addr;
986 
987 	mmap_read_lock(mm);
988 
989 	vma = find_vma_intersection(mm, start, end);
990 	if (vma)
991 		addr =  vma->vm_start;
992 
993 	mmap_read_unlock(mm);
994 	mmput(mm);
995 
996 	return addr;
997 }
998 EXPORT_SYMBOL_GPL(drm_gpusvm_find_vma_start);
999 
1000 /**
1001  * drm_gpusvm_range_find_or_insert() - Find or insert GPU SVM range
1002  * @gpusvm: Pointer to the GPU SVM structure
1003  * @fault_addr: Fault address
1004  * @gpuva_start: Start address of GPUVA which mirrors CPU
1005  * @gpuva_end: End address of GPUVA which mirrors CPU
1006  * @ctx: GPU SVM context
1007  *
1008  * This function finds or inserts a newly allocated a GPU SVM range based on the
1009  * fault address. Caller must hold a lock to protect range lookup and insertion.
1010  *
1011  * Return: Pointer to the GPU SVM range on success, ERR_PTR() on failure.
1012  */
1013 struct drm_gpusvm_range *
1014 drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm,
1015 				unsigned long fault_addr,
1016 				unsigned long gpuva_start,
1017 				unsigned long gpuva_end,
1018 				const struct drm_gpusvm_ctx *ctx)
1019 {
1020 	struct drm_gpusvm_notifier *notifier;
1021 	struct drm_gpusvm_range *range;
1022 	struct mm_struct *mm = gpusvm->mm;
1023 	struct vm_area_struct *vas;
1024 	bool notifier_alloc = false;
1025 	unsigned long chunk_size;
1026 	int err;
1027 	bool migrate_devmem;
1028 
1029 	drm_gpusvm_driver_lock_held(gpusvm);
1030 
1031 	if (fault_addr < gpusvm->mm_start ||
1032 	    fault_addr > gpusvm->mm_start + gpusvm->mm_range)
1033 		return ERR_PTR(-EINVAL);
1034 
1035 	if (!mmget_not_zero(mm))
1036 		return ERR_PTR(-EFAULT);
1037 
1038 	notifier = drm_gpusvm_notifier_find(gpusvm, fault_addr, fault_addr + 1);
1039 	if (!notifier) {
1040 		notifier = drm_gpusvm_notifier_alloc(gpusvm, fault_addr);
1041 		if (IS_ERR(notifier)) {
1042 			err = PTR_ERR(notifier);
1043 			goto err_mmunlock;
1044 		}
1045 		notifier_alloc = true;
1046 		err = mmu_interval_notifier_insert(&notifier->notifier,
1047 						   mm,
1048 						   drm_gpusvm_notifier_start(notifier),
1049 						   drm_gpusvm_notifier_size(notifier),
1050 						   &drm_gpusvm_notifier_ops);
1051 		if (err)
1052 			goto err_notifier;
1053 	}
1054 
1055 	mmap_read_lock(mm);
1056 
1057 	vas = vma_lookup(mm, fault_addr);
1058 	if (!vas) {
1059 		err = -ENOENT;
1060 		goto err_notifier_remove;
1061 	}
1062 
1063 	if (!ctx->read_only && !(vas->vm_flags & VM_WRITE)) {
1064 		err = -EPERM;
1065 		goto err_notifier_remove;
1066 	}
1067 
1068 	if (vas->vm_flags & (VM_IO | VM_PFNMAP)) {
1069 		err = -EIO;
1070 		goto err_notifier_remove;
1071 	}
1072 
1073 	range = drm_gpusvm_range_find(notifier, fault_addr, fault_addr + 1);
1074 	if (range)
1075 		goto out_mmunlock;
1076 	/*
1077 	 * XXX: Short-circuiting migration based on migrate_vma_* current
1078 	 * limitations. If/when migrate_vma_* add more support, this logic will
1079 	 * have to change.
1080 	 */
1081 	migrate_devmem = ctx->devmem_possible &&
1082 		vma_is_anonymous(vas) && !is_vm_hugetlb_page(vas);
1083 
1084 	chunk_size = drm_gpusvm_range_chunk_size(gpusvm, notifier, vas,
1085 						 fault_addr, gpuva_start,
1086 						 gpuva_end,
1087 						 ctx->check_pages_threshold,
1088 						 ctx->device_private_page_owner);
1089 	if (chunk_size == LONG_MAX) {
1090 		err = -EINVAL;
1091 		goto err_notifier_remove;
1092 	}
1093 
1094 	range = drm_gpusvm_range_alloc(gpusvm, notifier, fault_addr, chunk_size,
1095 				       migrate_devmem);
1096 	if (IS_ERR(range)) {
1097 		err = PTR_ERR(range);
1098 		goto err_notifier_remove;
1099 	}
1100 
1101 	drm_gpusvm_range_insert(notifier, range);
1102 	if (notifier_alloc)
1103 		drm_gpusvm_notifier_insert(gpusvm, notifier);
1104 
1105 out_mmunlock:
1106 	mmap_read_unlock(mm);
1107 	mmput(mm);
1108 
1109 	return range;
1110 
1111 err_notifier_remove:
1112 	mmap_read_unlock(mm);
1113 	if (notifier_alloc)
1114 		mmu_interval_notifier_remove(&notifier->notifier);
1115 err_notifier:
1116 	if (notifier_alloc)
1117 		drm_gpusvm_notifier_free(gpusvm, notifier);
1118 err_mmunlock:
1119 	mmput(mm);
1120 	return ERR_PTR(err);
1121 }
1122 EXPORT_SYMBOL_GPL(drm_gpusvm_range_find_or_insert);
1123 
1124 /**
1125  * __drm_gpusvm_unmap_pages() - Unmap pages associated with GPU SVM pages (internal)
1126  * @gpusvm: Pointer to the GPU SVM structure
1127  * @svm_pages: Pointer to the GPU SVM pages structure
1128  * @npages: Number of pages to unmap
1129  *
1130  * This function unmap pages associated with a GPU SVM pages struct. Assumes and
1131  * asserts correct locking is in place when called.
1132  */
1133 static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm,
1134 				     struct drm_gpusvm_pages *svm_pages,
1135 				     unsigned long npages)
1136 {
1137 	struct drm_pagemap *dpagemap = svm_pages->dpagemap;
1138 	struct device *dev = gpusvm->drm->dev;
1139 	unsigned long i, j;
1140 
1141 	lockdep_assert_held(&gpusvm->notifier_lock);
1142 
1143 	if (svm_pages->flags.has_dma_mapping) {
1144 		struct drm_gpusvm_pages_flags flags = {
1145 			.__flags = svm_pages->flags.__flags,
1146 		};
1147 		bool use_iova = dma_use_iova(&svm_pages->state);
1148 
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);
1153 
1154 		for (i = 0, j = 0; i < npages; j++) {
1155 			struct drm_pagemap_addr *addr = &svm_pages->dma_addr[j];
1156 
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)
1163 				dpagemap->ops->device_unmap(dpagemap,
1164 							    dev, addr);
1165 			i += 1 << addr->order;
1166 		}
1167 
1168 		/* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
1169 		flags.has_devmem_pages = false;
1170 		flags.has_dma_mapping = false;
1171 		WRITE_ONCE(svm_pages->flags.__flags, flags.__flags);
1172 
1173 		drm_pagemap_put(svm_pages->dpagemap);
1174 		svm_pages->dpagemap = NULL;
1175 	}
1176 }
1177 
1178 /**
1179  * __drm_gpusvm_free_pages() - Free dma array associated with GPU SVM pages
1180  * @gpusvm: Pointer to the GPU SVM structure
1181  * @svm_pages: Pointer to the GPU SVM pages structure
1182  *
1183  * This function frees the dma address array associated with a GPU SVM range.
1184  */
1185 static void __drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm,
1186 				    struct drm_gpusvm_pages *svm_pages)
1187 {
1188 	lockdep_assert_held(&gpusvm->notifier_lock);
1189 
1190 	if (svm_pages->dma_addr) {
1191 		kvfree(svm_pages->dma_addr);
1192 		svm_pages->dma_addr = NULL;
1193 	}
1194 }
1195 
1196 /**
1197  * drm_gpusvm_free_pages() - Free dma-mapping associated with GPU SVM pages
1198  * struct
1199  * @gpusvm: Pointer to the GPU SVM structure
1200  * @svm_pages: Pointer to the GPU SVM pages structure
1201  * @npages: Number of mapped pages
1202  *
1203  * This function unmaps and frees the dma address array associated with a GPU
1204  * SVM pages struct.
1205  */
1206 void drm_gpusvm_free_pages(struct drm_gpusvm *gpusvm,
1207 			   struct drm_gpusvm_pages *svm_pages,
1208 			   unsigned long npages)
1209 {
1210 	drm_gpusvm_notifier_lock(gpusvm);
1211 	__drm_gpusvm_unmap_pages(gpusvm, svm_pages, npages);
1212 	__drm_gpusvm_free_pages(gpusvm, svm_pages);
1213 	drm_gpusvm_notifier_unlock(gpusvm);
1214 }
1215 EXPORT_SYMBOL_GPL(drm_gpusvm_free_pages);
1216 
1217 /**
1218  * drm_gpusvm_range_remove() - Remove GPU SVM range
1219  * @gpusvm: Pointer to the GPU SVM structure
1220  * @range: Pointer to the GPU SVM range to be removed
1221  *
1222  * This function removes the specified GPU SVM range and also removes the parent
1223  * GPU SVM notifier if no more ranges remain in the notifier. The caller must
1224  * hold a lock to protect range and notifier removal.
1225  */
1226 void drm_gpusvm_range_remove(struct drm_gpusvm *gpusvm,
1227 			     struct drm_gpusvm_range *range)
1228 {
1229 	unsigned long npages = npages_in_range(drm_gpusvm_range_start(range),
1230 					       drm_gpusvm_range_end(range));
1231 	struct drm_gpusvm_notifier *notifier;
1232 
1233 	drm_gpusvm_driver_lock_held(gpusvm);
1234 
1235 	notifier = drm_gpusvm_notifier_find(gpusvm,
1236 					    drm_gpusvm_range_start(range),
1237 					    drm_gpusvm_range_start(range) + 1);
1238 	if (WARN_ON_ONCE(!notifier))
1239 		return;
1240 
1241 	drm_gpusvm_notifier_lock(gpusvm);
1242 	__drm_gpusvm_unmap_pages(gpusvm, &range->pages, npages);
1243 	__drm_gpusvm_free_pages(gpusvm, &range->pages);
1244 	__drm_gpusvm_range_remove(notifier, range);
1245 	drm_gpusvm_notifier_unlock(gpusvm);
1246 
1247 	drm_gpusvm_range_put(range);
1248 
1249 	if (RB_EMPTY_ROOT(&notifier->root.rb_root)) {
1250 		if (!notifier->flags.removed)
1251 			mmu_interval_notifier_remove(&notifier->notifier);
1252 		drm_gpusvm_notifier_remove(gpusvm, notifier);
1253 		drm_gpusvm_notifier_free(gpusvm, notifier);
1254 	}
1255 }
1256 EXPORT_SYMBOL_GPL(drm_gpusvm_range_remove);
1257 
1258 /**
1259  * drm_gpusvm_range_get() - Get a reference to GPU SVM range
1260  * @range: Pointer to the GPU SVM range
1261  *
1262  * This function increments the reference count of the specified GPU SVM range.
1263  *
1264  * Return: Pointer to the GPU SVM range.
1265  */
1266 struct drm_gpusvm_range *
1267 drm_gpusvm_range_get(struct drm_gpusvm_range *range)
1268 {
1269 	kref_get(&range->refcount);
1270 
1271 	return range;
1272 }
1273 EXPORT_SYMBOL_GPL(drm_gpusvm_range_get);
1274 
1275 /**
1276  * drm_gpusvm_range_destroy() - Destroy GPU SVM range
1277  * @refcount: Pointer to the reference counter embedded in the GPU SVM range
1278  *
1279  * This function destroys the specified GPU SVM range when its reference count
1280  * reaches zero. If a custom range-free function is provided, it is invoked to
1281  * free the range; otherwise, the range is deallocated using kfree().
1282  */
1283 static void drm_gpusvm_range_destroy(struct kref *refcount)
1284 {
1285 	struct drm_gpusvm_range *range =
1286 		container_of(refcount, struct drm_gpusvm_range, refcount);
1287 	struct drm_gpusvm *gpusvm = range->gpusvm;
1288 
1289 	if (gpusvm->ops->range_free)
1290 		gpusvm->ops->range_free(range);
1291 	else
1292 		kfree(range);
1293 }
1294 
1295 /**
1296  * drm_gpusvm_range_put() - Put a reference to GPU SVM range
1297  * @range: Pointer to the GPU SVM range
1298  *
1299  * This function decrements the reference count of the specified GPU SVM range
1300  * and frees it when the count reaches zero.
1301  */
1302 void drm_gpusvm_range_put(struct drm_gpusvm_range *range)
1303 {
1304 	kref_put(&range->refcount, drm_gpusvm_range_destroy);
1305 }
1306 EXPORT_SYMBOL_GPL(drm_gpusvm_range_put);
1307 
1308 /**
1309  * drm_gpusvm_pages_valid() - GPU SVM range pages valid
1310  * @gpusvm: Pointer to the GPU SVM structure
1311  * @svm_pages: Pointer to the GPU SVM pages structure
1312  *
1313  * This function determines if a GPU SVM range pages are valid. Expected be
1314  * called holding gpusvm->notifier_lock and as the last step before committing a
1315  * GPU binding. This is akin to a notifier seqno check in the HMM documentation
1316  * but due to wider notifiers (i.e., notifiers which span multiple ranges) this
1317  * function is required for finer grained checking (i.e., per range) if pages
1318  * are valid.
1319  *
1320  * Return: True if GPU SVM range has valid pages, False otherwise
1321  */
1322 static bool drm_gpusvm_pages_valid(struct drm_gpusvm *gpusvm,
1323 				   struct drm_gpusvm_pages *svm_pages)
1324 {
1325 	lockdep_assert_held(&gpusvm->notifier_lock);
1326 
1327 	return svm_pages->flags.has_devmem_pages || svm_pages->flags.has_dma_mapping;
1328 }
1329 
1330 /**
1331  * drm_gpusvm_range_pages_valid() - GPU SVM range pages valid
1332  * @gpusvm: Pointer to the GPU SVM structure
1333  * @range: Pointer to the GPU SVM range structure
1334  *
1335  * This function determines if a GPU SVM range pages are valid. Expected be
1336  * called holding gpusvm->notifier_lock and as the last step before committing a
1337  * GPU binding. This is akin to a notifier seqno check in the HMM documentation
1338  * but due to wider notifiers (i.e., notifiers which span multiple ranges) this
1339  * function is required for finer grained checking (i.e., per range) if pages
1340  * are valid.
1341  *
1342  * Return: True if GPU SVM range has valid pages, False otherwise
1343  */
1344 bool drm_gpusvm_range_pages_valid(struct drm_gpusvm *gpusvm,
1345 				  struct drm_gpusvm_range *range)
1346 {
1347 	return drm_gpusvm_pages_valid(gpusvm, &range->pages);
1348 }
1349 EXPORT_SYMBOL_GPL(drm_gpusvm_range_pages_valid);
1350 
1351 /**
1352  * drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked
1353  * @gpusvm: Pointer to the GPU SVM structure
1354  * @svm_pages: Pointer to the GPU SVM pages structure
1355  *
1356  * This function determines if a GPU SVM pages are valid. Expected be called
1357  * without holding gpusvm->notifier_lock.
1358  *
1359  * Return: True if GPU SVM pages are valid, False otherwise
1360  */
1361 static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm,
1362 					    struct drm_gpusvm_pages *svm_pages)
1363 {
1364 	bool pages_valid;
1365 
1366 	if (!svm_pages->dma_addr)
1367 		return false;
1368 
1369 	drm_gpusvm_notifier_lock(gpusvm);
1370 	pages_valid = drm_gpusvm_pages_valid(gpusvm, svm_pages);
1371 	if (!pages_valid)
1372 		__drm_gpusvm_free_pages(gpusvm, svm_pages);
1373 	drm_gpusvm_notifier_unlock(gpusvm);
1374 
1375 	return pages_valid;
1376 }
1377 
1378 /**
1379  * drm_gpusvm_get_pages() - Get pages and populate GPU SVM pages struct
1380  * @gpusvm: Pointer to the GPU SVM structure
1381  * @svm_pages: The SVM pages to populate. This will contain the dma-addresses
1382  * @mm: The mm corresponding to the CPU range
1383  * @notifier: The corresponding notifier for the given CPU range
1384  * @pages_start: Start CPU address for the pages
1385  * @pages_end: End CPU address for the pages (exclusive)
1386  * @ctx: GPU SVM context
1387  *
1388  * This function gets and maps pages for CPU range and ensures they are
1389  * mapped for DMA access.
1390  *
1391  * Return: 0 on success, negative error code on failure.
1392  */
1393 int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm,
1394 			 struct drm_gpusvm_pages *svm_pages,
1395 			 struct mm_struct *mm,
1396 			 struct mmu_interval_notifier *notifier,
1397 			 unsigned long pages_start, unsigned long pages_end,
1398 			 const struct drm_gpusvm_ctx *ctx)
1399 {
1400 	struct hmm_range hmm_range = {
1401 		.default_flags = HMM_PFN_REQ_FAULT | (ctx->read_only ? 0 :
1402 			HMM_PFN_REQ_WRITE),
1403 		.notifier = notifier,
1404 		.start = pages_start,
1405 		.end = pages_end,
1406 		.dev_private_owner = ctx->device_private_page_owner,
1407 	};
1408 	void *zdd;
1409 	unsigned long timeout =
1410 		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
1411 	unsigned long i, j;
1412 	unsigned long npages = npages_in_range(pages_start, pages_end);
1413 	unsigned long num_dma_mapped;
1414 	unsigned int order = 0;
1415 	unsigned long *pfns;
1416 	int err = 0;
1417 	struct dev_pagemap *pagemap;
1418 	struct drm_pagemap *dpagemap;
1419 	struct drm_gpusvm_pages_flags flags;
1420 	enum dma_data_direction dma_dir = ctx->read_only ? DMA_TO_DEVICE :
1421 							   DMA_BIDIRECTIONAL;
1422 	struct dma_iova_state *state = &svm_pages->state;
1423 
1424 retry:
1425 	if (time_after(jiffies, timeout))
1426 		return -EBUSY;
1427 
1428 	hmm_range.notifier_seq = mmu_interval_read_begin(notifier);
1429 	if (drm_gpusvm_pages_valid_unlocked(gpusvm, svm_pages))
1430 		goto set_seqno;
1431 
1432 	pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL);
1433 	if (!pfns)
1434 		return -ENOMEM;
1435 
1436 	if (!mmget_not_zero(mm)) {
1437 		err = -EFAULT;
1438 		goto err_free;
1439 	}
1440 
1441 	hmm_range.hmm_pfns = pfns;
1442 	while (true) {
1443 		mmap_read_lock(mm);
1444 		err = hmm_range_fault(&hmm_range);
1445 		mmap_read_unlock(mm);
1446 
1447 		if (err == -EBUSY) {
1448 			if (time_after(jiffies, timeout))
1449 				break;
1450 
1451 			hmm_range.notifier_seq =
1452 				mmu_interval_read_begin(notifier);
1453 			continue;
1454 		}
1455 		break;
1456 	}
1457 	mmput(mm);
1458 	if (err)
1459 		goto err_free;
1460 
1461 	*state = (struct dma_iova_state){};
1462 	svm_pages->state_offset = 0;
1463 
1464 map_pages:
1465 	/*
1466 	 * Perform all dma mappings under the notifier lock to not
1467 	 * access freed pages. A notifier will either block on
1468 	 * the notifier lock or unmap dma.
1469 	 */
1470 	drm_gpusvm_notifier_lock(gpusvm);
1471 
1472 	flags.__flags = svm_pages->flags.__flags;
1473 	if (flags.unmapped) {
1474 		drm_gpusvm_notifier_unlock(gpusvm);
1475 		err = -EFAULT;
1476 		goto err_free;
1477 	}
1478 
1479 	if (mmu_interval_read_retry(notifier, hmm_range.notifier_seq)) {
1480 		drm_gpusvm_notifier_unlock(gpusvm);
1481 		kvfree(pfns);
1482 		goto retry;
1483 	}
1484 
1485 	if (!svm_pages->dma_addr) {
1486 		/* Unlock and restart mapping to allocate memory. */
1487 		drm_gpusvm_notifier_unlock(gpusvm);
1488 		svm_pages->dma_addr =
1489 			kvmalloc_objs(*svm_pages->dma_addr, npages);
1490 		if (!svm_pages->dma_addr) {
1491 			err = -ENOMEM;
1492 			goto err_free;
1493 		}
1494 		goto map_pages;
1495 	}
1496 
1497 	zdd = NULL;
1498 	pagemap = NULL;
1499 	num_dma_mapped = 0;
1500 	for (i = 0, j = 0; i < npages; ++j) {
1501 		struct page *page = hmm_pfn_to_page(pfns[i]);
1502 
1503 		order = drm_gpusvm_hmm_pfn_to_order(pfns[i], i, npages);
1504 		if (is_device_private_page(page) ||
1505 		    is_device_coherent_page(page)) {
1506 			struct drm_pagemap_zdd *__zdd =
1507 				drm_pagemap_page_zone_device_data(page);
1508 
1509 			if (!ctx->allow_mixed &&
1510 			    zdd != __zdd && i > 0) {
1511 				err = -EOPNOTSUPP;
1512 				goto err_unmap;
1513 			}
1514 			zdd = __zdd;
1515 			if (pagemap != page_pgmap(page)) {
1516 				if (pagemap) {
1517 					err = -EOPNOTSUPP;
1518 					goto err_unmap;
1519 				}
1520 
1521 				pagemap = page_pgmap(page);
1522 				dpagemap = drm_pagemap_page_to_dpagemap(page);
1523 				if (drm_WARN_ON(gpusvm->drm, !dpagemap)) {
1524 					/*
1525 					 * Raced. This is not supposed to happen
1526 					 * since hmm_range_fault() should've migrated
1527 					 * this page to system.
1528 					 */
1529 					err = -EAGAIN;
1530 					goto err_unmap;
1531 				}
1532 			}
1533 			svm_pages->dma_addr[j] =
1534 				dpagemap->ops->device_map(dpagemap,
1535 							  gpusvm->drm->dev,
1536 							  page, order,
1537 							  dma_dir);
1538 			if (dma_mapping_error(gpusvm->drm->dev,
1539 					      svm_pages->dma_addr[j].addr)) {
1540 				err = -EFAULT;
1541 				goto err_unmap;
1542 			}
1543 		} else {
1544 			dma_addr_t addr;
1545 
1546 			if (is_zone_device_page(page) ||
1547 			    (pagemap && !ctx->allow_mixed)) {
1548 				err = -EOPNOTSUPP;
1549 				goto err_unmap;
1550 			}
1551 
1552 			if (ctx->devmem_only) {
1553 				err = -EFAULT;
1554 				goto err_unmap;
1555 			}
1556 
1557 			if (!i)
1558 				dma_iova_try_alloc(gpusvm->drm->dev, state,
1559 						   0, npages * PAGE_SIZE);
1560 
1561 			if (dma_use_iova(state)) {
1562 				err = dma_iova_link(gpusvm->drm->dev, state,
1563 						    hmm_pfn_to_phys(pfns[i]),
1564 						    svm_pages->state_offset,
1565 						    PAGE_SIZE << order,
1566 						    dma_dir, 0);
1567 				if (err)
1568 					goto err_unmap;
1569 
1570 				addr = state->addr + svm_pages->state_offset;
1571 				svm_pages->state_offset += PAGE_SIZE << order;
1572 			} else {
1573 				addr = dma_map_page(gpusvm->drm->dev,
1574 						    page, 0,
1575 						    PAGE_SIZE << order,
1576 						    dma_dir);
1577 				if (dma_mapping_error(gpusvm->drm->dev, addr)) {
1578 					err = -EFAULT;
1579 					goto err_unmap;
1580 				}
1581 			}
1582 
1583 			svm_pages->dma_addr[j] = drm_pagemap_addr_encode
1584 				(addr, DRM_INTERCONNECT_SYSTEM, order,
1585 				 dma_dir);
1586 		}
1587 		i += 1 << order;
1588 		num_dma_mapped = i;
1589 		flags.has_dma_mapping = true;
1590 	}
1591 
1592 	if (dma_use_iova(state)) {
1593 		err = dma_iova_sync(gpusvm->drm->dev, state, 0,
1594 				    svm_pages->state_offset);
1595 		if (err)
1596 			goto err_unmap;
1597 	}
1598 
1599 	if (pagemap) {
1600 		flags.has_devmem_pages = true;
1601 		drm_pagemap_get(dpagemap);
1602 		drm_pagemap_put(svm_pages->dpagemap);
1603 		svm_pages->dpagemap = dpagemap;
1604 	}
1605 
1606 	/* WRITE_ONCE pairs with READ_ONCE for opportunistic checks */
1607 	WRITE_ONCE(svm_pages->flags.__flags, flags.__flags);
1608 
1609 	drm_gpusvm_notifier_unlock(gpusvm);
1610 	kvfree(pfns);
1611 set_seqno:
1612 	svm_pages->notifier_seq = hmm_range.notifier_seq;
1613 
1614 	return 0;
1615 
1616 err_unmap:
1617 	svm_pages->flags.has_dma_mapping = true;
1618 	__drm_gpusvm_unmap_pages(gpusvm, svm_pages, num_dma_mapped);
1619 	drm_gpusvm_notifier_unlock(gpusvm);
1620 err_free:
1621 	kvfree(pfns);
1622 	if (err == -EAGAIN)
1623 		goto retry;
1624 	return err;
1625 }
1626 EXPORT_SYMBOL_GPL(drm_gpusvm_get_pages);
1627 
1628 /**
1629  * drm_gpusvm_range_get_pages() - Get pages for a GPU SVM range
1630  * @gpusvm: Pointer to the GPU SVM structure
1631  * @range: Pointer to the GPU SVM range structure
1632  * @ctx: GPU SVM context
1633  *
1634  * This function gets pages for a GPU SVM range and ensures they are mapped for
1635  * DMA access.
1636  *
1637  * Return: 0 on success, negative error code on failure.
1638  */
1639 int drm_gpusvm_range_get_pages(struct drm_gpusvm *gpusvm,
1640 			       struct drm_gpusvm_range *range,
1641 			       const struct drm_gpusvm_ctx *ctx)
1642 {
1643 	return drm_gpusvm_get_pages(gpusvm, &range->pages, gpusvm->mm,
1644 				    &range->notifier->notifier,
1645 				    drm_gpusvm_range_start(range),
1646 				    drm_gpusvm_range_end(range), ctx);
1647 }
1648 EXPORT_SYMBOL_GPL(drm_gpusvm_range_get_pages);
1649 
1650 /**
1651  * drm_gpusvm_unmap_pages() - Unmap GPU svm pages
1652  * @gpusvm: Pointer to the GPU SVM structure
1653  * @svm_pages: Pointer to the GPU SVM pages structure
1654  * @npages: Number of pages in @svm_pages.
1655  * @ctx: GPU SVM context
1656  *
1657  * This function unmaps pages associated with a GPU SVM pages struct. If
1658  * @in_notifier is set, it is assumed that gpusvm->notifier_lock is held in
1659  * write mode; if it is clear, it acquires gpusvm->notifier_lock in read mode.
1660  * Must be called in the invalidate() callback of the corresponding notifier for
1661  * IOMMU security model.
1662  */
1663 void drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm,
1664 			    struct drm_gpusvm_pages *svm_pages,
1665 			    unsigned long npages,
1666 			    const struct drm_gpusvm_ctx *ctx)
1667 {
1668 	if (ctx->in_notifier)
1669 		lockdep_assert_held_write(&gpusvm->notifier_lock);
1670 	else
1671 		drm_gpusvm_notifier_lock(gpusvm);
1672 
1673 	__drm_gpusvm_unmap_pages(gpusvm, svm_pages, npages);
1674 
1675 	if (!ctx->in_notifier)
1676 		drm_gpusvm_notifier_unlock(gpusvm);
1677 }
1678 EXPORT_SYMBOL_GPL(drm_gpusvm_unmap_pages);
1679 
1680 /**
1681  * drm_gpusvm_range_unmap_pages() - Unmap pages associated with a GPU SVM range
1682  * @gpusvm: Pointer to the GPU SVM structure
1683  * @range: Pointer to the GPU SVM range structure
1684  * @ctx: GPU SVM context
1685  *
1686  * This function unmaps pages associated with a GPU SVM range. If @in_notifier
1687  * is set, it is assumed that gpusvm->notifier_lock is held in write mode; if it
1688  * is clear, it acquires gpusvm->notifier_lock in read mode. Must be called on
1689  * each GPU SVM range attached to notifier in gpusvm->ops->invalidate for IOMMU
1690  * security model.
1691  */
1692 void drm_gpusvm_range_unmap_pages(struct drm_gpusvm *gpusvm,
1693 				  struct drm_gpusvm_range *range,
1694 				  const struct drm_gpusvm_ctx *ctx)
1695 {
1696 	unsigned long npages = npages_in_range(drm_gpusvm_range_start(range),
1697 					       drm_gpusvm_range_end(range));
1698 
1699 	return drm_gpusvm_unmap_pages(gpusvm, &range->pages, npages, ctx);
1700 }
1701 EXPORT_SYMBOL_GPL(drm_gpusvm_range_unmap_pages);
1702 
1703 /**
1704  * drm_gpusvm_range_evict() - Evict GPU SVM range
1705  * @gpusvm: Pointer to the GPU SVM structure
1706  * @range: Pointer to the GPU SVM range to be removed
1707  *
1708  * This function evicts the specified GPU SVM range.
1709  *
1710  * Return: 0 on success, a negative error code on failure.
1711  */
1712 int drm_gpusvm_range_evict(struct drm_gpusvm *gpusvm,
1713 			   struct drm_gpusvm_range *range)
1714 {
1715 	struct mmu_interval_notifier *notifier = &range->notifier->notifier;
1716 	struct hmm_range hmm_range = {
1717 		.default_flags = HMM_PFN_REQ_FAULT,
1718 		.notifier = notifier,
1719 		.start = drm_gpusvm_range_start(range),
1720 		.end = drm_gpusvm_range_end(range),
1721 		.dev_private_owner = NULL,
1722 	};
1723 	unsigned long timeout =
1724 		jiffies + msecs_to_jiffies(HMM_RANGE_DEFAULT_TIMEOUT);
1725 	unsigned long *pfns;
1726 	unsigned long npages = npages_in_range(drm_gpusvm_range_start(range),
1727 					       drm_gpusvm_range_end(range));
1728 	int err = 0;
1729 	struct mm_struct *mm = gpusvm->mm;
1730 
1731 	if (!mmget_not_zero(mm))
1732 		return -EFAULT;
1733 
1734 	pfns = kvmalloc_array(npages, sizeof(*pfns), GFP_KERNEL);
1735 	if (!pfns)
1736 		return -ENOMEM;
1737 
1738 	hmm_range.hmm_pfns = pfns;
1739 	while (!time_after(jiffies, timeout)) {
1740 		hmm_range.notifier_seq = mmu_interval_read_begin(notifier);
1741 		if (time_after(jiffies, timeout)) {
1742 			err = -ETIME;
1743 			break;
1744 		}
1745 
1746 		mmap_read_lock(mm);
1747 		err = hmm_range_fault(&hmm_range);
1748 		mmap_read_unlock(mm);
1749 		if (err != -EBUSY)
1750 			break;
1751 	}
1752 
1753 	kvfree(pfns);
1754 	mmput(mm);
1755 
1756 	return err;
1757 }
1758 EXPORT_SYMBOL_GPL(drm_gpusvm_range_evict);
1759 
1760 /**
1761  * drm_gpusvm_has_mapping() - Check if GPU SVM has mapping for the given address range
1762  * @gpusvm: Pointer to the GPU SVM structure.
1763  * @start: Start address
1764  * @end: End address
1765  *
1766  * Return: True if GPU SVM has mapping, False otherwise
1767  */
1768 bool drm_gpusvm_has_mapping(struct drm_gpusvm *gpusvm, unsigned long start,
1769 			    unsigned long end)
1770 {
1771 	struct drm_gpusvm_notifier *notifier;
1772 
1773 	drm_gpusvm_for_each_notifier(notifier, gpusvm, start, end) {
1774 		struct drm_gpusvm_range *range = NULL;
1775 
1776 		drm_gpusvm_for_each_range(range, notifier, start, end)
1777 			return true;
1778 	}
1779 
1780 	return false;
1781 }
1782 EXPORT_SYMBOL_GPL(drm_gpusvm_has_mapping);
1783 
1784 /**
1785  * drm_gpusvm_range_set_unmapped() - Mark a GPU SVM range as unmapped
1786  * @range: Pointer to the GPU SVM range structure.
1787  * @mmu_range: Pointer to the MMU notifier range structure.
1788  *
1789  * This function marks a GPU SVM range as unmapped and sets the partial_unmap flag
1790  * if the range partially falls within the provided MMU notifier range.
1791  */
1792 void drm_gpusvm_range_set_unmapped(struct drm_gpusvm_range *range,
1793 				   const struct mmu_notifier_range *mmu_range)
1794 {
1795 	lockdep_assert_held_write(&range->gpusvm->notifier_lock);
1796 
1797 	range->pages.flags.unmapped = true;
1798 	if (drm_gpusvm_range_start(range) < mmu_range->start ||
1799 	    drm_gpusvm_range_end(range) > mmu_range->end)
1800 		range->pages.flags.partial_unmap = true;
1801 }
1802 EXPORT_SYMBOL_GPL(drm_gpusvm_range_set_unmapped);
1803 
1804 MODULE_DESCRIPTION("DRM GPUSVM");
1805 MODULE_LICENSE("GPL");
1806