xref: /linux/drivers/gpu/drm/drm_gpuvm.c (revision ab779466166348eecf17d20f620aa9a47965c934)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3  * Copyright (c) 2022 Red Hat.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *     Danilo Krummrich <dakr@redhat.com>
25  *
26  */
27 
28 #include <drm/drm_gpuvm.h>
29 
30 #include <linux/interval_tree_generic.h>
31 #include <linux/mm.h>
32 
33 /**
34  * DOC: Overview
35  *
36  * The DRM GPU VA Manager, represented by struct drm_gpuvm keeps track of a
37  * GPU's virtual address (VA) space and manages the corresponding virtual
38  * mappings represented by &drm_gpuva objects. It also keeps track of the
39  * mapping's backing &drm_gem_object buffers.
40  *
41  * &drm_gem_object buffers maintain a list of &drm_gpuva objects representing
42  * all existent GPU VA mappings using this &drm_gem_object as backing buffer.
43  *
44  * GPU VAs can be flagged as sparse, such that drivers may use GPU VAs to also
45  * keep track of sparse PTEs in order to support Vulkan 'Sparse Resources'.
46  *
47  * The GPU VA manager internally uses a rb-tree to manage the
48  * &drm_gpuva mappings within a GPU's virtual address space.
49  *
50  * The &drm_gpuvm structure contains a special &drm_gpuva representing the
51  * portion of VA space reserved by the kernel. This node is initialized together
52  * with the GPU VA manager instance and removed when the GPU VA manager is
53  * destroyed.
54  *
55  * In a typical application drivers would embed struct drm_gpuvm and
56  * struct drm_gpuva within their own driver specific structures, there won't be
57  * any memory allocations of its own nor memory allocations of &drm_gpuva
58  * entries.
59  *
60  * The data structures needed to store &drm_gpuvas within the &drm_gpuvm are
61  * contained within struct drm_gpuva already. Hence, for inserting &drm_gpuva
62  * entries from within dma-fence signalling critical sections it is enough to
63  * pre-allocate the &drm_gpuva structures.
64  *
65  * &drm_gem_objects which are private to a single VM can share a common
66  * &dma_resv in order to improve locking efficiency (e.g. with &drm_exec).
67  * For this purpose drivers must pass a &drm_gem_object to drm_gpuvm_init(), in
68  * the following called 'resv object', which serves as the container of the
69  * GPUVM's shared &dma_resv. This resv object can be a driver specific
70  * &drm_gem_object, such as the &drm_gem_object containing the root page table,
71  * but it can also be a 'dummy' object, which can be allocated with
72  * drm_gpuvm_resv_object_alloc().
73  *
74  * In order to connect a struct drm_gpuva its backing &drm_gem_object each
75  * &drm_gem_object maintains a list of &drm_gpuvm_bo structures, and each
76  * &drm_gpuvm_bo contains a list of &drm_gpuva structures.
77  *
78  * A &drm_gpuvm_bo is an abstraction that represents a combination of a
79  * &drm_gpuvm and a &drm_gem_object. Every such combination should be unique.
80  * This is ensured by the API through drm_gpuvm_bo_obtain() and
81  * drm_gpuvm_bo_obtain_prealloc() which first look into the corresponding
82  * &drm_gem_object list of &drm_gpuvm_bos for an existing instance of this
83  * particular combination. If not existent a new instance is created and linked
84  * to the &drm_gem_object.
85  *
86  * &drm_gpuvm_bo structures, since unique for a given &drm_gpuvm, are also used
87  * as entry for the &drm_gpuvm's lists of external and evicted objects. Those
88  * lists are maintained in order to accelerate locking of dma-resv locks and
89  * validation of evicted objects bound in a &drm_gpuvm. For instance, all
90  * &drm_gem_object's &dma_resv of a given &drm_gpuvm can be locked by calling
91  * drm_gpuvm_exec_lock(). Once locked drivers can call drm_gpuvm_validate() in
92  * order to validate all evicted &drm_gem_objects. It is also possible to lock
93  * additional &drm_gem_objects by providing the corresponding parameters to
94  * drm_gpuvm_exec_lock() as well as open code the &drm_exec loop while making
95  * use of helper functions such as drm_gpuvm_prepare_range() or
96  * drm_gpuvm_prepare_objects().
97  *
98  * Every bound &drm_gem_object is treated as external object when its &dma_resv
99  * structure is different than the &drm_gpuvm's common &dma_resv structure.
100  */
101 
102 /**
103  * DOC: Split and Merge
104  *
105  * Besides its capability to manage and represent a GPU VA space, the
106  * GPU VA manager also provides functions to let the &drm_gpuvm calculate a
107  * sequence of operations to satisfy a given map or unmap request.
108  *
109  * Therefore the DRM GPU VA manager provides an algorithm implementing splitting
110  * and merging of existent GPU VA mappings with the ones that are requested to
111  * be mapped or unmapped. This feature is required by the Vulkan API to
112  * implement Vulkan 'Sparse Memory Bindings' - drivers UAPIs often refer to this
113  * as VM BIND.
114  *
115  * Drivers can call drm_gpuvm_sm_map() to receive a sequence of callbacks
116  * containing map, unmap and remap operations for a given newly requested
117  * mapping. The sequence of callbacks represents the set of operations to
118  * execute in order to integrate the new mapping cleanly into the current state
119  * of the GPU VA space.
120  *
121  * Depending on how the new GPU VA mapping intersects with the existent mappings
122  * of the GPU VA space the &drm_gpuvm_ops callbacks contain an arbitrary amount
123  * of unmap operations, a maximum of two remap operations and a single map
124  * operation. The caller might receive no callback at all if no operation is
125  * required, e.g. if the requested mapping already exists in the exact same way.
126  *
127  * The single map operation represents the original map operation requested by
128  * the caller.
129  *
130  * &drm_gpuva_op_unmap contains a 'keep' field, which indicates whether the
131  * &drm_gpuva to unmap is physically contiguous with the original mapping
132  * request. Optionally, if 'keep' is set, drivers may keep the actual page table
133  * entries for this &drm_gpuva, adding the missing page table entries only and
134  * update the &drm_gpuvm's view of things accordingly.
135  *
136  * Drivers may do the same optimization, namely delta page table updates, also
137  * for remap operations. This is possible since &drm_gpuva_op_remap consists of
138  * one unmap operation and one or two map operations, such that drivers can
139  * derive the page table update delta accordingly.
140  *
141  * Note that there can't be more than two existent mappings to split up, one at
142  * the beginning and one at the end of the new mapping, hence there is a
143  * maximum of two remap operations.
144  *
145  * Analogous to drm_gpuvm_sm_map() drm_gpuvm_sm_unmap() uses &drm_gpuvm_ops to
146  * call back into the driver in order to unmap a range of GPU VA space. The
147  * logic behind this function is way simpler though: For all existent mappings
148  * enclosed by the given range unmap operations are created. For mappings which
149  * are only partically located within the given range, remap operations are
150  * created such that those mappings are split up and re-mapped partically.
151  *
152  * As an alternative to drm_gpuvm_sm_map() and drm_gpuvm_sm_unmap(),
153  * drm_gpuvm_sm_map_ops_create() and drm_gpuvm_sm_unmap_ops_create() can be used
154  * to directly obtain an instance of struct drm_gpuva_ops containing a list of
155  * &drm_gpuva_op, which can be iterated with drm_gpuva_for_each_op(). This list
156  * contains the &drm_gpuva_ops analogous to the callbacks one would receive when
157  * calling drm_gpuvm_sm_map() or drm_gpuvm_sm_unmap(). While this way requires
158  * more memory (to allocate the &drm_gpuva_ops), it provides drivers a way to
159  * iterate the &drm_gpuva_op multiple times, e.g. once in a context where memory
160  * allocations are possible (e.g. to allocate GPU page tables) and once in the
161  * dma-fence signalling critical path.
162  *
163  * To update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert() and
164  * drm_gpuva_remove() may be used. These functions can safely be used from
165  * &drm_gpuvm_ops callbacks originating from drm_gpuvm_sm_map() or
166  * drm_gpuvm_sm_unmap(). However, it might be more convenient to use the
167  * provided helper functions drm_gpuva_map(), drm_gpuva_remap() and
168  * drm_gpuva_unmap() instead.
169  *
170  * The following diagram depicts the basic relationships of existent GPU VA
171  * mappings, a newly requested mapping and the resulting mappings as implemented
172  * by drm_gpuvm_sm_map() - it doesn't cover any arbitrary combinations of these.
173  *
174  * 1) Requested mapping is identical. Replace it, but indicate the backing PTEs
175  *    could be kept.
176  *
177  *    ::
178  *
179  *	     0     a     1
180  *	old: |-----------| (bo_offset=n)
181  *
182  *	     0     a     1
183  *	req: |-----------| (bo_offset=n)
184  *
185  *	     0     a     1
186  *	new: |-----------| (bo_offset=n)
187  *
188  *
189  * 2) Requested mapping is identical, except for the BO offset, hence replace
190  *    the mapping.
191  *
192  *    ::
193  *
194  *	     0     a     1
195  *	old: |-----------| (bo_offset=n)
196  *
197  *	     0     a     1
198  *	req: |-----------| (bo_offset=m)
199  *
200  *	     0     a     1
201  *	new: |-----------| (bo_offset=m)
202  *
203  *
204  * 3) Requested mapping is identical, except for the backing BO, hence replace
205  *    the mapping.
206  *
207  *    ::
208  *
209  *	     0     a     1
210  *	old: |-----------| (bo_offset=n)
211  *
212  *	     0     b     1
213  *	req: |-----------| (bo_offset=n)
214  *
215  *	     0     b     1
216  *	new: |-----------| (bo_offset=n)
217  *
218  *
219  * 4) Existent mapping is a left aligned subset of the requested one, hence
220  *    replace the existent one.
221  *
222  *    ::
223  *
224  *	     0  a  1
225  *	old: |-----|       (bo_offset=n)
226  *
227  *	     0     a     2
228  *	req: |-----------| (bo_offset=n)
229  *
230  *	     0     a     2
231  *	new: |-----------| (bo_offset=n)
232  *
233  *    .. note::
234  *       We expect to see the same result for a request with a different BO
235  *       and/or non-contiguous BO offset.
236  *
237  *
238  * 5) Requested mapping's range is a left aligned subset of the existent one,
239  *    but backed by a different BO. Hence, map the requested mapping and split
240  *    the existent one adjusting its BO offset.
241  *
242  *    ::
243  *
244  *	     0     a     2
245  *	old: |-----------| (bo_offset=n)
246  *
247  *	     0  b  1
248  *	req: |-----|       (bo_offset=n)
249  *
250  *	     0  b  1  a' 2
251  *	new: |-----|-----| (b.bo_offset=n, a.bo_offset=n+1)
252  *
253  *    .. note::
254  *       We expect to see the same result for a request with a different BO
255  *       and/or non-contiguous BO offset.
256  *
257  *
258  * 6) Existent mapping is a superset of the requested mapping. Split it up, but
259  *    indicate that the backing PTEs could be kept.
260  *
261  *    ::
262  *
263  *	     0     a     2
264  *	old: |-----------| (bo_offset=n)
265  *
266  *	     0  a  1
267  *	req: |-----|       (bo_offset=n)
268  *
269  *	     0  a  1  a' 2
270  *	new: |-----|-----| (a.bo_offset=n, a'.bo_offset=n+1)
271  *
272  *
273  * 7) Requested mapping's range is a right aligned subset of the existent one,
274  *    but backed by a different BO. Hence, map the requested mapping and split
275  *    the existent one, without adjusting the BO offset.
276  *
277  *    ::
278  *
279  *	     0     a     2
280  *	old: |-----------| (bo_offset=n)
281  *
282  *	           1  b  2
283  *	req:       |-----| (bo_offset=m)
284  *
285  *	     0  a  1  b  2
286  *	new: |-----|-----| (a.bo_offset=n,b.bo_offset=m)
287  *
288  *
289  * 8) Existent mapping is a superset of the requested mapping. Split it up, but
290  *    indicate that the backing PTEs could be kept.
291  *
292  *    ::
293  *
294  *	      0     a     2
295  *	old: |-----------| (bo_offset=n)
296  *
297  *	           1  a  2
298  *	req:       |-----| (bo_offset=n+1)
299  *
300  *	     0  a' 1  a  2
301  *	new: |-----|-----| (a'.bo_offset=n, a.bo_offset=n+1)
302  *
303  *
304  * 9) Existent mapping is overlapped at the end by the requested mapping backed
305  *    by a different BO. Hence, map the requested mapping and split up the
306  *    existent one, without adjusting the BO offset.
307  *
308  *    ::
309  *
310  *	     0     a     2
311  *	old: |-----------|       (bo_offset=n)
312  *
313  *	           1     b     3
314  *	req:       |-----------| (bo_offset=m)
315  *
316  *	     0  a  1     b     3
317  *	new: |-----|-----------| (a.bo_offset=n,b.bo_offset=m)
318  *
319  *
320  * 10) Existent mapping is overlapped by the requested mapping, both having the
321  *     same backing BO with a contiguous offset. Indicate the backing PTEs of
322  *     the old mapping could be kept.
323  *
324  *     ::
325  *
326  *	      0     a     2
327  *	 old: |-----------|       (bo_offset=n)
328  *
329  *	            1     a     3
330  *	 req:       |-----------| (bo_offset=n+1)
331  *
332  *	      0  a' 1     a     3
333  *	 new: |-----|-----------| (a'.bo_offset=n, a.bo_offset=n+1)
334  *
335  *
336  * 11) Requested mapping's range is a centered subset of the existent one
337  *     having a different backing BO. Hence, map the requested mapping and split
338  *     up the existent one in two mappings, adjusting the BO offset of the right
339  *     one accordingly.
340  *
341  *     ::
342  *
343  *	      0        a        3
344  *	 old: |-----------------| (bo_offset=n)
345  *
346  *	            1  b  2
347  *	 req:       |-----|       (bo_offset=m)
348  *
349  *	      0  a  1  b  2  a' 3
350  *	 new: |-----|-----|-----| (a.bo_offset=n,b.bo_offset=m,a'.bo_offset=n+2)
351  *
352  *
353  * 12) Requested mapping is a contiguous subset of the existent one. Split it
354  *     up, but indicate that the backing PTEs could be kept.
355  *
356  *     ::
357  *
358  *	      0        a        3
359  *	 old: |-----------------| (bo_offset=n)
360  *
361  *	            1  a  2
362  *	 req:       |-----|       (bo_offset=n+1)
363  *
364  *	      0  a' 1  a  2 a'' 3
365  *	 old: |-----|-----|-----| (a'.bo_offset=n, a.bo_offset=n+1, a''.bo_offset=n+2)
366  *
367  *
368  * 13) Existent mapping is a right aligned subset of the requested one, hence
369  *     replace the existent one.
370  *
371  *     ::
372  *
373  *	            1  a  2
374  *	 old:       |-----| (bo_offset=n+1)
375  *
376  *	      0     a     2
377  *	 req: |-----------| (bo_offset=n)
378  *
379  *	      0     a     2
380  *	 new: |-----------| (bo_offset=n)
381  *
382  *     .. note::
383  *        We expect to see the same result for a request with a different bo
384  *        and/or non-contiguous bo_offset.
385  *
386  *
387  * 14) Existent mapping is a centered subset of the requested one, hence
388  *     replace the existent one.
389  *
390  *     ::
391  *
392  *	            1  a  2
393  *	 old:       |-----| (bo_offset=n+1)
394  *
395  *	      0        a       3
396  *	 req: |----------------| (bo_offset=n)
397  *
398  *	      0        a       3
399  *	 new: |----------------| (bo_offset=n)
400  *
401  *     .. note::
402  *        We expect to see the same result for a request with a different bo
403  *        and/or non-contiguous bo_offset.
404  *
405  *
406  * 15) Existent mappings is overlapped at the beginning by the requested mapping
407  *     backed by a different BO. Hence, map the requested mapping and split up
408  *     the existent one, adjusting its BO offset accordingly.
409  *
410  *     ::
411  *
412  *	            1     a     3
413  *	 old:       |-----------| (bo_offset=n)
414  *
415  *	      0     b     2
416  *	 req: |-----------|       (bo_offset=m)
417  *
418  *	      0     b     2  a' 3
419  *	 new: |-----------|-----| (b.bo_offset=m,a.bo_offset=n+2)
420  */
421 
422 /**
423  * DOC: Locking
424  *
425  * In terms of managing &drm_gpuva entries DRM GPUVM does not take care of
426  * locking itself, it is the drivers responsibility to take care about locking.
427  * Drivers might want to protect the following operations: inserting, removing
428  * and iterating &drm_gpuva objects as well as generating all kinds of
429  * operations, such as split / merge or prefetch.
430  *
431  * DRM GPUVM also does not take care of the locking of the backing
432  * &drm_gem_object buffers GPU VA lists and &drm_gpuvm_bo abstractions by
433  * itself; drivers are responsible to enforce mutual exclusion using either the
434  * GEMs dma_resv lock or alternatively a driver specific external lock. For the
435  * latter see also drm_gem_gpuva_set_lock().
436  *
437  * However, DRM GPUVM contains lockdep checks to ensure callers of its API hold
438  * the corresponding lock whenever the &drm_gem_objects GPU VA list is accessed
439  * by functions such as drm_gpuva_link() or drm_gpuva_unlink(), but also
440  * drm_gpuvm_bo_obtain() and drm_gpuvm_bo_put().
441  *
442  * The latter is required since on creation and destruction of a &drm_gpuvm_bo
443  * the &drm_gpuvm_bo is attached / removed from the &drm_gem_objects gpuva list.
444  * Subsequent calls to drm_gpuvm_bo_obtain() for the same &drm_gpuvm and
445  * &drm_gem_object must be able to observe previous creations and destructions
446  * of &drm_gpuvm_bos in order to keep instances unique.
447  *
448  * The &drm_gpuvm's lists for keeping track of external and evicted objects are
449  * protected against concurrent insertion / removal and iteration internally.
450  *
451  * However, drivers still need ensure to protect concurrent calls to functions
452  * iterating those lists, namely drm_gpuvm_prepare_objects() and
453  * drm_gpuvm_validate().
454  *
455  * Alternatively, drivers can set the &DRM_GPUVM_RESV_PROTECTED flag to indicate
456  * that the corresponding &dma_resv locks are held in order to protect the
457  * lists. If &DRM_GPUVM_RESV_PROTECTED is set, internal locking is disabled and
458  * the corresponding lockdep checks are enabled. This is an optimization for
459  * drivers which are capable of taking the corresponding &dma_resv locks and
460  * hence do not require internal locking.
461  */
462 
463 /**
464  * DOC: Examples
465  *
466  * This section gives two examples on how to let the DRM GPUVA Manager generate
467  * &drm_gpuva_op in order to satisfy a given map or unmap request and how to
468  * make use of them.
469  *
470  * The below code is strictly limited to illustrate the generic usage pattern.
471  * To maintain simplicitly, it doesn't make use of any abstractions for common
472  * code, different (asyncronous) stages with fence signalling critical paths,
473  * any other helpers or error handling in terms of freeing memory and dropping
474  * previously taken locks.
475  *
476  * 1) Obtain a list of &drm_gpuva_op to create a new mapping::
477  *
478  *	// Allocates a new &drm_gpuva.
479  *	struct drm_gpuva * driver_gpuva_alloc(void);
480  *
481  *	// Typically drivers would embedd the &drm_gpuvm and &drm_gpuva
482  *	// structure in individual driver structures and lock the dma-resv with
483  *	// drm_exec or similar helpers.
484  *	int driver_mapping_create(struct drm_gpuvm *gpuvm,
485  *				  u64 addr, u64 range,
486  *				  struct drm_gem_object *obj, u64 offset)
487  *	{
488  *		struct drm_gpuva_ops *ops;
489  *		struct drm_gpuva_op *op
490  *		struct drm_gpuvm_bo *vm_bo;
491  *
492  *		driver_lock_va_space();
493  *		ops = drm_gpuvm_sm_map_ops_create(gpuvm, addr, range,
494  *						  obj, offset);
495  *		if (IS_ERR(ops))
496  *			return PTR_ERR(ops);
497  *
498  *		vm_bo = drm_gpuvm_bo_obtain(gpuvm, obj);
499  *		if (IS_ERR(vm_bo))
500  *			return PTR_ERR(vm_bo);
501  *
502  *		drm_gpuva_for_each_op(op, ops) {
503  *			struct drm_gpuva *va;
504  *
505  *			switch (op->op) {
506  *			case DRM_GPUVA_OP_MAP:
507  *				va = driver_gpuva_alloc();
508  *				if (!va)
509  *					; // unwind previous VA space updates,
510  *					  // free memory and unlock
511  *
512  *				driver_vm_map();
513  *				drm_gpuva_map(gpuvm, va, &op->map);
514  *				drm_gpuva_link(va, vm_bo);
515  *
516  *				break;
517  *			case DRM_GPUVA_OP_REMAP: {
518  *				struct drm_gpuva *prev = NULL, *next = NULL;
519  *
520  *				va = op->remap.unmap->va;
521  *
522  *				if (op->remap.prev) {
523  *					prev = driver_gpuva_alloc();
524  *					if (!prev)
525  *						; // unwind previous VA space
526  *						  // updates, free memory and
527  *						  // unlock
528  *				}
529  *
530  *				if (op->remap.next) {
531  *					next = driver_gpuva_alloc();
532  *					if (!next)
533  *						; // unwind previous VA space
534  *						  // updates, free memory and
535  *						  // unlock
536  *				}
537  *
538  *				driver_vm_remap();
539  *				drm_gpuva_remap(prev, next, &op->remap);
540  *
541  *				if (prev)
542  *					drm_gpuva_link(prev, va->vm_bo);
543  *				if (next)
544  *					drm_gpuva_link(next, va->vm_bo);
545  *				drm_gpuva_unlink(va);
546  *
547  *				break;
548  *			}
549  *			case DRM_GPUVA_OP_UNMAP:
550  *				va = op->unmap->va;
551  *
552  *				driver_vm_unmap();
553  *				drm_gpuva_unlink(va);
554  *				drm_gpuva_unmap(&op->unmap);
555  *
556  *				break;
557  *			default:
558  *				break;
559  *			}
560  *		}
561  *		drm_gpuvm_bo_put(vm_bo);
562  *		driver_unlock_va_space();
563  *
564  *		return 0;
565  *	}
566  *
567  * 2) Receive a callback for each &drm_gpuva_op to create a new mapping::
568  *
569  *	struct driver_context {
570  *		struct drm_gpuvm *gpuvm;
571  *		struct drm_gpuvm_bo *vm_bo;
572  *		struct drm_gpuva *new_va;
573  *		struct drm_gpuva *prev_va;
574  *		struct drm_gpuva *next_va;
575  *	};
576  *
577  *	// ops to pass to drm_gpuvm_init()
578  *	static const struct drm_gpuvm_ops driver_gpuvm_ops = {
579  *		.sm_step_map = driver_gpuva_map,
580  *		.sm_step_remap = driver_gpuva_remap,
581  *		.sm_step_unmap = driver_gpuva_unmap,
582  *	};
583  *
584  *	// Typically drivers would embedd the &drm_gpuvm and &drm_gpuva
585  *	// structure in individual driver structures and lock the dma-resv with
586  *	// drm_exec or similar helpers.
587  *	int driver_mapping_create(struct drm_gpuvm *gpuvm,
588  *				  u64 addr, u64 range,
589  *				  struct drm_gem_object *obj, u64 offset)
590  *	{
591  *		struct driver_context ctx;
592  *		struct drm_gpuvm_bo *vm_bo;
593  *		struct drm_gpuva_ops *ops;
594  *		struct drm_gpuva_op *op;
595  *		int ret = 0;
596  *
597  *		ctx.gpuvm = gpuvm;
598  *
599  *		ctx.new_va = kzalloc(sizeof(*ctx.new_va), GFP_KERNEL);
600  *		ctx.prev_va = kzalloc(sizeof(*ctx.prev_va), GFP_KERNEL);
601  *		ctx.next_va = kzalloc(sizeof(*ctx.next_va), GFP_KERNEL);
602  *		ctx.vm_bo = drm_gpuvm_bo_create(gpuvm, obj);
603  *		if (!ctx.new_va || !ctx.prev_va || !ctx.next_va || !vm_bo) {
604  *			ret = -ENOMEM;
605  *			goto out;
606  *		}
607  *
608  *		// Typically protected with a driver specific GEM gpuva lock
609  *		// used in the fence signaling path for drm_gpuva_link() and
610  *		// drm_gpuva_unlink(), hence pre-allocate.
611  *		ctx.vm_bo = drm_gpuvm_bo_obtain_prealloc(ctx.vm_bo);
612  *
613  *		driver_lock_va_space();
614  *		ret = drm_gpuvm_sm_map(gpuvm, &ctx, addr, range, obj, offset);
615  *		driver_unlock_va_space();
616  *
617  *	out:
618  *		drm_gpuvm_bo_put(ctx.vm_bo);
619  *		kfree(ctx.new_va);
620  *		kfree(ctx.prev_va);
621  *		kfree(ctx.next_va);
622  *		return ret;
623  *	}
624  *
625  *	int driver_gpuva_map(struct drm_gpuva_op *op, void *__ctx)
626  *	{
627  *		struct driver_context *ctx = __ctx;
628  *
629  *		drm_gpuva_map(ctx->vm, ctx->new_va, &op->map);
630  *
631  *		drm_gpuva_link(ctx->new_va, ctx->vm_bo);
632  *
633  *		// prevent the new GPUVA from being freed in
634  *		// driver_mapping_create()
635  *		ctx->new_va = NULL;
636  *
637  *		return 0;
638  *	}
639  *
640  *	int driver_gpuva_remap(struct drm_gpuva_op *op, void *__ctx)
641  *	{
642  *		struct driver_context *ctx = __ctx;
643  *		struct drm_gpuva *va = op->remap.unmap->va;
644  *
645  *		drm_gpuva_remap(ctx->prev_va, ctx->next_va, &op->remap);
646  *
647  *		if (op->remap.prev) {
648  *			drm_gpuva_link(ctx->prev_va, va->vm_bo);
649  *			ctx->prev_va = NULL;
650  *		}
651  *
652  *		if (op->remap.next) {
653  *			drm_gpuva_link(ctx->next_va, va->vm_bo);
654  *			ctx->next_va = NULL;
655  *		}
656  *
657  *		drm_gpuva_unlink(va);
658  *		kfree(va);
659  *
660  *		return 0;
661  *	}
662  *
663  *	int driver_gpuva_unmap(struct drm_gpuva_op *op, void *__ctx)
664  *	{
665  *		drm_gpuva_unlink(op->unmap.va);
666  *		drm_gpuva_unmap(&op->unmap);
667  *		kfree(op->unmap.va);
668  *
669  *		return 0;
670  *	}
671  */
672 
673 /**
674  * get_next_vm_bo_from_list() - get the next vm_bo element
675  * @__gpuvm: the &drm_gpuvm
676  * @__list_name: the name of the list we're iterating on
677  * @__local_list: a pointer to the local list used to store already iterated items
678  * @__prev_vm_bo: the previous element we got from get_next_vm_bo_from_list()
679  *
680  * This helper is here to provide lockless list iteration. Lockless as in, the
681  * iterator releases the lock immediately after picking the first element from
682  * the list, so list insertion deletion can happen concurrently.
683  *
684  * Elements popped from the original list are kept in a local list, so removal
685  * and is_empty checks can still happen while we're iterating the list.
686  */
687 #define get_next_vm_bo_from_list(__gpuvm, __list_name, __local_list, __prev_vm_bo)	\
688 	({										\
689 		struct drm_gpuvm_bo *__vm_bo = NULL;					\
690 											\
691 		drm_gpuvm_bo_put(__prev_vm_bo);						\
692 											\
693 		spin_lock(&(__gpuvm)->__list_name.lock);				\
694 		if (!(__gpuvm)->__list_name.local_list)					\
695 			(__gpuvm)->__list_name.local_list = __local_list;		\
696 		else									\
697 			drm_WARN_ON((__gpuvm)->drm,					\
698 				    (__gpuvm)->__list_name.local_list != __local_list);	\
699 											\
700 		while (!list_empty(&(__gpuvm)->__list_name.list)) {			\
701 			__vm_bo = list_first_entry(&(__gpuvm)->__list_name.list,	\
702 						   struct drm_gpuvm_bo,			\
703 						   list.entry.__list_name);		\
704 			if (kref_get_unless_zero(&__vm_bo->kref)) {			\
705 				list_move_tail(&(__vm_bo)->list.entry.__list_name,	\
706 					       __local_list);				\
707 				break;							\
708 			} else {							\
709 				list_del_init(&(__vm_bo)->list.entry.__list_name);	\
710 				__vm_bo = NULL;						\
711 			}								\
712 		}									\
713 		spin_unlock(&(__gpuvm)->__list_name.lock);				\
714 											\
715 		__vm_bo;								\
716 	})
717 
718 /**
719  * for_each_vm_bo_in_list() - internal vm_bo list iterator
720  * @__gpuvm: the &drm_gpuvm
721  * @__list_name: the name of the list we're iterating on
722  * @__local_list: a pointer to the local list used to store already iterated items
723  * @__vm_bo: the struct drm_gpuvm_bo to assign in each iteration step
724  *
725  * This helper is here to provide lockless list iteration. Lockless as in, the
726  * iterator releases the lock immediately after picking the first element from the
727  * list, hence list insertion and deletion can happen concurrently.
728  *
729  * It is not allowed to re-assign the vm_bo pointer from inside this loop.
730  *
731  * Typical use:
732  *
733  *	struct drm_gpuvm_bo *vm_bo;
734  *	LIST_HEAD(my_local_list);
735  *
736  *	ret = 0;
737  *	for_each_vm_bo_in_list(gpuvm, <list_name>, &my_local_list, vm_bo) {
738  *		ret = do_something_with_vm_bo(..., vm_bo);
739  *		if (ret)
740  *			break;
741  *	}
742  *	// Drop ref in case we break out of the loop.
743  *	drm_gpuvm_bo_put(vm_bo);
744  *	restore_vm_bo_list(gpuvm, <list_name>, &my_local_list);
745  *
746  *
747  * Only used for internal list iterations, not meant to be exposed to the outside
748  * world.
749  */
750 #define for_each_vm_bo_in_list(__gpuvm, __list_name, __local_list, __vm_bo)	\
751 	for (__vm_bo = get_next_vm_bo_from_list(__gpuvm, __list_name,		\
752 						__local_list, NULL);		\
753 	     __vm_bo;								\
754 	     __vm_bo = get_next_vm_bo_from_list(__gpuvm, __list_name,		\
755 						__local_list, __vm_bo))
756 
757 static void
758 __restore_vm_bo_list(struct drm_gpuvm *gpuvm, spinlock_t *lock,
759 		     struct list_head *list, struct list_head **local_list)
760 {
761 	/* Merge back the two lists, moving local list elements to the
762 	 * head to preserve previous ordering, in case it matters.
763 	 */
764 	spin_lock(lock);
765 	if (*local_list) {
766 		list_splice(*local_list, list);
767 		*local_list = NULL;
768 	}
769 	spin_unlock(lock);
770 }
771 
772 /**
773  * restore_vm_bo_list() - move vm_bo elements back to their original list
774  * @__gpuvm: the &drm_gpuvm
775  * @__list_name: the name of the list we're iterating on
776  *
777  * When we're done iterating a vm_bo list, we should call restore_vm_bo_list()
778  * to restore the original state and let new iterations take place.
779  */
780 #define restore_vm_bo_list(__gpuvm, __list_name)			\
781 	__restore_vm_bo_list((__gpuvm), &(__gpuvm)->__list_name.lock,	\
782 			     &(__gpuvm)->__list_name.list,		\
783 			     &(__gpuvm)->__list_name.local_list)
784 
785 static void
786 cond_spin_lock(spinlock_t *lock, bool cond)
787 {
788 	if (cond)
789 		spin_lock(lock);
790 }
791 
792 static void
793 cond_spin_unlock(spinlock_t *lock, bool cond)
794 {
795 	if (cond)
796 		spin_unlock(lock);
797 }
798 
799 static void
800 __drm_gpuvm_bo_list_add(struct drm_gpuvm *gpuvm, spinlock_t *lock,
801 			struct list_head *entry, struct list_head *list)
802 {
803 	cond_spin_lock(lock, !!lock);
804 	if (list_empty(entry))
805 		list_add_tail(entry, list);
806 	cond_spin_unlock(lock, !!lock);
807 }
808 
809 /**
810  * drm_gpuvm_bo_list_add() - insert a vm_bo into the given list
811  * @__vm_bo: the &drm_gpuvm_bo
812  * @__list_name: the name of the list to insert into
813  * @__lock: whether to lock with the internal spinlock
814  *
815  * Inserts the given @__vm_bo into the list specified by @__list_name.
816  */
817 #define drm_gpuvm_bo_list_add(__vm_bo, __list_name, __lock)			\
818 	__drm_gpuvm_bo_list_add((__vm_bo)->vm,					\
819 				__lock ? &(__vm_bo)->vm->__list_name.lock :	\
820 					 NULL,					\
821 				&(__vm_bo)->list.entry.__list_name,		\
822 				&(__vm_bo)->vm->__list_name.list)
823 
824 static void
825 __drm_gpuvm_bo_list_del(struct drm_gpuvm *gpuvm, spinlock_t *lock,
826 			struct list_head *entry, bool init)
827 {
828 	cond_spin_lock(lock, !!lock);
829 	if (init) {
830 		if (!list_empty(entry))
831 			list_del_init(entry);
832 	} else {
833 		list_del(entry);
834 	}
835 	cond_spin_unlock(lock, !!lock);
836 }
837 
838 /**
839  * drm_gpuvm_bo_list_del_init() - remove a vm_bo from the given list
840  * @__vm_bo: the &drm_gpuvm_bo
841  * @__list_name: the name of the list to insert into
842  * @__lock: whether to lock with the internal spinlock
843  *
844  * Removes the given @__vm_bo from the list specified by @__list_name.
845  */
846 #define drm_gpuvm_bo_list_del_init(__vm_bo, __list_name, __lock)		\
847 	__drm_gpuvm_bo_list_del((__vm_bo)->vm,					\
848 				__lock ? &(__vm_bo)->vm->__list_name.lock :	\
849 					 NULL,					\
850 				&(__vm_bo)->list.entry.__list_name,		\
851 				true)
852 
853 /**
854  * drm_gpuvm_bo_list_del() - remove a vm_bo from the given list
855  * @__vm_bo: the &drm_gpuvm_bo
856  * @__list_name: the name of the list to insert into
857  * @__lock: whether to lock with the internal spinlock
858  *
859  * Removes the given @__vm_bo from the list specified by @__list_name.
860  */
861 #define drm_gpuvm_bo_list_del(__vm_bo, __list_name, __lock)			\
862 	__drm_gpuvm_bo_list_del((__vm_bo)->vm,					\
863 				__lock ? &(__vm_bo)->vm->__list_name.lock :	\
864 					 NULL,					\
865 				&(__vm_bo)->list.entry.__list_name,		\
866 				false)
867 
868 #define to_drm_gpuva(__node)	container_of((__node), struct drm_gpuva, rb.node)
869 
870 #define GPUVA_START(node) ((node)->va.addr)
871 #define GPUVA_LAST(node) ((node)->va.addr + (node)->va.range - 1)
872 
873 /* We do not actually use drm_gpuva_it_next(), tell the compiler to not complain
874  * about this.
875  */
876 INTERVAL_TREE_DEFINE(struct drm_gpuva, rb.node, u64, rb.__subtree_last,
877 		     GPUVA_START, GPUVA_LAST, static __maybe_unused,
878 		     drm_gpuva_it)
879 
880 static int __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
881 			      struct drm_gpuva *va);
882 static void __drm_gpuva_remove(struct drm_gpuva *va);
883 
884 static bool
885 drm_gpuvm_check_overflow(u64 addr, u64 range)
886 {
887 	u64 end;
888 
889 	return check_add_overflow(addr, range, &end);
890 }
891 
892 static bool
893 drm_gpuvm_warn_check_overflow(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
894 {
895 	return drm_WARN(gpuvm->drm, drm_gpuvm_check_overflow(addr, range),
896 			"GPUVA address limited to %zu bytes.\n", sizeof(addr));
897 }
898 
899 static bool
900 drm_gpuvm_in_mm_range(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
901 {
902 	u64 end = addr + range;
903 	u64 mm_start = gpuvm->mm_start;
904 	u64 mm_end = mm_start + gpuvm->mm_range;
905 
906 	return addr >= mm_start && end <= mm_end;
907 }
908 
909 static bool
910 drm_gpuvm_in_kernel_node(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
911 {
912 	u64 end = addr + range;
913 	u64 kstart = gpuvm->kernel_alloc_node.va.addr;
914 	u64 krange = gpuvm->kernel_alloc_node.va.range;
915 	u64 kend = kstart + krange;
916 
917 	return krange && addr < kend && kstart < end;
918 }
919 
920 /**
921  * drm_gpuvm_range_valid() - checks whether the given range is valid for the
922  * given &drm_gpuvm
923  * @gpuvm: the GPUVM to check the range for
924  * @addr: the base address
925  * @range: the range starting from the base address
926  *
927  * Checks whether the range is within the GPUVM's managed boundaries.
928  *
929  * Returns: true for a valid range, false otherwise
930  */
931 bool
932 drm_gpuvm_range_valid(struct drm_gpuvm *gpuvm,
933 		      u64 addr, u64 range)
934 {
935 	return !drm_gpuvm_check_overflow(addr, range) &&
936 	       drm_gpuvm_in_mm_range(gpuvm, addr, range) &&
937 	       !drm_gpuvm_in_kernel_node(gpuvm, addr, range);
938 }
939 EXPORT_SYMBOL_GPL(drm_gpuvm_range_valid);
940 
941 static void
942 drm_gpuvm_gem_object_free(struct drm_gem_object *obj)
943 {
944 	drm_gem_object_release(obj);
945 	kfree(obj);
946 }
947 
948 static const struct drm_gem_object_funcs drm_gpuvm_object_funcs = {
949 	.free = drm_gpuvm_gem_object_free,
950 };
951 
952 /**
953  * drm_gpuvm_resv_object_alloc() - allocate a dummy &drm_gem_object
954  * @drm: the drivers &drm_device
955  *
956  * Allocates a dummy &drm_gem_object which can be passed to drm_gpuvm_init() in
957  * order to serve as root GEM object providing the &drm_resv shared across
958  * &drm_gem_objects local to a single GPUVM.
959  *
960  * Returns: the &drm_gem_object on success, NULL on failure
961  */
962 struct drm_gem_object *
963 drm_gpuvm_resv_object_alloc(struct drm_device *drm)
964 {
965 	struct drm_gem_object *obj;
966 
967 	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
968 	if (!obj)
969 		return NULL;
970 
971 	obj->funcs = &drm_gpuvm_object_funcs;
972 	drm_gem_private_object_init(drm, obj, 0);
973 
974 	return obj;
975 }
976 EXPORT_SYMBOL_GPL(drm_gpuvm_resv_object_alloc);
977 
978 /**
979  * drm_gpuvm_init() - initialize a &drm_gpuvm
980  * @gpuvm: pointer to the &drm_gpuvm to initialize
981  * @name: the name of the GPU VA space
982  * @flags: the &drm_gpuvm_flags for this GPUVM
983  * @drm: the &drm_device this VM resides in
984  * @r_obj: the resv &drm_gem_object providing the GPUVM's common &dma_resv
985  * @start_offset: the start offset of the GPU VA space
986  * @range: the size of the GPU VA space
987  * @reserve_offset: the start of the kernel reserved GPU VA area
988  * @reserve_range: the size of the kernel reserved GPU VA area
989  * @ops: &drm_gpuvm_ops called on &drm_gpuvm_sm_map / &drm_gpuvm_sm_unmap
990  *
991  * The &drm_gpuvm must be initialized with this function before use.
992  *
993  * Note that @gpuvm must be cleared to 0 before calling this function. The given
994  * &name is expected to be managed by the surrounding driver structures.
995  */
996 void
997 drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name,
998 	       enum drm_gpuvm_flags flags,
999 	       struct drm_device *drm,
1000 	       struct drm_gem_object *r_obj,
1001 	       u64 start_offset, u64 range,
1002 	       u64 reserve_offset, u64 reserve_range,
1003 	       const struct drm_gpuvm_ops *ops)
1004 {
1005 	gpuvm->rb.tree = RB_ROOT_CACHED;
1006 	INIT_LIST_HEAD(&gpuvm->rb.list);
1007 
1008 	INIT_LIST_HEAD(&gpuvm->extobj.list);
1009 	spin_lock_init(&gpuvm->extobj.lock);
1010 
1011 	INIT_LIST_HEAD(&gpuvm->evict.list);
1012 	spin_lock_init(&gpuvm->evict.lock);
1013 
1014 	kref_init(&gpuvm->kref);
1015 
1016 	gpuvm->name = name ? name : "unknown";
1017 	gpuvm->flags = flags;
1018 	gpuvm->ops = ops;
1019 	gpuvm->drm = drm;
1020 	gpuvm->r_obj = r_obj;
1021 
1022 	drm_gem_object_get(r_obj);
1023 
1024 	drm_gpuvm_warn_check_overflow(gpuvm, start_offset, range);
1025 	gpuvm->mm_start = start_offset;
1026 	gpuvm->mm_range = range;
1027 
1028 	memset(&gpuvm->kernel_alloc_node, 0, sizeof(struct drm_gpuva));
1029 	if (reserve_range) {
1030 		gpuvm->kernel_alloc_node.va.addr = reserve_offset;
1031 		gpuvm->kernel_alloc_node.va.range = reserve_range;
1032 
1033 		if (likely(!drm_gpuvm_warn_check_overflow(gpuvm, reserve_offset,
1034 							  reserve_range)))
1035 			__drm_gpuva_insert(gpuvm, &gpuvm->kernel_alloc_node);
1036 	}
1037 }
1038 EXPORT_SYMBOL_GPL(drm_gpuvm_init);
1039 
1040 static void
1041 drm_gpuvm_fini(struct drm_gpuvm *gpuvm)
1042 {
1043 	gpuvm->name = NULL;
1044 
1045 	if (gpuvm->kernel_alloc_node.va.range)
1046 		__drm_gpuva_remove(&gpuvm->kernel_alloc_node);
1047 
1048 	drm_WARN(gpuvm->drm, !RB_EMPTY_ROOT(&gpuvm->rb.tree.rb_root),
1049 		 "GPUVA tree is not empty, potentially leaking memory.\n");
1050 
1051 	drm_WARN(gpuvm->drm, !list_empty(&gpuvm->extobj.list),
1052 		 "Extobj list should be empty.\n");
1053 	drm_WARN(gpuvm->drm, !list_empty(&gpuvm->evict.list),
1054 		 "Evict list should be empty.\n");
1055 
1056 	drm_gem_object_put(gpuvm->r_obj);
1057 }
1058 
1059 static void
1060 drm_gpuvm_free(struct kref *kref)
1061 {
1062 	struct drm_gpuvm *gpuvm = container_of(kref, struct drm_gpuvm, kref);
1063 
1064 	drm_gpuvm_fini(gpuvm);
1065 
1066 	if (drm_WARN_ON(gpuvm->drm, !gpuvm->ops->vm_free))
1067 		return;
1068 
1069 	gpuvm->ops->vm_free(gpuvm);
1070 }
1071 
1072 /**
1073  * drm_gpuvm_put() - drop a struct drm_gpuvm reference
1074  * @gpuvm: the &drm_gpuvm to release the reference of
1075  *
1076  * This releases a reference to @gpuvm.
1077  *
1078  * This function may be called from atomic context.
1079  */
1080 void
1081 drm_gpuvm_put(struct drm_gpuvm *gpuvm)
1082 {
1083 	if (gpuvm)
1084 		kref_put(&gpuvm->kref, drm_gpuvm_free);
1085 }
1086 EXPORT_SYMBOL_GPL(drm_gpuvm_put);
1087 
1088 static int
1089 __drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
1090 			    struct drm_exec *exec,
1091 			    unsigned int num_fences)
1092 {
1093 	struct drm_gpuvm_bo *vm_bo;
1094 	LIST_HEAD(extobjs);
1095 	int ret = 0;
1096 
1097 	for_each_vm_bo_in_list(gpuvm, extobj, &extobjs, vm_bo) {
1098 		ret = drm_exec_prepare_obj(exec, vm_bo->obj, num_fences);
1099 		if (ret)
1100 			break;
1101 	}
1102 	/* Drop ref in case we break out of the loop. */
1103 	drm_gpuvm_bo_put(vm_bo);
1104 	restore_vm_bo_list(gpuvm, extobj);
1105 
1106 	return ret;
1107 }
1108 
1109 static int
1110 drm_gpuvm_prepare_objects_locked(struct drm_gpuvm *gpuvm,
1111 				 struct drm_exec *exec,
1112 				 unsigned int num_fences)
1113 {
1114 	struct drm_gpuvm_bo *vm_bo;
1115 	int ret = 0;
1116 
1117 	drm_gpuvm_resv_assert_held(gpuvm);
1118 	list_for_each_entry(vm_bo, &gpuvm->extobj.list, list.entry.extobj) {
1119 		ret = drm_exec_prepare_obj(exec, vm_bo->obj, num_fences);
1120 		if (ret)
1121 			break;
1122 
1123 		if (vm_bo->evicted)
1124 			drm_gpuvm_bo_list_add(vm_bo, evict, false);
1125 	}
1126 
1127 	return ret;
1128 }
1129 
1130 /**
1131  * drm_gpuvm_prepare_objects() - prepare all assoiciated BOs
1132  * @gpuvm: the &drm_gpuvm
1133  * @exec: the &drm_exec locking context
1134  * @num_fences: the amount of &dma_fences to reserve
1135  *
1136  * Calls drm_exec_prepare_obj() for all &drm_gem_objects the given
1137  * &drm_gpuvm contains mappings of.
1138  *
1139  * Using this function directly, it is the drivers responsibility to call
1140  * drm_exec_init() and drm_exec_fini() accordingly.
1141  *
1142  * Note: This function is safe against concurrent insertion and removal of
1143  * external objects, however it is not safe against concurrent usage itself.
1144  *
1145  * Drivers need to make sure to protect this case with either an outer VM lock
1146  * or by calling drm_gpuvm_prepare_vm() before this function within the
1147  * drm_exec_until_all_locked() loop, such that the GPUVM's dma-resv lock ensures
1148  * mutual exclusion.
1149  *
1150  * Returns: 0 on success, negative error code on failure.
1151  */
1152 int
1153 drm_gpuvm_prepare_objects(struct drm_gpuvm *gpuvm,
1154 			  struct drm_exec *exec,
1155 			  unsigned int num_fences)
1156 {
1157 	if (drm_gpuvm_resv_protected(gpuvm))
1158 		return drm_gpuvm_prepare_objects_locked(gpuvm, exec,
1159 							num_fences);
1160 	else
1161 		return __drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
1162 }
1163 EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_objects);
1164 
1165 /**
1166  * drm_gpuvm_prepare_range() - prepare all BOs mapped within a given range
1167  * @gpuvm: the &drm_gpuvm
1168  * @exec: the &drm_exec locking context
1169  * @addr: the start address within the VA space
1170  * @range: the range to iterate within the VA space
1171  * @num_fences: the amount of &dma_fences to reserve
1172  *
1173  * Calls drm_exec_prepare_obj() for all &drm_gem_objects mapped between @addr
1174  * and @addr + @range.
1175  *
1176  * Returns: 0 on success, negative error code on failure.
1177  */
1178 int
1179 drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm, struct drm_exec *exec,
1180 			u64 addr, u64 range, unsigned int num_fences)
1181 {
1182 	struct drm_gpuva *va;
1183 	u64 end = addr + range;
1184 	int ret;
1185 
1186 	drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) {
1187 		struct drm_gem_object *obj = va->gem.obj;
1188 
1189 		ret = drm_exec_prepare_obj(exec, obj, num_fences);
1190 		if (ret)
1191 			return ret;
1192 	}
1193 
1194 	return 0;
1195 }
1196 EXPORT_SYMBOL_GPL(drm_gpuvm_prepare_range);
1197 
1198 /**
1199  * drm_gpuvm_exec_lock() - lock all dma-resv of all assoiciated BOs
1200  * @vm_exec: the &drm_gpuvm_exec wrapper
1201  *
1202  * Acquires all dma-resv locks of all &drm_gem_objects the given
1203  * &drm_gpuvm contains mappings of.
1204  *
1205  * Addionally, when calling this function with struct drm_gpuvm_exec::extra
1206  * being set the driver receives the given @fn callback to lock additional
1207  * dma-resv in the context of the &drm_gpuvm_exec instance. Typically, drivers
1208  * would call drm_exec_prepare_obj() from within this callback.
1209  *
1210  * Returns: 0 on success, negative error code on failure.
1211  */
1212 int
1213 drm_gpuvm_exec_lock(struct drm_gpuvm_exec *vm_exec)
1214 {
1215 	struct drm_gpuvm *gpuvm = vm_exec->vm;
1216 	struct drm_exec *exec = &vm_exec->exec;
1217 	unsigned int num_fences = vm_exec->num_fences;
1218 	int ret;
1219 
1220 	drm_exec_init(exec, vm_exec->flags);
1221 
1222 	drm_exec_until_all_locked(exec) {
1223 		ret = drm_gpuvm_prepare_vm(gpuvm, exec, num_fences);
1224 		drm_exec_retry_on_contention(exec);
1225 		if (ret)
1226 			goto err;
1227 
1228 		ret = drm_gpuvm_prepare_objects(gpuvm, exec, num_fences);
1229 		drm_exec_retry_on_contention(exec);
1230 		if (ret)
1231 			goto err;
1232 
1233 		if (vm_exec->extra.fn) {
1234 			ret = vm_exec->extra.fn(vm_exec);
1235 			drm_exec_retry_on_contention(exec);
1236 			if (ret)
1237 				goto err;
1238 		}
1239 	}
1240 
1241 	return 0;
1242 
1243 err:
1244 	drm_exec_fini(exec);
1245 	return ret;
1246 }
1247 EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock);
1248 
1249 static int
1250 fn_lock_array(struct drm_gpuvm_exec *vm_exec)
1251 {
1252 	struct {
1253 		struct drm_gem_object **objs;
1254 		unsigned int num_objs;
1255 	} *args = vm_exec->extra.priv;
1256 
1257 	return drm_exec_prepare_array(&vm_exec->exec, args->objs,
1258 				      args->num_objs, vm_exec->num_fences);
1259 }
1260 
1261 /**
1262  * drm_gpuvm_exec_lock_array() - lock all dma-resv of all assoiciated BOs
1263  * @vm_exec: the &drm_gpuvm_exec wrapper
1264  * @objs: additional &drm_gem_objects to lock
1265  * @num_objs: the number of additional &drm_gem_objects to lock
1266  *
1267  * Acquires all dma-resv locks of all &drm_gem_objects the given &drm_gpuvm
1268  * contains mappings of, plus the ones given through @objs.
1269  *
1270  * Returns: 0 on success, negative error code on failure.
1271  */
1272 int
1273 drm_gpuvm_exec_lock_array(struct drm_gpuvm_exec *vm_exec,
1274 			  struct drm_gem_object **objs,
1275 			  unsigned int num_objs)
1276 {
1277 	struct {
1278 		struct drm_gem_object **objs;
1279 		unsigned int num_objs;
1280 	} args;
1281 
1282 	args.objs = objs;
1283 	args.num_objs = num_objs;
1284 
1285 	vm_exec->extra.fn = fn_lock_array;
1286 	vm_exec->extra.priv = &args;
1287 
1288 	return drm_gpuvm_exec_lock(vm_exec);
1289 }
1290 EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_array);
1291 
1292 /**
1293  * drm_gpuvm_exec_lock_range() - prepare all BOs mapped within a given range
1294  * @vm_exec: the &drm_gpuvm_exec wrapper
1295  * @addr: the start address within the VA space
1296  * @range: the range to iterate within the VA space
1297  *
1298  * Acquires all dma-resv locks of all &drm_gem_objects mapped between @addr and
1299  * @addr + @range.
1300  *
1301  * Returns: 0 on success, negative error code on failure.
1302  */
1303 int
1304 drm_gpuvm_exec_lock_range(struct drm_gpuvm_exec *vm_exec,
1305 			  u64 addr, u64 range)
1306 {
1307 	struct drm_gpuvm *gpuvm = vm_exec->vm;
1308 	struct drm_exec *exec = &vm_exec->exec;
1309 	int ret;
1310 
1311 	drm_exec_init(exec, vm_exec->flags);
1312 
1313 	drm_exec_until_all_locked(exec) {
1314 		ret = drm_gpuvm_prepare_range(gpuvm, exec, addr, range,
1315 					      vm_exec->num_fences);
1316 		drm_exec_retry_on_contention(exec);
1317 		if (ret)
1318 			goto err;
1319 	}
1320 
1321 	return ret;
1322 
1323 err:
1324 	drm_exec_fini(exec);
1325 	return ret;
1326 }
1327 EXPORT_SYMBOL_GPL(drm_gpuvm_exec_lock_range);
1328 
1329 static int
1330 __drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1331 {
1332 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
1333 	struct drm_gpuvm_bo *vm_bo;
1334 	LIST_HEAD(evict);
1335 	int ret = 0;
1336 
1337 	for_each_vm_bo_in_list(gpuvm, evict, &evict, vm_bo) {
1338 		ret = ops->vm_bo_validate(vm_bo, exec);
1339 		if (ret)
1340 			break;
1341 	}
1342 	/* Drop ref in case we break out of the loop. */
1343 	drm_gpuvm_bo_put(vm_bo);
1344 	restore_vm_bo_list(gpuvm, evict);
1345 
1346 	return ret;
1347 }
1348 
1349 static int
1350 drm_gpuvm_validate_locked(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1351 {
1352 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
1353 	struct drm_gpuvm_bo *vm_bo, *next;
1354 	int ret = 0;
1355 
1356 	drm_gpuvm_resv_assert_held(gpuvm);
1357 
1358 	list_for_each_entry_safe(vm_bo, next, &gpuvm->evict.list,
1359 				 list.entry.evict) {
1360 		ret = ops->vm_bo_validate(vm_bo, exec);
1361 		if (ret)
1362 			break;
1363 
1364 		dma_resv_assert_held(vm_bo->obj->resv);
1365 		if (!vm_bo->evicted)
1366 			drm_gpuvm_bo_list_del_init(vm_bo, evict, false);
1367 	}
1368 
1369 	return ret;
1370 }
1371 
1372 /**
1373  * drm_gpuvm_validate() - validate all BOs marked as evicted
1374  * @gpuvm: the &drm_gpuvm to validate evicted BOs
1375  * @exec: the &drm_exec instance used for locking the GPUVM
1376  *
1377  * Calls the &drm_gpuvm_ops::vm_bo_validate callback for all evicted buffer
1378  * objects being mapped in the given &drm_gpuvm.
1379  *
1380  * Returns: 0 on success, negative error code on failure.
1381  */
1382 int
1383 drm_gpuvm_validate(struct drm_gpuvm *gpuvm, struct drm_exec *exec)
1384 {
1385 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
1386 
1387 	if (unlikely(!ops || !ops->vm_bo_validate))
1388 		return -EOPNOTSUPP;
1389 
1390 	if (drm_gpuvm_resv_protected(gpuvm))
1391 		return drm_gpuvm_validate_locked(gpuvm, exec);
1392 	else
1393 		return __drm_gpuvm_validate(gpuvm, exec);
1394 }
1395 EXPORT_SYMBOL_GPL(drm_gpuvm_validate);
1396 
1397 /**
1398  * drm_gpuvm_resv_add_fence - add fence to private and all extobj
1399  * dma-resv
1400  * @gpuvm: the &drm_gpuvm to add a fence to
1401  * @exec: the &drm_exec locking context
1402  * @fence: fence to add
1403  * @private_usage: private dma-resv usage
1404  * @extobj_usage: extobj dma-resv usage
1405  */
1406 void
1407 drm_gpuvm_resv_add_fence(struct drm_gpuvm *gpuvm,
1408 			 struct drm_exec *exec,
1409 			 struct dma_fence *fence,
1410 			 enum dma_resv_usage private_usage,
1411 			 enum dma_resv_usage extobj_usage)
1412 {
1413 	struct drm_gem_object *obj;
1414 	unsigned long index;
1415 
1416 	drm_exec_for_each_locked_object(exec, index, obj) {
1417 		dma_resv_assert_held(obj->resv);
1418 		dma_resv_add_fence(obj->resv, fence,
1419 				   drm_gpuvm_is_extobj(gpuvm, obj) ?
1420 				   extobj_usage : private_usage);
1421 	}
1422 }
1423 EXPORT_SYMBOL_GPL(drm_gpuvm_resv_add_fence);
1424 
1425 /**
1426  * drm_gpuvm_bo_create() - create a new instance of struct drm_gpuvm_bo
1427  * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1428  * @obj: The &drm_gem_object being mapped in the @gpuvm.
1429  *
1430  * If provided by the driver, this function uses the &drm_gpuvm_ops
1431  * vm_bo_alloc() callback to allocate.
1432  *
1433  * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure
1434  */
1435 struct drm_gpuvm_bo *
1436 drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm,
1437 		    struct drm_gem_object *obj)
1438 {
1439 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
1440 	struct drm_gpuvm_bo *vm_bo;
1441 
1442 	if (ops && ops->vm_bo_alloc)
1443 		vm_bo = ops->vm_bo_alloc();
1444 	else
1445 		vm_bo = kzalloc(sizeof(*vm_bo), GFP_KERNEL);
1446 
1447 	if (unlikely(!vm_bo))
1448 		return NULL;
1449 
1450 	vm_bo->vm = drm_gpuvm_get(gpuvm);
1451 	vm_bo->obj = obj;
1452 	drm_gem_object_get(obj);
1453 
1454 	kref_init(&vm_bo->kref);
1455 	INIT_LIST_HEAD(&vm_bo->list.gpuva);
1456 	INIT_LIST_HEAD(&vm_bo->list.entry.gem);
1457 
1458 	INIT_LIST_HEAD(&vm_bo->list.entry.extobj);
1459 	INIT_LIST_HEAD(&vm_bo->list.entry.evict);
1460 
1461 	return vm_bo;
1462 }
1463 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_create);
1464 
1465 static void
1466 drm_gpuvm_bo_destroy(struct kref *kref)
1467 {
1468 	struct drm_gpuvm_bo *vm_bo = container_of(kref, struct drm_gpuvm_bo,
1469 						  kref);
1470 	struct drm_gpuvm *gpuvm = vm_bo->vm;
1471 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
1472 	struct drm_gem_object *obj = vm_bo->obj;
1473 	bool lock = !drm_gpuvm_resv_protected(gpuvm);
1474 
1475 	if (!lock)
1476 		drm_gpuvm_resv_assert_held(gpuvm);
1477 
1478 	drm_gpuvm_bo_list_del(vm_bo, extobj, lock);
1479 	drm_gpuvm_bo_list_del(vm_bo, evict, lock);
1480 
1481 	drm_gem_gpuva_assert_lock_held(obj);
1482 	list_del(&vm_bo->list.entry.gem);
1483 
1484 	if (ops && ops->vm_bo_free)
1485 		ops->vm_bo_free(vm_bo);
1486 	else
1487 		kfree(vm_bo);
1488 
1489 	drm_gpuvm_put(gpuvm);
1490 	drm_gem_object_put(obj);
1491 }
1492 
1493 /**
1494  * drm_gpuvm_bo_put() - drop a struct drm_gpuvm_bo reference
1495  * @vm_bo: the &drm_gpuvm_bo to release the reference of
1496  *
1497  * This releases a reference to @vm_bo.
1498  *
1499  * If the reference count drops to zero, the &gpuvm_bo is destroyed, which
1500  * includes removing it from the GEMs gpuva list. Hence, if a call to this
1501  * function can potentially let the reference count drop to zero the caller must
1502  * hold the dma-resv or driver specific GEM gpuva lock.
1503  *
1504  * This function may only be called from non-atomic context.
1505  */
1506 void
1507 drm_gpuvm_bo_put(struct drm_gpuvm_bo *vm_bo)
1508 {
1509 	might_sleep();
1510 
1511 	if (vm_bo)
1512 		kref_put(&vm_bo->kref, drm_gpuvm_bo_destroy);
1513 }
1514 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_put);
1515 
1516 static struct drm_gpuvm_bo *
1517 __drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
1518 		    struct drm_gem_object *obj)
1519 {
1520 	struct drm_gpuvm_bo *vm_bo;
1521 
1522 	drm_gem_gpuva_assert_lock_held(obj);
1523 	drm_gem_for_each_gpuvm_bo(vm_bo, obj)
1524 		if (vm_bo->vm == gpuvm)
1525 			return vm_bo;
1526 
1527 	return NULL;
1528 }
1529 
1530 /**
1531  * drm_gpuvm_bo_find() - find the &drm_gpuvm_bo for the given
1532  * &drm_gpuvm and &drm_gem_object
1533  * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1534  * @obj: The &drm_gem_object being mapped in the @gpuvm.
1535  *
1536  * Find the &drm_gpuvm_bo representing the combination of the given
1537  * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1538  * count of the &drm_gpuvm_bo accordingly.
1539  *
1540  * Returns: a pointer to the &drm_gpuvm_bo on success, NULL on failure
1541  */
1542 struct drm_gpuvm_bo *
1543 drm_gpuvm_bo_find(struct drm_gpuvm *gpuvm,
1544 		  struct drm_gem_object *obj)
1545 {
1546 	struct drm_gpuvm_bo *vm_bo = __drm_gpuvm_bo_find(gpuvm, obj);
1547 
1548 	return vm_bo ? drm_gpuvm_bo_get(vm_bo) : NULL;
1549 }
1550 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_find);
1551 
1552 /**
1553  * drm_gpuvm_bo_obtain() - obtains and instance of the &drm_gpuvm_bo for the
1554  * given &drm_gpuvm and &drm_gem_object
1555  * @gpuvm: The &drm_gpuvm the @obj is mapped in.
1556  * @obj: The &drm_gem_object being mapped in the @gpuvm.
1557  *
1558  * Find the &drm_gpuvm_bo representing the combination of the given
1559  * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1560  * count of the &drm_gpuvm_bo accordingly. If not found, allocates a new
1561  * &drm_gpuvm_bo.
1562  *
1563  * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
1564  *
1565  * Returns: a pointer to the &drm_gpuvm_bo on success, an ERR_PTR on failure
1566  */
1567 struct drm_gpuvm_bo *
1568 drm_gpuvm_bo_obtain(struct drm_gpuvm *gpuvm,
1569 		    struct drm_gem_object *obj)
1570 {
1571 	struct drm_gpuvm_bo *vm_bo;
1572 
1573 	vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
1574 	if (vm_bo)
1575 		return vm_bo;
1576 
1577 	vm_bo = drm_gpuvm_bo_create(gpuvm, obj);
1578 	if (!vm_bo)
1579 		return ERR_PTR(-ENOMEM);
1580 
1581 	drm_gem_gpuva_assert_lock_held(obj);
1582 	list_add_tail(&vm_bo->list.entry.gem, &obj->gpuva.list);
1583 
1584 	return vm_bo;
1585 }
1586 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain);
1587 
1588 /**
1589  * drm_gpuvm_bo_obtain_prealloc() - obtains and instance of the &drm_gpuvm_bo
1590  * for the given &drm_gpuvm and &drm_gem_object
1591  * @__vm_bo: A pre-allocated struct drm_gpuvm_bo.
1592  *
1593  * Find the &drm_gpuvm_bo representing the combination of the given
1594  * &drm_gpuvm and &drm_gem_object. If found, increases the reference
1595  * count of the found &drm_gpuvm_bo accordingly, while the @__vm_bo reference
1596  * count is decreased. If not found @__vm_bo is returned without further
1597  * increase of the reference count.
1598  *
1599  * A new &drm_gpuvm_bo is added to the GEMs gpuva list.
1600  *
1601  * Returns: a pointer to the found &drm_gpuvm_bo or @__vm_bo if no existing
1602  * &drm_gpuvm_bo was found
1603  */
1604 struct drm_gpuvm_bo *
1605 drm_gpuvm_bo_obtain_prealloc(struct drm_gpuvm_bo *__vm_bo)
1606 {
1607 	struct drm_gpuvm *gpuvm = __vm_bo->vm;
1608 	struct drm_gem_object *obj = __vm_bo->obj;
1609 	struct drm_gpuvm_bo *vm_bo;
1610 
1611 	vm_bo = drm_gpuvm_bo_find(gpuvm, obj);
1612 	if (vm_bo) {
1613 		drm_gpuvm_bo_put(__vm_bo);
1614 		return vm_bo;
1615 	}
1616 
1617 	drm_gem_gpuva_assert_lock_held(obj);
1618 	list_add_tail(&__vm_bo->list.entry.gem, &obj->gpuva.list);
1619 
1620 	return __vm_bo;
1621 }
1622 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_obtain_prealloc);
1623 
1624 /**
1625  * drm_gpuvm_bo_extobj_add() - adds the &drm_gpuvm_bo to its &drm_gpuvm's
1626  * extobj list
1627  * @vm_bo: The &drm_gpuvm_bo to add to its &drm_gpuvm's the extobj list.
1628  *
1629  * Adds the given @vm_bo to its &drm_gpuvm's extobj list if not on the list
1630  * already and if the corresponding &drm_gem_object is an external object,
1631  * actually.
1632  */
1633 void
1634 drm_gpuvm_bo_extobj_add(struct drm_gpuvm_bo *vm_bo)
1635 {
1636 	struct drm_gpuvm *gpuvm = vm_bo->vm;
1637 	bool lock = !drm_gpuvm_resv_protected(gpuvm);
1638 
1639 	if (!lock)
1640 		drm_gpuvm_resv_assert_held(gpuvm);
1641 
1642 	if (drm_gpuvm_is_extobj(gpuvm, vm_bo->obj))
1643 		drm_gpuvm_bo_list_add(vm_bo, extobj, lock);
1644 }
1645 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_extobj_add);
1646 
1647 /**
1648  * drm_gpuvm_bo_evict() - add / remove a &drm_gpuvm_bo to / from the &drm_gpuvms
1649  * evicted list
1650  * @vm_bo: the &drm_gpuvm_bo to add or remove
1651  * @evict: indicates whether the object is evicted
1652  *
1653  * Adds a &drm_gpuvm_bo to or removes it from the &drm_gpuvms evicted list.
1654  */
1655 void
1656 drm_gpuvm_bo_evict(struct drm_gpuvm_bo *vm_bo, bool evict)
1657 {
1658 	struct drm_gpuvm *gpuvm = vm_bo->vm;
1659 	struct drm_gem_object *obj = vm_bo->obj;
1660 	bool lock = !drm_gpuvm_resv_protected(gpuvm);
1661 
1662 	dma_resv_assert_held(obj->resv);
1663 	vm_bo->evicted = evict;
1664 
1665 	/* Can't add external objects to the evicted list directly if not using
1666 	 * internal spinlocks, since in this case the evicted list is protected
1667 	 * with the VM's common dma-resv lock.
1668 	 */
1669 	if (drm_gpuvm_is_extobj(gpuvm, obj) && !lock)
1670 		return;
1671 
1672 	if (evict)
1673 		drm_gpuvm_bo_list_add(vm_bo, evict, lock);
1674 	else
1675 		drm_gpuvm_bo_list_del_init(vm_bo, evict, lock);
1676 }
1677 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_evict);
1678 
1679 static int
1680 __drm_gpuva_insert(struct drm_gpuvm *gpuvm,
1681 		   struct drm_gpuva *va)
1682 {
1683 	struct rb_node *node;
1684 	struct list_head *head;
1685 
1686 	if (drm_gpuva_it_iter_first(&gpuvm->rb.tree,
1687 				    GPUVA_START(va),
1688 				    GPUVA_LAST(va)))
1689 		return -EEXIST;
1690 
1691 	va->vm = gpuvm;
1692 
1693 	drm_gpuva_it_insert(va, &gpuvm->rb.tree);
1694 
1695 	node = rb_prev(&va->rb.node);
1696 	if (node)
1697 		head = &(to_drm_gpuva(node))->rb.entry;
1698 	else
1699 		head = &gpuvm->rb.list;
1700 
1701 	list_add(&va->rb.entry, head);
1702 
1703 	return 0;
1704 }
1705 
1706 /**
1707  * drm_gpuva_insert() - insert a &drm_gpuva
1708  * @gpuvm: the &drm_gpuvm to insert the &drm_gpuva in
1709  * @va: the &drm_gpuva to insert
1710  *
1711  * Insert a &drm_gpuva with a given address and range into a
1712  * &drm_gpuvm.
1713  *
1714  * It is safe to use this function using the safe versions of iterating the GPU
1715  * VA space, such as drm_gpuvm_for_each_va_safe() and
1716  * drm_gpuvm_for_each_va_range_safe().
1717  *
1718  * Returns: 0 on success, negative error code on failure.
1719  */
1720 int
1721 drm_gpuva_insert(struct drm_gpuvm *gpuvm,
1722 		 struct drm_gpuva *va)
1723 {
1724 	u64 addr = va->va.addr;
1725 	u64 range = va->va.range;
1726 	int ret;
1727 
1728 	if (unlikely(!drm_gpuvm_range_valid(gpuvm, addr, range)))
1729 		return -EINVAL;
1730 
1731 	ret = __drm_gpuva_insert(gpuvm, va);
1732 	if (likely(!ret))
1733 		/* Take a reference of the GPUVM for the successfully inserted
1734 		 * drm_gpuva. We can't take the reference in
1735 		 * __drm_gpuva_insert() itself, since we don't want to increse
1736 		 * the reference count for the GPUVM's kernel_alloc_node.
1737 		 */
1738 		drm_gpuvm_get(gpuvm);
1739 
1740 	return ret;
1741 }
1742 EXPORT_SYMBOL_GPL(drm_gpuva_insert);
1743 
1744 static void
1745 __drm_gpuva_remove(struct drm_gpuva *va)
1746 {
1747 	drm_gpuva_it_remove(va, &va->vm->rb.tree);
1748 	list_del_init(&va->rb.entry);
1749 }
1750 
1751 /**
1752  * drm_gpuva_remove() - remove a &drm_gpuva
1753  * @va: the &drm_gpuva to remove
1754  *
1755  * This removes the given &va from the underlaying tree.
1756  *
1757  * It is safe to use this function using the safe versions of iterating the GPU
1758  * VA space, such as drm_gpuvm_for_each_va_safe() and
1759  * drm_gpuvm_for_each_va_range_safe().
1760  */
1761 void
1762 drm_gpuva_remove(struct drm_gpuva *va)
1763 {
1764 	struct drm_gpuvm *gpuvm = va->vm;
1765 
1766 	if (unlikely(va == &gpuvm->kernel_alloc_node)) {
1767 		drm_WARN(gpuvm->drm, 1,
1768 			 "Can't destroy kernel reserved node.\n");
1769 		return;
1770 	}
1771 
1772 	__drm_gpuva_remove(va);
1773 	drm_gpuvm_put(va->vm);
1774 }
1775 EXPORT_SYMBOL_GPL(drm_gpuva_remove);
1776 
1777 /**
1778  * drm_gpuva_link() - link a &drm_gpuva
1779  * @va: the &drm_gpuva to link
1780  * @vm_bo: the &drm_gpuvm_bo to add the &drm_gpuva to
1781  *
1782  * This adds the given &va to the GPU VA list of the &drm_gpuvm_bo and the
1783  * &drm_gpuvm_bo to the &drm_gem_object it is associated with.
1784  *
1785  * For every &drm_gpuva entry added to the &drm_gpuvm_bo an additional
1786  * reference of the latter is taken.
1787  *
1788  * This function expects the caller to protect the GEM's GPUVA list against
1789  * concurrent access using either the GEMs dma_resv lock or a driver specific
1790  * lock set through drm_gem_gpuva_set_lock().
1791  */
1792 void
1793 drm_gpuva_link(struct drm_gpuva *va, struct drm_gpuvm_bo *vm_bo)
1794 {
1795 	struct drm_gem_object *obj = va->gem.obj;
1796 	struct drm_gpuvm *gpuvm = va->vm;
1797 
1798 	if (unlikely(!obj))
1799 		return;
1800 
1801 	drm_WARN_ON(gpuvm->drm, obj != vm_bo->obj);
1802 
1803 	va->vm_bo = drm_gpuvm_bo_get(vm_bo);
1804 
1805 	drm_gem_gpuva_assert_lock_held(obj);
1806 	list_add_tail(&va->gem.entry, &vm_bo->list.gpuva);
1807 }
1808 EXPORT_SYMBOL_GPL(drm_gpuva_link);
1809 
1810 /**
1811  * drm_gpuva_unlink() - unlink a &drm_gpuva
1812  * @va: the &drm_gpuva to unlink
1813  *
1814  * This removes the given &va from the GPU VA list of the &drm_gem_object it is
1815  * associated with.
1816  *
1817  * This removes the given &va from the GPU VA list of the &drm_gpuvm_bo and
1818  * the &drm_gpuvm_bo from the &drm_gem_object it is associated with in case
1819  * this call unlinks the last &drm_gpuva from the &drm_gpuvm_bo.
1820  *
1821  * For every &drm_gpuva entry removed from the &drm_gpuvm_bo a reference of
1822  * the latter is dropped.
1823  *
1824  * This function expects the caller to protect the GEM's GPUVA list against
1825  * concurrent access using either the GEMs dma_resv lock or a driver specific
1826  * lock set through drm_gem_gpuva_set_lock().
1827  */
1828 void
1829 drm_gpuva_unlink(struct drm_gpuva *va)
1830 {
1831 	struct drm_gem_object *obj = va->gem.obj;
1832 	struct drm_gpuvm_bo *vm_bo = va->vm_bo;
1833 
1834 	if (unlikely(!obj))
1835 		return;
1836 
1837 	drm_gem_gpuva_assert_lock_held(obj);
1838 	list_del_init(&va->gem.entry);
1839 
1840 	va->vm_bo = NULL;
1841 	drm_gpuvm_bo_put(vm_bo);
1842 }
1843 EXPORT_SYMBOL_GPL(drm_gpuva_unlink);
1844 
1845 /**
1846  * drm_gpuva_find_first() - find the first &drm_gpuva in the given range
1847  * @gpuvm: the &drm_gpuvm to search in
1848  * @addr: the &drm_gpuvas address
1849  * @range: the &drm_gpuvas range
1850  *
1851  * Returns: the first &drm_gpuva within the given range
1852  */
1853 struct drm_gpuva *
1854 drm_gpuva_find_first(struct drm_gpuvm *gpuvm,
1855 		     u64 addr, u64 range)
1856 {
1857 	u64 last = addr + range - 1;
1858 
1859 	return drm_gpuva_it_iter_first(&gpuvm->rb.tree, addr, last);
1860 }
1861 EXPORT_SYMBOL_GPL(drm_gpuva_find_first);
1862 
1863 /**
1864  * drm_gpuva_find() - find a &drm_gpuva
1865  * @gpuvm: the &drm_gpuvm to search in
1866  * @addr: the &drm_gpuvas address
1867  * @range: the &drm_gpuvas range
1868  *
1869  * Returns: the &drm_gpuva at a given &addr and with a given &range
1870  */
1871 struct drm_gpuva *
1872 drm_gpuva_find(struct drm_gpuvm *gpuvm,
1873 	       u64 addr, u64 range)
1874 {
1875 	struct drm_gpuva *va;
1876 
1877 	va = drm_gpuva_find_first(gpuvm, addr, range);
1878 	if (!va)
1879 		goto out;
1880 
1881 	if (va->va.addr != addr ||
1882 	    va->va.range != range)
1883 		goto out;
1884 
1885 	return va;
1886 
1887 out:
1888 	return NULL;
1889 }
1890 EXPORT_SYMBOL_GPL(drm_gpuva_find);
1891 
1892 /**
1893  * drm_gpuva_find_prev() - find the &drm_gpuva before the given address
1894  * @gpuvm: the &drm_gpuvm to search in
1895  * @start: the given GPU VA's start address
1896  *
1897  * Find the adjacent &drm_gpuva before the GPU VA with given &start address.
1898  *
1899  * Note that if there is any free space between the GPU VA mappings no mapping
1900  * is returned.
1901  *
1902  * Returns: a pointer to the found &drm_gpuva or NULL if none was found
1903  */
1904 struct drm_gpuva *
1905 drm_gpuva_find_prev(struct drm_gpuvm *gpuvm, u64 start)
1906 {
1907 	if (!drm_gpuvm_range_valid(gpuvm, start - 1, 1))
1908 		return NULL;
1909 
1910 	return drm_gpuva_it_iter_first(&gpuvm->rb.tree, start - 1, start);
1911 }
1912 EXPORT_SYMBOL_GPL(drm_gpuva_find_prev);
1913 
1914 /**
1915  * drm_gpuva_find_next() - find the &drm_gpuva after the given address
1916  * @gpuvm: the &drm_gpuvm to search in
1917  * @end: the given GPU VA's end address
1918  *
1919  * Find the adjacent &drm_gpuva after the GPU VA with given &end address.
1920  *
1921  * Note that if there is any free space between the GPU VA mappings no mapping
1922  * is returned.
1923  *
1924  * Returns: a pointer to the found &drm_gpuva or NULL if none was found
1925  */
1926 struct drm_gpuva *
1927 drm_gpuva_find_next(struct drm_gpuvm *gpuvm, u64 end)
1928 {
1929 	if (!drm_gpuvm_range_valid(gpuvm, end, 1))
1930 		return NULL;
1931 
1932 	return drm_gpuva_it_iter_first(&gpuvm->rb.tree, end, end + 1);
1933 }
1934 EXPORT_SYMBOL_GPL(drm_gpuva_find_next);
1935 
1936 /**
1937  * drm_gpuvm_interval_empty() - indicate whether a given interval of the VA space
1938  * is empty
1939  * @gpuvm: the &drm_gpuvm to check the range for
1940  * @addr: the start address of the range
1941  * @range: the range of the interval
1942  *
1943  * Returns: true if the interval is empty, false otherwise
1944  */
1945 bool
1946 drm_gpuvm_interval_empty(struct drm_gpuvm *gpuvm, u64 addr, u64 range)
1947 {
1948 	return !drm_gpuva_find_first(gpuvm, addr, range);
1949 }
1950 EXPORT_SYMBOL_GPL(drm_gpuvm_interval_empty);
1951 
1952 /**
1953  * drm_gpuva_map() - helper to insert a &drm_gpuva according to a
1954  * &drm_gpuva_op_map
1955  * @gpuvm: the &drm_gpuvm
1956  * @va: the &drm_gpuva to insert
1957  * @op: the &drm_gpuva_op_map to initialize @va with
1958  *
1959  * Initializes the @va from the @op and inserts it into the given @gpuvm.
1960  */
1961 void
1962 drm_gpuva_map(struct drm_gpuvm *gpuvm,
1963 	      struct drm_gpuva *va,
1964 	      struct drm_gpuva_op_map *op)
1965 {
1966 	drm_gpuva_init_from_op(va, op);
1967 	drm_gpuva_insert(gpuvm, va);
1968 }
1969 EXPORT_SYMBOL_GPL(drm_gpuva_map);
1970 
1971 /**
1972  * drm_gpuva_remap() - helper to remap a &drm_gpuva according to a
1973  * &drm_gpuva_op_remap
1974  * @prev: the &drm_gpuva to remap when keeping the start of a mapping
1975  * @next: the &drm_gpuva to remap when keeping the end of a mapping
1976  * @op: the &drm_gpuva_op_remap to initialize @prev and @next with
1977  *
1978  * Removes the currently mapped &drm_gpuva and remaps it using @prev and/or
1979  * @next.
1980  */
1981 void
1982 drm_gpuva_remap(struct drm_gpuva *prev,
1983 		struct drm_gpuva *next,
1984 		struct drm_gpuva_op_remap *op)
1985 {
1986 	struct drm_gpuva *va = op->unmap->va;
1987 	struct drm_gpuvm *gpuvm = va->vm;
1988 
1989 	drm_gpuva_remove(va);
1990 
1991 	if (op->prev) {
1992 		drm_gpuva_init_from_op(prev, op->prev);
1993 		drm_gpuva_insert(gpuvm, prev);
1994 	}
1995 
1996 	if (op->next) {
1997 		drm_gpuva_init_from_op(next, op->next);
1998 		drm_gpuva_insert(gpuvm, next);
1999 	}
2000 }
2001 EXPORT_SYMBOL_GPL(drm_gpuva_remap);
2002 
2003 /**
2004  * drm_gpuva_unmap() - helper to remove a &drm_gpuva according to a
2005  * &drm_gpuva_op_unmap
2006  * @op: the &drm_gpuva_op_unmap specifying the &drm_gpuva to remove
2007  *
2008  * Removes the &drm_gpuva associated with the &drm_gpuva_op_unmap.
2009  */
2010 void
2011 drm_gpuva_unmap(struct drm_gpuva_op_unmap *op)
2012 {
2013 	drm_gpuva_remove(op->va);
2014 }
2015 EXPORT_SYMBOL_GPL(drm_gpuva_unmap);
2016 
2017 static int
2018 op_map_cb(const struct drm_gpuvm_ops *fn, void *priv,
2019 	  u64 addr, u64 range,
2020 	  struct drm_gem_object *obj, u64 offset)
2021 {
2022 	struct drm_gpuva_op op = {};
2023 
2024 	op.op = DRM_GPUVA_OP_MAP;
2025 	op.map.va.addr = addr;
2026 	op.map.va.range = range;
2027 	op.map.gem.obj = obj;
2028 	op.map.gem.offset = offset;
2029 
2030 	return fn->sm_step_map(&op, priv);
2031 }
2032 
2033 static int
2034 op_remap_cb(const struct drm_gpuvm_ops *fn, void *priv,
2035 	    struct drm_gpuva_op_map *prev,
2036 	    struct drm_gpuva_op_map *next,
2037 	    struct drm_gpuva_op_unmap *unmap)
2038 {
2039 	struct drm_gpuva_op op = {};
2040 	struct drm_gpuva_op_remap *r;
2041 
2042 	op.op = DRM_GPUVA_OP_REMAP;
2043 	r = &op.remap;
2044 	r->prev = prev;
2045 	r->next = next;
2046 	r->unmap = unmap;
2047 
2048 	return fn->sm_step_remap(&op, priv);
2049 }
2050 
2051 static int
2052 op_unmap_cb(const struct drm_gpuvm_ops *fn, void *priv,
2053 	    struct drm_gpuva *va, bool merge)
2054 {
2055 	struct drm_gpuva_op op = {};
2056 
2057 	op.op = DRM_GPUVA_OP_UNMAP;
2058 	op.unmap.va = va;
2059 	op.unmap.keep = merge;
2060 
2061 	return fn->sm_step_unmap(&op, priv);
2062 }
2063 
2064 static int
2065 __drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm,
2066 		   const struct drm_gpuvm_ops *ops, void *priv,
2067 		   u64 req_addr, u64 req_range,
2068 		   struct drm_gem_object *req_obj, u64 req_offset)
2069 {
2070 	struct drm_gpuva *va, *next;
2071 	u64 req_end = req_addr + req_range;
2072 	int ret;
2073 
2074 	if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range)))
2075 		return -EINVAL;
2076 
2077 	drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) {
2078 		struct drm_gem_object *obj = va->gem.obj;
2079 		u64 offset = va->gem.offset;
2080 		u64 addr = va->va.addr;
2081 		u64 range = va->va.range;
2082 		u64 end = addr + range;
2083 		bool merge = !!va->gem.obj;
2084 
2085 		if (addr == req_addr) {
2086 			merge &= obj == req_obj &&
2087 				 offset == req_offset;
2088 
2089 			if (end == req_end) {
2090 				ret = op_unmap_cb(ops, priv, va, merge);
2091 				if (ret)
2092 					return ret;
2093 				break;
2094 			}
2095 
2096 			if (end < req_end) {
2097 				ret = op_unmap_cb(ops, priv, va, merge);
2098 				if (ret)
2099 					return ret;
2100 				continue;
2101 			}
2102 
2103 			if (end > req_end) {
2104 				struct drm_gpuva_op_map n = {
2105 					.va.addr = req_end,
2106 					.va.range = range - req_range,
2107 					.gem.obj = obj,
2108 					.gem.offset = offset + req_range,
2109 				};
2110 				struct drm_gpuva_op_unmap u = {
2111 					.va = va,
2112 					.keep = merge,
2113 				};
2114 
2115 				ret = op_remap_cb(ops, priv, NULL, &n, &u);
2116 				if (ret)
2117 					return ret;
2118 				break;
2119 			}
2120 		} else if (addr < req_addr) {
2121 			u64 ls_range = req_addr - addr;
2122 			struct drm_gpuva_op_map p = {
2123 				.va.addr = addr,
2124 				.va.range = ls_range,
2125 				.gem.obj = obj,
2126 				.gem.offset = offset,
2127 			};
2128 			struct drm_gpuva_op_unmap u = { .va = va };
2129 
2130 			merge &= obj == req_obj &&
2131 				 offset + ls_range == req_offset;
2132 			u.keep = merge;
2133 
2134 			if (end == req_end) {
2135 				ret = op_remap_cb(ops, priv, &p, NULL, &u);
2136 				if (ret)
2137 					return ret;
2138 				break;
2139 			}
2140 
2141 			if (end < req_end) {
2142 				ret = op_remap_cb(ops, priv, &p, NULL, &u);
2143 				if (ret)
2144 					return ret;
2145 				continue;
2146 			}
2147 
2148 			if (end > req_end) {
2149 				struct drm_gpuva_op_map n = {
2150 					.va.addr = req_end,
2151 					.va.range = end - req_end,
2152 					.gem.obj = obj,
2153 					.gem.offset = offset + ls_range +
2154 						      req_range,
2155 				};
2156 
2157 				ret = op_remap_cb(ops, priv, &p, &n, &u);
2158 				if (ret)
2159 					return ret;
2160 				break;
2161 			}
2162 		} else if (addr > req_addr) {
2163 			merge &= obj == req_obj &&
2164 				 offset == req_offset +
2165 					   (addr - req_addr);
2166 
2167 			if (end == req_end) {
2168 				ret = op_unmap_cb(ops, priv, va, merge);
2169 				if (ret)
2170 					return ret;
2171 				break;
2172 			}
2173 
2174 			if (end < req_end) {
2175 				ret = op_unmap_cb(ops, priv, va, merge);
2176 				if (ret)
2177 					return ret;
2178 				continue;
2179 			}
2180 
2181 			if (end > req_end) {
2182 				struct drm_gpuva_op_map n = {
2183 					.va.addr = req_end,
2184 					.va.range = end - req_end,
2185 					.gem.obj = obj,
2186 					.gem.offset = offset + req_end - addr,
2187 				};
2188 				struct drm_gpuva_op_unmap u = {
2189 					.va = va,
2190 					.keep = merge,
2191 				};
2192 
2193 				ret = op_remap_cb(ops, priv, NULL, &n, &u);
2194 				if (ret)
2195 					return ret;
2196 				break;
2197 			}
2198 		}
2199 	}
2200 
2201 	return op_map_cb(ops, priv,
2202 			 req_addr, req_range,
2203 			 req_obj, req_offset);
2204 }
2205 
2206 static int
2207 __drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm,
2208 		     const struct drm_gpuvm_ops *ops, void *priv,
2209 		     u64 req_addr, u64 req_range)
2210 {
2211 	struct drm_gpuva *va, *next;
2212 	u64 req_end = req_addr + req_range;
2213 	int ret;
2214 
2215 	if (unlikely(!drm_gpuvm_range_valid(gpuvm, req_addr, req_range)))
2216 		return -EINVAL;
2217 
2218 	drm_gpuvm_for_each_va_range_safe(va, next, gpuvm, req_addr, req_end) {
2219 		struct drm_gpuva_op_map prev = {}, next = {};
2220 		bool prev_split = false, next_split = false;
2221 		struct drm_gem_object *obj = va->gem.obj;
2222 		u64 offset = va->gem.offset;
2223 		u64 addr = va->va.addr;
2224 		u64 range = va->va.range;
2225 		u64 end = addr + range;
2226 
2227 		if (addr < req_addr) {
2228 			prev.va.addr = addr;
2229 			prev.va.range = req_addr - addr;
2230 			prev.gem.obj = obj;
2231 			prev.gem.offset = offset;
2232 
2233 			prev_split = true;
2234 		}
2235 
2236 		if (end > req_end) {
2237 			next.va.addr = req_end;
2238 			next.va.range = end - req_end;
2239 			next.gem.obj = obj;
2240 			next.gem.offset = offset + (req_end - addr);
2241 
2242 			next_split = true;
2243 		}
2244 
2245 		if (prev_split || next_split) {
2246 			struct drm_gpuva_op_unmap unmap = { .va = va };
2247 
2248 			ret = op_remap_cb(ops, priv,
2249 					  prev_split ? &prev : NULL,
2250 					  next_split ? &next : NULL,
2251 					  &unmap);
2252 			if (ret)
2253 				return ret;
2254 		} else {
2255 			ret = op_unmap_cb(ops, priv, va, false);
2256 			if (ret)
2257 				return ret;
2258 		}
2259 	}
2260 
2261 	return 0;
2262 }
2263 
2264 /**
2265  * drm_gpuvm_sm_map() - creates the &drm_gpuva_op split/merge steps
2266  * @gpuvm: the &drm_gpuvm representing the GPU VA space
2267  * @req_addr: the start address of the new mapping
2268  * @req_range: the range of the new mapping
2269  * @req_obj: the &drm_gem_object to map
2270  * @req_offset: the offset within the &drm_gem_object
2271  * @priv: pointer to a driver private data structure
2272  *
2273  * This function iterates the given range of the GPU VA space. It utilizes the
2274  * &drm_gpuvm_ops to call back into the driver providing the split and merge
2275  * steps.
2276  *
2277  * Drivers may use these callbacks to update the GPU VA space right away within
2278  * the callback. In case the driver decides to copy and store the operations for
2279  * later processing neither this function nor &drm_gpuvm_sm_unmap is allowed to
2280  * be called before the &drm_gpuvm's view of the GPU VA space was
2281  * updated with the previous set of operations. To update the
2282  * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
2283  * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
2284  * used.
2285  *
2286  * A sequence of callbacks can contain map, unmap and remap operations, but
2287  * the sequence of callbacks might also be empty if no operation is required,
2288  * e.g. if the requested mapping already exists in the exact same way.
2289  *
2290  * There can be an arbitrary amount of unmap operations, a maximum of two remap
2291  * operations and a single map operation. The latter one represents the original
2292  * map operation requested by the caller.
2293  *
2294  * Returns: 0 on success or a negative error code
2295  */
2296 int
2297 drm_gpuvm_sm_map(struct drm_gpuvm *gpuvm, void *priv,
2298 		 u64 req_addr, u64 req_range,
2299 		 struct drm_gem_object *req_obj, u64 req_offset)
2300 {
2301 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
2302 
2303 	if (unlikely(!(ops && ops->sm_step_map &&
2304 		       ops->sm_step_remap &&
2305 		       ops->sm_step_unmap)))
2306 		return -EINVAL;
2307 
2308 	return __drm_gpuvm_sm_map(gpuvm, ops, priv,
2309 				  req_addr, req_range,
2310 				  req_obj, req_offset);
2311 }
2312 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map);
2313 
2314 /**
2315  * drm_gpuvm_sm_unmap() - creates the &drm_gpuva_ops to split on unmap
2316  * @gpuvm: the &drm_gpuvm representing the GPU VA space
2317  * @priv: pointer to a driver private data structure
2318  * @req_addr: the start address of the range to unmap
2319  * @req_range: the range of the mappings to unmap
2320  *
2321  * This function iterates the given range of the GPU VA space. It utilizes the
2322  * &drm_gpuvm_ops to call back into the driver providing the operations to
2323  * unmap and, if required, split existent mappings.
2324  *
2325  * Drivers may use these callbacks to update the GPU VA space right away within
2326  * the callback. In case the driver decides to copy and store the operations for
2327  * later processing neither this function nor &drm_gpuvm_sm_map is allowed to be
2328  * called before the &drm_gpuvm's view of the GPU VA space was updated
2329  * with the previous set of operations. To update the &drm_gpuvm's view
2330  * of the GPU VA space drm_gpuva_insert(), drm_gpuva_destroy_locked() and/or
2331  * drm_gpuva_destroy_unlocked() should be used.
2332  *
2333  * A sequence of callbacks can contain unmap and remap operations, depending on
2334  * whether there are actual overlapping mappings to split.
2335  *
2336  * There can be an arbitrary amount of unmap operations and a maximum of two
2337  * remap operations.
2338  *
2339  * Returns: 0 on success or a negative error code
2340  */
2341 int
2342 drm_gpuvm_sm_unmap(struct drm_gpuvm *gpuvm, void *priv,
2343 		   u64 req_addr, u64 req_range)
2344 {
2345 	const struct drm_gpuvm_ops *ops = gpuvm->ops;
2346 
2347 	if (unlikely(!(ops && ops->sm_step_remap &&
2348 		       ops->sm_step_unmap)))
2349 		return -EINVAL;
2350 
2351 	return __drm_gpuvm_sm_unmap(gpuvm, ops, priv,
2352 				    req_addr, req_range);
2353 }
2354 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap);
2355 
2356 static struct drm_gpuva_op *
2357 gpuva_op_alloc(struct drm_gpuvm *gpuvm)
2358 {
2359 	const struct drm_gpuvm_ops *fn = gpuvm->ops;
2360 	struct drm_gpuva_op *op;
2361 
2362 	if (fn && fn->op_alloc)
2363 		op = fn->op_alloc();
2364 	else
2365 		op = kzalloc(sizeof(*op), GFP_KERNEL);
2366 
2367 	if (unlikely(!op))
2368 		return NULL;
2369 
2370 	return op;
2371 }
2372 
2373 static void
2374 gpuva_op_free(struct drm_gpuvm *gpuvm,
2375 	      struct drm_gpuva_op *op)
2376 {
2377 	const struct drm_gpuvm_ops *fn = gpuvm->ops;
2378 
2379 	if (fn && fn->op_free)
2380 		fn->op_free(op);
2381 	else
2382 		kfree(op);
2383 }
2384 
2385 static int
2386 drm_gpuva_sm_step(struct drm_gpuva_op *__op,
2387 		  void *priv)
2388 {
2389 	struct {
2390 		struct drm_gpuvm *vm;
2391 		struct drm_gpuva_ops *ops;
2392 	} *args = priv;
2393 	struct drm_gpuvm *gpuvm = args->vm;
2394 	struct drm_gpuva_ops *ops = args->ops;
2395 	struct drm_gpuva_op *op;
2396 
2397 	op = gpuva_op_alloc(gpuvm);
2398 	if (unlikely(!op))
2399 		goto err;
2400 
2401 	memcpy(op, __op, sizeof(*op));
2402 
2403 	if (op->op == DRM_GPUVA_OP_REMAP) {
2404 		struct drm_gpuva_op_remap *__r = &__op->remap;
2405 		struct drm_gpuva_op_remap *r = &op->remap;
2406 
2407 		r->unmap = kmemdup(__r->unmap, sizeof(*r->unmap),
2408 				   GFP_KERNEL);
2409 		if (unlikely(!r->unmap))
2410 			goto err_free_op;
2411 
2412 		if (__r->prev) {
2413 			r->prev = kmemdup(__r->prev, sizeof(*r->prev),
2414 					  GFP_KERNEL);
2415 			if (unlikely(!r->prev))
2416 				goto err_free_unmap;
2417 		}
2418 
2419 		if (__r->next) {
2420 			r->next = kmemdup(__r->next, sizeof(*r->next),
2421 					  GFP_KERNEL);
2422 			if (unlikely(!r->next))
2423 				goto err_free_prev;
2424 		}
2425 	}
2426 
2427 	list_add_tail(&op->entry, &ops->list);
2428 
2429 	return 0;
2430 
2431 err_free_unmap:
2432 	kfree(op->remap.unmap);
2433 err_free_prev:
2434 	kfree(op->remap.prev);
2435 err_free_op:
2436 	gpuva_op_free(gpuvm, op);
2437 err:
2438 	return -ENOMEM;
2439 }
2440 
2441 static const struct drm_gpuvm_ops gpuvm_list_ops = {
2442 	.sm_step_map = drm_gpuva_sm_step,
2443 	.sm_step_remap = drm_gpuva_sm_step,
2444 	.sm_step_unmap = drm_gpuva_sm_step,
2445 };
2446 
2447 /**
2448  * drm_gpuvm_sm_map_ops_create() - creates the &drm_gpuva_ops to split and merge
2449  * @gpuvm: the &drm_gpuvm representing the GPU VA space
2450  * @req_addr: the start address of the new mapping
2451  * @req_range: the range of the new mapping
2452  * @req_obj: the &drm_gem_object to map
2453  * @req_offset: the offset within the &drm_gem_object
2454  *
2455  * This function creates a list of operations to perform splitting and merging
2456  * of existent mapping(s) with the newly requested one.
2457  *
2458  * The list can be iterated with &drm_gpuva_for_each_op and must be processed
2459  * in the given order. It can contain map, unmap and remap operations, but it
2460  * also can be empty if no operation is required, e.g. if the requested mapping
2461  * already exists is the exact same way.
2462  *
2463  * There can be an arbitrary amount of unmap operations, a maximum of two remap
2464  * operations and a single map operation. The latter one represents the original
2465  * map operation requested by the caller.
2466  *
2467  * Note that before calling this function again with another mapping request it
2468  * is necessary to update the &drm_gpuvm's view of the GPU VA space. The
2469  * previously obtained operations must be either processed or abandoned. To
2470  * update the &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
2471  * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
2472  * used.
2473  *
2474  * After the caller finished processing the returned &drm_gpuva_ops, they must
2475  * be freed with &drm_gpuva_ops_free.
2476  *
2477  * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
2478  */
2479 struct drm_gpuva_ops *
2480 drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm,
2481 			    u64 req_addr, u64 req_range,
2482 			    struct drm_gem_object *req_obj, u64 req_offset)
2483 {
2484 	struct drm_gpuva_ops *ops;
2485 	struct {
2486 		struct drm_gpuvm *vm;
2487 		struct drm_gpuva_ops *ops;
2488 	} args;
2489 	int ret;
2490 
2491 	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
2492 	if (unlikely(!ops))
2493 		return ERR_PTR(-ENOMEM);
2494 
2495 	INIT_LIST_HEAD(&ops->list);
2496 
2497 	args.vm = gpuvm;
2498 	args.ops = ops;
2499 
2500 	ret = __drm_gpuvm_sm_map(gpuvm, &gpuvm_list_ops, &args,
2501 				 req_addr, req_range,
2502 				 req_obj, req_offset);
2503 	if (ret)
2504 		goto err_free_ops;
2505 
2506 	return ops;
2507 
2508 err_free_ops:
2509 	drm_gpuva_ops_free(gpuvm, ops);
2510 	return ERR_PTR(ret);
2511 }
2512 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_map_ops_create);
2513 
2514 /**
2515  * drm_gpuvm_sm_unmap_ops_create() - creates the &drm_gpuva_ops to split on
2516  * unmap
2517  * @gpuvm: the &drm_gpuvm representing the GPU VA space
2518  * @req_addr: the start address of the range to unmap
2519  * @req_range: the range of the mappings to unmap
2520  *
2521  * This function creates a list of operations to perform unmapping and, if
2522  * required, splitting of the mappings overlapping the unmap range.
2523  *
2524  * The list can be iterated with &drm_gpuva_for_each_op and must be processed
2525  * in the given order. It can contain unmap and remap operations, depending on
2526  * whether there are actual overlapping mappings to split.
2527  *
2528  * There can be an arbitrary amount of unmap operations and a maximum of two
2529  * remap operations.
2530  *
2531  * Note that before calling this function again with another range to unmap it
2532  * is necessary to update the &drm_gpuvm's view of the GPU VA space. The
2533  * previously obtained operations must be processed or abandoned. To update the
2534  * &drm_gpuvm's view of the GPU VA space drm_gpuva_insert(),
2535  * drm_gpuva_destroy_locked() and/or drm_gpuva_destroy_unlocked() should be
2536  * used.
2537  *
2538  * After the caller finished processing the returned &drm_gpuva_ops, they must
2539  * be freed with &drm_gpuva_ops_free.
2540  *
2541  * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
2542  */
2543 struct drm_gpuva_ops *
2544 drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm,
2545 			      u64 req_addr, u64 req_range)
2546 {
2547 	struct drm_gpuva_ops *ops;
2548 	struct {
2549 		struct drm_gpuvm *vm;
2550 		struct drm_gpuva_ops *ops;
2551 	} args;
2552 	int ret;
2553 
2554 	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
2555 	if (unlikely(!ops))
2556 		return ERR_PTR(-ENOMEM);
2557 
2558 	INIT_LIST_HEAD(&ops->list);
2559 
2560 	args.vm = gpuvm;
2561 	args.ops = ops;
2562 
2563 	ret = __drm_gpuvm_sm_unmap(gpuvm, &gpuvm_list_ops, &args,
2564 				   req_addr, req_range);
2565 	if (ret)
2566 		goto err_free_ops;
2567 
2568 	return ops;
2569 
2570 err_free_ops:
2571 	drm_gpuva_ops_free(gpuvm, ops);
2572 	return ERR_PTR(ret);
2573 }
2574 EXPORT_SYMBOL_GPL(drm_gpuvm_sm_unmap_ops_create);
2575 
2576 /**
2577  * drm_gpuvm_prefetch_ops_create() - creates the &drm_gpuva_ops to prefetch
2578  * @gpuvm: the &drm_gpuvm representing the GPU VA space
2579  * @addr: the start address of the range to prefetch
2580  * @range: the range of the mappings to prefetch
2581  *
2582  * This function creates a list of operations to perform prefetching.
2583  *
2584  * The list can be iterated with &drm_gpuva_for_each_op and must be processed
2585  * in the given order. It can contain prefetch operations.
2586  *
2587  * There can be an arbitrary amount of prefetch operations.
2588  *
2589  * After the caller finished processing the returned &drm_gpuva_ops, they must
2590  * be freed with &drm_gpuva_ops_free.
2591  *
2592  * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
2593  */
2594 struct drm_gpuva_ops *
2595 drm_gpuvm_prefetch_ops_create(struct drm_gpuvm *gpuvm,
2596 			      u64 addr, u64 range)
2597 {
2598 	struct drm_gpuva_ops *ops;
2599 	struct drm_gpuva_op *op;
2600 	struct drm_gpuva *va;
2601 	u64 end = addr + range;
2602 	int ret;
2603 
2604 	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
2605 	if (!ops)
2606 		return ERR_PTR(-ENOMEM);
2607 
2608 	INIT_LIST_HEAD(&ops->list);
2609 
2610 	drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) {
2611 		op = gpuva_op_alloc(gpuvm);
2612 		if (!op) {
2613 			ret = -ENOMEM;
2614 			goto err_free_ops;
2615 		}
2616 
2617 		op->op = DRM_GPUVA_OP_PREFETCH;
2618 		op->prefetch.va = va;
2619 		list_add_tail(&op->entry, &ops->list);
2620 	}
2621 
2622 	return ops;
2623 
2624 err_free_ops:
2625 	drm_gpuva_ops_free(gpuvm, ops);
2626 	return ERR_PTR(ret);
2627 }
2628 EXPORT_SYMBOL_GPL(drm_gpuvm_prefetch_ops_create);
2629 
2630 /**
2631  * drm_gpuvm_bo_unmap_ops_create() - creates the &drm_gpuva_ops to unmap a GEM
2632  * @vm_bo: the &drm_gpuvm_bo abstraction
2633  *
2634  * This function creates a list of operations to perform unmapping for every
2635  * GPUVA attached to a GEM.
2636  *
2637  * The list can be iterated with &drm_gpuva_for_each_op and consists out of an
2638  * arbitrary amount of unmap operations.
2639  *
2640  * After the caller finished processing the returned &drm_gpuva_ops, they must
2641  * be freed with &drm_gpuva_ops_free.
2642  *
2643  * It is the callers responsibility to protect the GEMs GPUVA list against
2644  * concurrent access using the GEMs dma_resv lock.
2645  *
2646  * Returns: a pointer to the &drm_gpuva_ops on success, an ERR_PTR on failure
2647  */
2648 struct drm_gpuva_ops *
2649 drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo)
2650 {
2651 	struct drm_gpuva_ops *ops;
2652 	struct drm_gpuva_op *op;
2653 	struct drm_gpuva *va;
2654 	int ret;
2655 
2656 	drm_gem_gpuva_assert_lock_held(vm_bo->obj);
2657 
2658 	ops = kzalloc(sizeof(*ops), GFP_KERNEL);
2659 	if (!ops)
2660 		return ERR_PTR(-ENOMEM);
2661 
2662 	INIT_LIST_HEAD(&ops->list);
2663 
2664 	drm_gpuvm_bo_for_each_va(va, vm_bo) {
2665 		op = gpuva_op_alloc(vm_bo->vm);
2666 		if (!op) {
2667 			ret = -ENOMEM;
2668 			goto err_free_ops;
2669 		}
2670 
2671 		op->op = DRM_GPUVA_OP_UNMAP;
2672 		op->unmap.va = va;
2673 		list_add_tail(&op->entry, &ops->list);
2674 	}
2675 
2676 	return ops;
2677 
2678 err_free_ops:
2679 	drm_gpuva_ops_free(vm_bo->vm, ops);
2680 	return ERR_PTR(ret);
2681 }
2682 EXPORT_SYMBOL_GPL(drm_gpuvm_bo_unmap_ops_create);
2683 
2684 /**
2685  * drm_gpuva_ops_free() - free the given &drm_gpuva_ops
2686  * @gpuvm: the &drm_gpuvm the ops were created for
2687  * @ops: the &drm_gpuva_ops to free
2688  *
2689  * Frees the given &drm_gpuva_ops structure including all the ops associated
2690  * with it.
2691  */
2692 void
2693 drm_gpuva_ops_free(struct drm_gpuvm *gpuvm,
2694 		   struct drm_gpuva_ops *ops)
2695 {
2696 	struct drm_gpuva_op *op, *next;
2697 
2698 	drm_gpuva_for_each_op_safe(op, next, ops) {
2699 		list_del(&op->entry);
2700 
2701 		if (op->op == DRM_GPUVA_OP_REMAP) {
2702 			kfree(op->remap.prev);
2703 			kfree(op->remap.next);
2704 			kfree(op->remap.unmap);
2705 		}
2706 
2707 		gpuva_op_free(gpuvm, op);
2708 	}
2709 
2710 	kfree(ops);
2711 }
2712 EXPORT_SYMBOL_GPL(drm_gpuva_ops_free);
2713 
2714 MODULE_DESCRIPTION("DRM GPUVM");
2715 MODULE_LICENSE("GPL");
2716