xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/i915/gem/selftests/i915_gem_mman.c (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: i915_gem_mman.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $	*/
2 
3 /*
4  * SPDX-License-Identifier: MIT
5  *
6  * Copyright © 2016 Intel Corporation
7  */
8 
9 #include <sys/cdefs.h>
10 __KERNEL_RCSID(0, "$NetBSD: i915_gem_mman.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $");
11 
12 #include <linux/prime_numbers.h>
13 
14 #include "gt/intel_engine_pm.h"
15 #include "gt/intel_gt.h"
16 #include "gt/intel_gt_pm.h"
17 #include "gem/i915_gem_region.h"
18 #include "huge_gem_object.h"
19 #include "i915_selftest.h"
20 #include "selftests/i915_random.h"
21 #include "selftests/igt_flush_test.h"
22 #include "selftests/igt_mmap.h"
23 
24 struct tile {
25 	unsigned int width;
26 	unsigned int height;
27 	unsigned int stride;
28 	unsigned int size;
29 	unsigned int tiling;
30 	unsigned int swizzle;
31 };
32 
swizzle_bit(unsigned int bit,u64 offset)33 static u64 swizzle_bit(unsigned int bit, u64 offset)
34 {
35 	return (offset & BIT_ULL(bit)) >> (bit - 6);
36 }
37 
tiled_offset(const struct tile * tile,u64 v)38 static u64 tiled_offset(const struct tile *tile, u64 v)
39 {
40 	u64 x, y;
41 
42 	if (tile->tiling == I915_TILING_NONE)
43 		return v;
44 
45 	y = div64_u64_rem(v, tile->stride, &x);
46 	v = div64_u64_rem(y, tile->height, &y) * tile->stride * tile->height;
47 
48 	if (tile->tiling == I915_TILING_X) {
49 		v += y * tile->width;
50 		v += div64_u64_rem(x, tile->width, &x) << tile->size;
51 		v += x;
52 	} else if (tile->width == 128) {
53 		const unsigned int ytile_span = 16;
54 		const unsigned int ytile_height = 512;
55 
56 		v += y * ytile_span;
57 		v += div64_u64_rem(x, ytile_span, &x) * ytile_height;
58 		v += x;
59 	} else {
60 		const unsigned int ytile_span = 32;
61 		const unsigned int ytile_height = 256;
62 
63 		v += y * ytile_span;
64 		v += div64_u64_rem(x, ytile_span, &x) * ytile_height;
65 		v += x;
66 	}
67 
68 	switch (tile->swizzle) {
69 	case I915_BIT_6_SWIZZLE_9:
70 		v ^= swizzle_bit(9, v);
71 		break;
72 	case I915_BIT_6_SWIZZLE_9_10:
73 		v ^= swizzle_bit(9, v) ^ swizzle_bit(10, v);
74 		break;
75 	case I915_BIT_6_SWIZZLE_9_11:
76 		v ^= swizzle_bit(9, v) ^ swizzle_bit(11, v);
77 		break;
78 	case I915_BIT_6_SWIZZLE_9_10_11:
79 		v ^= swizzle_bit(9, v) ^ swizzle_bit(10, v) ^ swizzle_bit(11, v);
80 		break;
81 	}
82 
83 	return v;
84 }
85 
check_partial_mapping(struct drm_i915_gem_object * obj,const struct tile * tile,struct rnd_state * prng)86 static int check_partial_mapping(struct drm_i915_gem_object *obj,
87 				 const struct tile *tile,
88 				 struct rnd_state *prng)
89 {
90 	const unsigned long npages = obj->base.size / PAGE_SIZE;
91 	struct i915_ggtt_view view;
92 	struct i915_vma *vma;
93 	unsigned long page;
94 	u32 __iomem *io;
95 	struct page *p;
96 	unsigned int n;
97 	u64 offset;
98 	u32 *cpu;
99 	int err;
100 
101 	err = i915_gem_object_set_tiling(obj, tile->tiling, tile->stride);
102 	if (err) {
103 		pr_err("Failed to set tiling mode=%u, stride=%u, err=%d\n",
104 		       tile->tiling, tile->stride, err);
105 		return err;
106 	}
107 
108 	GEM_BUG_ON(i915_gem_object_get_tiling(obj) != tile->tiling);
109 	GEM_BUG_ON(i915_gem_object_get_stride(obj) != tile->stride);
110 
111 	i915_gem_object_lock(obj);
112 	err = i915_gem_object_set_to_gtt_domain(obj, true);
113 	i915_gem_object_unlock(obj);
114 	if (err) {
115 		pr_err("Failed to flush to GTT write domain; err=%d\n", err);
116 		return err;
117 	}
118 
119 	page = i915_prandom_u32_max_state(npages, prng);
120 	view = compute_partial_view(obj, page, MIN_CHUNK_PAGES);
121 
122 	vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
123 	if (IS_ERR(vma)) {
124 		pr_err("Failed to pin partial view: offset=%lu; err=%d\n",
125 		       page, (int)PTR_ERR(vma));
126 		return PTR_ERR(vma);
127 	}
128 
129 	n = page - view.partial.offset;
130 	GEM_BUG_ON(n >= view.partial.size);
131 
132 	io = i915_vma_pin_iomap(vma);
133 	i915_vma_unpin(vma);
134 	if (IS_ERR(io)) {
135 		pr_err("Failed to iomap partial view: offset=%lu; err=%d\n",
136 		       page, (int)PTR_ERR(io));
137 		err = PTR_ERR(io);
138 		goto out;
139 	}
140 
141 	iowrite32(page, io + n * PAGE_SIZE / sizeof(*io));
142 	i915_vma_unpin_iomap(vma);
143 
144 	offset = tiled_offset(tile, page << PAGE_SHIFT);
145 	if (offset >= obj->base.size)
146 		goto out;
147 
148 	intel_gt_flush_ggtt_writes(&to_i915(obj->base.dev)->gt);
149 
150 	p = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
151 	cpu = kmap(p) + offset_in_page(offset);
152 	drm_clflush_virt_range(cpu, sizeof(*cpu));
153 	if (*cpu != (u32)page) {
154 		pr_err("Partial view for %lu [%u] (offset=%llu, size=%u [%llu, row size %u], fence=%d, tiling=%d, stride=%d) misalignment, expected write to page (%llu + %u [0x%llx]) of 0x%x, found 0x%x\n",
155 		       page, n,
156 		       view.partial.offset,
157 		       view.partial.size,
158 		       vma->size >> PAGE_SHIFT,
159 		       tile->tiling ? tile_row_pages(obj) : 0,
160 		       vma->fence ? vma->fence->id : -1, tile->tiling, tile->stride,
161 		       offset >> PAGE_SHIFT,
162 		       (unsigned int)offset_in_page(offset),
163 		       offset,
164 		       (u32)page, *cpu);
165 		err = -EINVAL;
166 	}
167 	*cpu = 0;
168 	drm_clflush_virt_range(cpu, sizeof(*cpu));
169 	kunmap(p);
170 
171 out:
172 	__i915_vma_put(vma);
173 	return err;
174 }
175 
check_partial_mappings(struct drm_i915_gem_object * obj,const struct tile * tile,unsigned long end_time)176 static int check_partial_mappings(struct drm_i915_gem_object *obj,
177 				  const struct tile *tile,
178 				  unsigned long end_time)
179 {
180 	const unsigned int nreal = obj->scratch / PAGE_SIZE;
181 	const unsigned long npages = obj->base.size / PAGE_SIZE;
182 	struct i915_vma *vma;
183 	unsigned long page;
184 	int err;
185 
186 	err = i915_gem_object_set_tiling(obj, tile->tiling, tile->stride);
187 	if (err) {
188 		pr_err("Failed to set tiling mode=%u, stride=%u, err=%d\n",
189 		       tile->tiling, tile->stride, err);
190 		return err;
191 	}
192 
193 	GEM_BUG_ON(i915_gem_object_get_tiling(obj) != tile->tiling);
194 	GEM_BUG_ON(i915_gem_object_get_stride(obj) != tile->stride);
195 
196 	i915_gem_object_lock(obj);
197 	err = i915_gem_object_set_to_gtt_domain(obj, true);
198 	i915_gem_object_unlock(obj);
199 	if (err) {
200 		pr_err("Failed to flush to GTT write domain; err=%d\n", err);
201 		return err;
202 	}
203 
204 	for_each_prime_number_from(page, 1, npages) {
205 		struct i915_ggtt_view view =
206 			compute_partial_view(obj, page, MIN_CHUNK_PAGES);
207 		u32 __iomem *io;
208 		struct page *p;
209 		unsigned int n;
210 		u64 offset;
211 		u32 *cpu;
212 
213 		GEM_BUG_ON(view.partial.size > nreal);
214 		cond_resched();
215 
216 		vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, PIN_MAPPABLE);
217 		if (IS_ERR(vma)) {
218 			pr_err("Failed to pin partial view: offset=%lu; err=%d\n",
219 			       page, (int)PTR_ERR(vma));
220 			return PTR_ERR(vma);
221 		}
222 
223 		n = page - view.partial.offset;
224 		GEM_BUG_ON(n >= view.partial.size);
225 
226 		io = i915_vma_pin_iomap(vma);
227 		i915_vma_unpin(vma);
228 		if (IS_ERR(io)) {
229 			pr_err("Failed to iomap partial view: offset=%lu; err=%d\n",
230 			       page, (int)PTR_ERR(io));
231 			return PTR_ERR(io);
232 		}
233 
234 		iowrite32(page, io + n * PAGE_SIZE / sizeof(*io));
235 		i915_vma_unpin_iomap(vma);
236 
237 		offset = tiled_offset(tile, page << PAGE_SHIFT);
238 		if (offset >= obj->base.size)
239 			continue;
240 
241 		intel_gt_flush_ggtt_writes(&to_i915(obj->base.dev)->gt);
242 
243 		p = i915_gem_object_get_page(obj, offset >> PAGE_SHIFT);
244 		cpu = kmap(p) + offset_in_page(offset);
245 		drm_clflush_virt_range(cpu, sizeof(*cpu));
246 		if (*cpu != (u32)page) {
247 			pr_err("Partial view for %lu [%u] (offset=%llu, size=%u [%llu, row size %u], fence=%d, tiling=%d, stride=%d) misalignment, expected write to page (%llu + %u [0x%llx]) of 0x%x, found 0x%x\n",
248 			       page, n,
249 			       view.partial.offset,
250 			       view.partial.size,
251 			       vma->size >> PAGE_SHIFT,
252 			       tile->tiling ? tile_row_pages(obj) : 0,
253 			       vma->fence ? vma->fence->id : -1, tile->tiling, tile->stride,
254 			       offset >> PAGE_SHIFT,
255 			       (unsigned int)offset_in_page(offset),
256 			       offset,
257 			       (u32)page, *cpu);
258 			err = -EINVAL;
259 		}
260 		*cpu = 0;
261 		drm_clflush_virt_range(cpu, sizeof(*cpu));
262 		kunmap(p);
263 		if (err)
264 			return err;
265 
266 		__i915_vma_put(vma);
267 
268 		if (igt_timeout(end_time,
269 				"%s: timed out after tiling=%d stride=%d\n",
270 				__func__, tile->tiling, tile->stride))
271 			return -EINTR;
272 	}
273 
274 	return 0;
275 }
276 
277 static unsigned int
setup_tile_size(struct tile * tile,struct drm_i915_private * i915)278 setup_tile_size(struct tile *tile, struct drm_i915_private *i915)
279 {
280 	if (INTEL_GEN(i915) <= 2) {
281 		tile->height = 16;
282 		tile->width = 128;
283 		tile->size = 11;
284 	} else if (tile->tiling == I915_TILING_Y &&
285 		   HAS_128_BYTE_Y_TILING(i915)) {
286 		tile->height = 32;
287 		tile->width = 128;
288 		tile->size = 12;
289 	} else {
290 		tile->height = 8;
291 		tile->width = 512;
292 		tile->size = 12;
293 	}
294 
295 	if (INTEL_GEN(i915) < 4)
296 		return 8192 / tile->width;
297 	else if (INTEL_GEN(i915) < 7)
298 		return 128 * I965_FENCE_MAX_PITCH_VAL / tile->width;
299 	else
300 		return 128 * GEN7_FENCE_MAX_PITCH_VAL / tile->width;
301 }
302 
igt_partial_tiling(void * arg)303 static int igt_partial_tiling(void *arg)
304 {
305 	const unsigned int nreal = 1 << 12; /* largest tile row x2 */
306 	struct drm_i915_private *i915 = arg;
307 	struct drm_i915_gem_object *obj;
308 	intel_wakeref_t wakeref;
309 	int tiling;
310 	int err;
311 
312 	if (!i915_ggtt_has_aperture(&i915->ggtt))
313 		return 0;
314 
315 	/* We want to check the page mapping and fencing of a large object
316 	 * mmapped through the GTT. The object we create is larger than can
317 	 * possibly be mmaped as a whole, and so we must use partial GGTT vma.
318 	 * We then check that a write through each partial GGTT vma ends up
319 	 * in the right set of pages within the object, and with the expected
320 	 * tiling, which we verify by manual swizzling.
321 	 */
322 
323 	obj = huge_gem_object(i915,
324 			      nreal << PAGE_SHIFT,
325 			      (1 + next_prime_number(i915->ggtt.vm.total >> PAGE_SHIFT)) << PAGE_SHIFT);
326 	if (IS_ERR(obj))
327 		return PTR_ERR(obj);
328 
329 	err = i915_gem_object_pin_pages(obj);
330 	if (err) {
331 		pr_err("Failed to allocate %u pages (%lu total), err=%d\n",
332 		       nreal, obj->base.size / PAGE_SIZE, err);
333 		goto out;
334 	}
335 
336 	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
337 
338 	if (1) {
339 		IGT_TIMEOUT(end);
340 		struct tile tile;
341 
342 		tile.height = 1;
343 		tile.width = 1;
344 		tile.size = 0;
345 		tile.stride = 0;
346 		tile.swizzle = I915_BIT_6_SWIZZLE_NONE;
347 		tile.tiling = I915_TILING_NONE;
348 
349 		err = check_partial_mappings(obj, &tile, end);
350 		if (err && err != -EINTR)
351 			goto out_unlock;
352 	}
353 
354 	for (tiling = I915_TILING_X; tiling <= I915_TILING_Y; tiling++) {
355 		IGT_TIMEOUT(end);
356 		unsigned int max_pitch;
357 		unsigned int pitch;
358 		struct tile tile;
359 
360 		if (i915->quirks & QUIRK_PIN_SWIZZLED_PAGES)
361 			/*
362 			 * The swizzling pattern is actually unknown as it
363 			 * varies based on physical address of each page.
364 			 * See i915_gem_detect_bit_6_swizzle().
365 			 */
366 			break;
367 
368 		tile.tiling = tiling;
369 		switch (tiling) {
370 		case I915_TILING_X:
371 			tile.swizzle = i915->ggtt.bit_6_swizzle_x;
372 			break;
373 		case I915_TILING_Y:
374 			tile.swizzle = i915->ggtt.bit_6_swizzle_y;
375 			break;
376 		}
377 
378 		GEM_BUG_ON(tile.swizzle == I915_BIT_6_SWIZZLE_UNKNOWN);
379 		if (tile.swizzle == I915_BIT_6_SWIZZLE_9_17 ||
380 		    tile.swizzle == I915_BIT_6_SWIZZLE_9_10_17)
381 			continue;
382 
383 		max_pitch = setup_tile_size(&tile, i915);
384 
385 		for (pitch = max_pitch; pitch; pitch >>= 1) {
386 			tile.stride = tile.width * pitch;
387 			err = check_partial_mappings(obj, &tile, end);
388 			if (err == -EINTR)
389 				goto next_tiling;
390 			if (err)
391 				goto out_unlock;
392 
393 			if (pitch > 2 && INTEL_GEN(i915) >= 4) {
394 				tile.stride = tile.width * (pitch - 1);
395 				err = check_partial_mappings(obj, &tile, end);
396 				if (err == -EINTR)
397 					goto next_tiling;
398 				if (err)
399 					goto out_unlock;
400 			}
401 
402 			if (pitch < max_pitch && INTEL_GEN(i915) >= 4) {
403 				tile.stride = tile.width * (pitch + 1);
404 				err = check_partial_mappings(obj, &tile, end);
405 				if (err == -EINTR)
406 					goto next_tiling;
407 				if (err)
408 					goto out_unlock;
409 			}
410 		}
411 
412 		if (INTEL_GEN(i915) >= 4) {
413 			for_each_prime_number(pitch, max_pitch) {
414 				tile.stride = tile.width * pitch;
415 				err = check_partial_mappings(obj, &tile, end);
416 				if (err == -EINTR)
417 					goto next_tiling;
418 				if (err)
419 					goto out_unlock;
420 			}
421 		}
422 
423 next_tiling: ;
424 	}
425 
426 out_unlock:
427 	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
428 	i915_gem_object_unpin_pages(obj);
429 out:
430 	i915_gem_object_put(obj);
431 	return err;
432 }
433 
igt_smoke_tiling(void * arg)434 static int igt_smoke_tiling(void *arg)
435 {
436 	const unsigned int nreal = 1 << 12; /* largest tile row x2 */
437 	struct drm_i915_private *i915 = arg;
438 	struct drm_i915_gem_object *obj;
439 	intel_wakeref_t wakeref;
440 	I915_RND_STATE(prng);
441 	unsigned long count;
442 	IGT_TIMEOUT(end);
443 	int err;
444 
445 	if (!i915_ggtt_has_aperture(&i915->ggtt))
446 		return 0;
447 
448 	/*
449 	 * igt_partial_tiling() does an exhastive check of partial tiling
450 	 * chunking, but will undoubtably run out of time. Here, we do a
451 	 * randomised search and hope over many runs of 1s with different
452 	 * seeds we will do a thorough check.
453 	 *
454 	 * Remember to look at the st_seed if we see a flip-flop in BAT!
455 	 */
456 
457 	if (i915->quirks & QUIRK_PIN_SWIZZLED_PAGES)
458 		return 0;
459 
460 	obj = huge_gem_object(i915,
461 			      nreal << PAGE_SHIFT,
462 			      (1 + next_prime_number(i915->ggtt.vm.total >> PAGE_SHIFT)) << PAGE_SHIFT);
463 	if (IS_ERR(obj))
464 		return PTR_ERR(obj);
465 
466 	err = i915_gem_object_pin_pages(obj);
467 	if (err) {
468 		pr_err("Failed to allocate %u pages (%lu total), err=%d\n",
469 		       nreal, obj->base.size / PAGE_SIZE, err);
470 		goto out;
471 	}
472 
473 	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
474 
475 	count = 0;
476 	do {
477 		struct tile tile;
478 
479 		tile.tiling =
480 			i915_prandom_u32_max_state(I915_TILING_Y + 1, &prng);
481 		switch (tile.tiling) {
482 		case I915_TILING_NONE:
483 			tile.height = 1;
484 			tile.width = 1;
485 			tile.size = 0;
486 			tile.stride = 0;
487 			tile.swizzle = I915_BIT_6_SWIZZLE_NONE;
488 			break;
489 
490 		case I915_TILING_X:
491 			tile.swizzle = i915->ggtt.bit_6_swizzle_x;
492 			break;
493 		case I915_TILING_Y:
494 			tile.swizzle = i915->ggtt.bit_6_swizzle_y;
495 			break;
496 		}
497 
498 		if (tile.swizzle == I915_BIT_6_SWIZZLE_9_17 ||
499 		    tile.swizzle == I915_BIT_6_SWIZZLE_9_10_17)
500 			continue;
501 
502 		if (tile.tiling != I915_TILING_NONE) {
503 			unsigned int max_pitch = setup_tile_size(&tile, i915);
504 
505 			tile.stride =
506 				i915_prandom_u32_max_state(max_pitch, &prng);
507 			tile.stride = (1 + tile.stride) * tile.width;
508 			if (INTEL_GEN(i915) < 4)
509 				tile.stride = rounddown_pow_of_two(tile.stride);
510 		}
511 
512 		err = check_partial_mapping(obj, &tile, &prng);
513 		if (err)
514 			break;
515 
516 		count++;
517 	} while (!__igt_timeout(end, NULL));
518 
519 	pr_info("%s: Completed %lu trials\n", __func__, count);
520 
521 	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
522 	i915_gem_object_unpin_pages(obj);
523 out:
524 	i915_gem_object_put(obj);
525 	return err;
526 }
527 
make_obj_busy(struct drm_i915_gem_object * obj)528 static int make_obj_busy(struct drm_i915_gem_object *obj)
529 {
530 	struct drm_i915_private *i915 = to_i915(obj->base.dev);
531 	struct intel_engine_cs *engine;
532 
533 	for_each_uabi_engine(engine, i915) {
534 		struct i915_request *rq;
535 		struct i915_vma *vma;
536 		int err;
537 
538 		vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL);
539 		if (IS_ERR(vma))
540 			return PTR_ERR(vma);
541 
542 		err = i915_vma_pin(vma, 0, 0, PIN_USER);
543 		if (err)
544 			return err;
545 
546 		rq = intel_engine_create_kernel_request(engine);
547 		if (IS_ERR(rq)) {
548 			i915_vma_unpin(vma);
549 			return PTR_ERR(rq);
550 		}
551 
552 		i915_vma_lock(vma);
553 		err = i915_request_await_object(rq, vma->obj, true);
554 		if (err == 0)
555 			err = i915_vma_move_to_active(vma, rq,
556 						      EXEC_OBJECT_WRITE);
557 		i915_vma_unlock(vma);
558 
559 		i915_request_add(rq);
560 		i915_vma_unpin(vma);
561 		if (err)
562 			return err;
563 	}
564 
565 	i915_gem_object_put(obj); /* leave it only alive via its active ref */
566 	return 0;
567 }
568 
assert_mmap_offset(struct drm_i915_private * i915,unsigned long size,int expected)569 static bool assert_mmap_offset(struct drm_i915_private *i915,
570 			       unsigned long size,
571 			       int expected)
572 {
573 	struct drm_i915_gem_object *obj;
574 	struct i915_mmap_offset *mmo;
575 
576 	obj = i915_gem_object_create_internal(i915, size);
577 	if (IS_ERR(obj))
578 		return PTR_ERR(obj);
579 
580 	mmo = mmap_offset_attach(obj, I915_MMAP_OFFSET_GTT, NULL);
581 	i915_gem_object_put(obj);
582 
583 	return PTR_ERR_OR_ZERO(mmo) == expected;
584 }
585 
disable_retire_worker(struct drm_i915_private * i915)586 static void disable_retire_worker(struct drm_i915_private *i915)
587 {
588 	i915_gem_driver_unregister__shrinker(i915);
589 	intel_gt_pm_get(&i915->gt);
590 	cancel_delayed_work_sync(&i915->gt.requests.retire_work);
591 }
592 
restore_retire_worker(struct drm_i915_private * i915)593 static void restore_retire_worker(struct drm_i915_private *i915)
594 {
595 	igt_flush_test(i915);
596 	intel_gt_pm_put(&i915->gt);
597 	i915_gem_driver_register__shrinker(i915);
598 }
599 
mmap_offset_lock(struct drm_i915_private * i915)600 static void mmap_offset_lock(struct drm_i915_private *i915)
601 	__acquires(&i915->drm.vma_offset_manager->vm_lock)
602 {
603 	write_lock(&i915->drm.vma_offset_manager->vm_lock);
604 }
605 
mmap_offset_unlock(struct drm_i915_private * i915)606 static void mmap_offset_unlock(struct drm_i915_private *i915)
607 	__releases(&i915->drm.vma_offset_manager->vm_lock)
608 {
609 	write_unlock(&i915->drm.vma_offset_manager->vm_lock);
610 }
611 
igt_mmap_offset_exhaustion(void * arg)612 static int igt_mmap_offset_exhaustion(void *arg)
613 {
614 	struct drm_i915_private *i915 = arg;
615 	struct drm_mm *mm = &i915->drm.vma_offset_manager->vm_addr_space_mm;
616 	struct drm_i915_gem_object *obj;
617 	struct drm_mm_node *hole, *next;
618 	struct i915_mmap_offset *mmo;
619 	int loop, err = 0;
620 
621 	/* Disable background reaper */
622 	disable_retire_worker(i915);
623 	GEM_BUG_ON(!i915->gt.awake);
624 	intel_gt_retire_requests(&i915->gt);
625 	i915_gem_drain_freed_objects(i915);
626 
627 	/* Trim the device mmap space to only a page */
628 	mmap_offset_lock(i915);
629 	loop = 1; /* PAGE_SIZE units */
630 	list_for_each_entry_safe(hole, next, &mm->hole_stack, hole_stack) {
631 		struct drm_mm_node *resv;
632 
633 		resv = kzalloc(sizeof(*resv), GFP_NOWAIT);
634 		if (!resv) {
635 			err = -ENOMEM;
636 			goto out_park;
637 		}
638 
639 		resv->start = drm_mm_hole_node_start(hole) + loop;
640 		resv->size = hole->hole_size - loop;
641 		resv->color = -1ul;
642 		loop = 0;
643 
644 		if (!resv->size) {
645 			kfree(resv);
646 			continue;
647 		}
648 
649 		pr_debug("Reserving hole [%llx + %llx]\n",
650 			 resv->start, resv->size);
651 
652 		err = drm_mm_reserve_node(mm, resv);
653 		if (err) {
654 			pr_err("Failed to trim VMA manager, err=%d\n", err);
655 			kfree(resv);
656 			goto out_park;
657 		}
658 	}
659 	GEM_BUG_ON(!list_is_singular(&mm->hole_stack));
660 	mmap_offset_unlock(i915);
661 
662 	/* Just fits! */
663 	if (!assert_mmap_offset(i915, PAGE_SIZE, 0)) {
664 		pr_err("Unable to insert object into single page hole\n");
665 		err = -EINVAL;
666 		goto out;
667 	}
668 
669 	/* Too large */
670 	if (!assert_mmap_offset(i915, 2 * PAGE_SIZE, -ENOSPC)) {
671 		pr_err("Unexpectedly succeeded in inserting too large object into single page hole\n");
672 		err = -EINVAL;
673 		goto out;
674 	}
675 
676 	/* Fill the hole, further allocation attempts should then fail */
677 	obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
678 	if (IS_ERR(obj)) {
679 		err = PTR_ERR(obj);
680 		goto out;
681 	}
682 
683 	mmo = mmap_offset_attach(obj, I915_MMAP_OFFSET_GTT, NULL);
684 	if (IS_ERR(mmo)) {
685 		pr_err("Unable to insert object into reclaimed hole\n");
686 		err = PTR_ERR(mmo);
687 		goto err_obj;
688 	}
689 
690 	if (!assert_mmap_offset(i915, PAGE_SIZE, -ENOSPC)) {
691 		pr_err("Unexpectedly succeeded in inserting object into no holes!\n");
692 		err = -EINVAL;
693 		goto err_obj;
694 	}
695 
696 	i915_gem_object_put(obj);
697 
698 	/* Now fill with busy dead objects that we expect to reap */
699 	for (loop = 0; loop < 3; loop++) {
700 		if (intel_gt_is_wedged(&i915->gt))
701 			break;
702 
703 		obj = i915_gem_object_create_internal(i915, PAGE_SIZE);
704 		if (IS_ERR(obj)) {
705 			err = PTR_ERR(obj);
706 			goto out;
707 		}
708 
709 		err = make_obj_busy(obj);
710 		if (err) {
711 			pr_err("[loop %d] Failed to busy the object\n", loop);
712 			goto err_obj;
713 		}
714 	}
715 
716 out:
717 	mmap_offset_lock(i915);
718 out_park:
719 	drm_mm_for_each_node_safe(hole, next, mm) {
720 		if (hole->color != -1ul)
721 			continue;
722 
723 		drm_mm_remove_node(hole);
724 		kfree(hole);
725 	}
726 	mmap_offset_unlock(i915);
727 	restore_retire_worker(i915);
728 	return err;
729 err_obj:
730 	i915_gem_object_put(obj);
731 	goto out;
732 }
733 
gtt_set(struct drm_i915_gem_object * obj)734 static int gtt_set(struct drm_i915_gem_object *obj)
735 {
736 	struct i915_vma *vma;
737 	void __iomem *map;
738 	int err = 0;
739 
740 	vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
741 	if (IS_ERR(vma))
742 		return PTR_ERR(vma);
743 
744 	intel_gt_pm_get(vma->vm->gt);
745 	map = i915_vma_pin_iomap(vma);
746 	i915_vma_unpin(vma);
747 	if (IS_ERR(map)) {
748 		err = PTR_ERR(map);
749 		goto out;
750 	}
751 
752 	memset_io(map, POISON_INUSE, obj->base.size);
753 	i915_vma_unpin_iomap(vma);
754 
755 out:
756 	intel_gt_pm_put(vma->vm->gt);
757 	return err;
758 }
759 
gtt_check(struct drm_i915_gem_object * obj)760 static int gtt_check(struct drm_i915_gem_object *obj)
761 {
762 	struct i915_vma *vma;
763 	void __iomem *map;
764 	int err = 0;
765 
766 	vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, PIN_MAPPABLE);
767 	if (IS_ERR(vma))
768 		return PTR_ERR(vma);
769 
770 	intel_gt_pm_get(vma->vm->gt);
771 	map = i915_vma_pin_iomap(vma);
772 	i915_vma_unpin(vma);
773 	if (IS_ERR(map)) {
774 		err = PTR_ERR(map);
775 		goto out;
776 	}
777 
778 	if (memchr_inv((void __force *)map, POISON_FREE, obj->base.size)) {
779 		pr_err("%s: Write via mmap did not land in backing store (GTT)\n",
780 		       obj->mm.region->name);
781 		err = -EINVAL;
782 	}
783 	i915_vma_unpin_iomap(vma);
784 
785 out:
786 	intel_gt_pm_put(vma->vm->gt);
787 	return err;
788 }
789 
wc_set(struct drm_i915_gem_object * obj)790 static int wc_set(struct drm_i915_gem_object *obj)
791 {
792 	void *vaddr;
793 
794 	vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);
795 	if (IS_ERR(vaddr))
796 		return PTR_ERR(vaddr);
797 
798 	memset(vaddr, POISON_INUSE, obj->base.size);
799 	i915_gem_object_flush_map(obj);
800 	i915_gem_object_unpin_map(obj);
801 
802 	return 0;
803 }
804 
wc_check(struct drm_i915_gem_object * obj)805 static int wc_check(struct drm_i915_gem_object *obj)
806 {
807 	void *vaddr;
808 	int err = 0;
809 
810 	vaddr = i915_gem_object_pin_map(obj, I915_MAP_WC);
811 	if (IS_ERR(vaddr))
812 		return PTR_ERR(vaddr);
813 
814 	if (memchr_inv(vaddr, POISON_FREE, obj->base.size)) {
815 		pr_err("%s: Write via mmap did not land in backing store (WC)\n",
816 		       obj->mm.region->name);
817 		err = -EINVAL;
818 	}
819 	i915_gem_object_unpin_map(obj);
820 
821 	return err;
822 }
823 
can_mmap(struct drm_i915_gem_object * obj,enum i915_mmap_type type)824 static bool can_mmap(struct drm_i915_gem_object *obj, enum i915_mmap_type type)
825 {
826 	if (type == I915_MMAP_TYPE_GTT &&
827 	    !i915_ggtt_has_aperture(&to_i915(obj->base.dev)->ggtt))
828 		return false;
829 
830 	if (type != I915_MMAP_TYPE_GTT &&
831 	    !i915_gem_object_type_has(obj,
832 				      I915_GEM_OBJECT_HAS_STRUCT_PAGE |
833 				      I915_GEM_OBJECT_HAS_IOMEM))
834 		return false;
835 
836 	return true;
837 }
838 
839 #define expand32(x) (((x) << 0) | ((x) << 8) | ((x) << 16) | ((x) << 24))
__igt_mmap(struct drm_i915_private * i915,struct drm_i915_gem_object * obj,enum i915_mmap_type type)840 static int __igt_mmap(struct drm_i915_private *i915,
841 		      struct drm_i915_gem_object *obj,
842 		      enum i915_mmap_type type)
843 {
844 	struct i915_mmap_offset *mmo;
845 	struct vm_area_struct *area;
846 	unsigned long addr;
847 	int err, i;
848 
849 	if (!can_mmap(obj, type))
850 		return 0;
851 
852 	err = wc_set(obj);
853 	if (err == -ENXIO)
854 		err = gtt_set(obj);
855 	if (err)
856 		return err;
857 
858 	mmo = mmap_offset_attach(obj, type, NULL);
859 	if (IS_ERR(mmo))
860 		return PTR_ERR(mmo);
861 
862 	addr = igt_mmap_node(i915, &mmo->vma_node, 0, PROT_WRITE, MAP_SHARED);
863 	if (IS_ERR_VALUE(addr))
864 		return addr;
865 
866 	pr_debug("igt_mmap(%s, %d) @ %lx\n", obj->mm.region->name, type, addr);
867 
868 	area = find_vma(current->mm, addr);
869 	if (!area) {
870 		pr_err("%s: Did not create a vm_area_struct for the mmap\n",
871 		       obj->mm.region->name);
872 		err = -EINVAL;
873 		goto out_unmap;
874 	}
875 
876 	if (area->vm_private_data != mmo) {
877 		pr_err("%s: vm_area_struct did not point back to our mmap_offset object!\n",
878 		       obj->mm.region->name);
879 		err = -EINVAL;
880 		goto out_unmap;
881 	}
882 
883 	for (i = 0; i < obj->base.size / sizeof(u32); i++) {
884 		u32 __user *ux = u64_to_user_ptr((u64)(addr + i * sizeof(*ux)));
885 		u32 x;
886 
887 		if (get_user(x, ux)) {
888 			pr_err("%s: Unable to read from mmap, offset:%zd\n",
889 			       obj->mm.region->name, i * sizeof(x));
890 			err = -EFAULT;
891 			goto out_unmap;
892 		}
893 
894 		if (x != expand32(POISON_INUSE)) {
895 			pr_err("%s: Read incorrect value from mmap, offset:%zd, found:%x, expected:%x\n",
896 			       obj->mm.region->name,
897 			       i * sizeof(x), x, expand32(POISON_INUSE));
898 			err = -EINVAL;
899 			goto out_unmap;
900 		}
901 
902 		x = expand32(POISON_FREE);
903 		if (put_user(x, ux)) {
904 			pr_err("%s: Unable to write to mmap, offset:%zd\n",
905 			       obj->mm.region->name, i * sizeof(x));
906 			err = -EFAULT;
907 			goto out_unmap;
908 		}
909 	}
910 
911 	if (type == I915_MMAP_TYPE_GTT)
912 		intel_gt_flush_ggtt_writes(&i915->gt);
913 
914 	err = wc_check(obj);
915 	if (err == -ENXIO)
916 		err = gtt_check(obj);
917 out_unmap:
918 	vm_munmap(addr, obj->base.size);
919 	return err;
920 }
921 
igt_mmap(void * arg)922 static int igt_mmap(void *arg)
923 {
924 	struct drm_i915_private *i915 = arg;
925 	struct intel_memory_region *mr;
926 	enum intel_region_id id;
927 
928 	for_each_memory_region(mr, i915, id) {
929 		unsigned long sizes[] = {
930 			PAGE_SIZE,
931 			mr->min_page_size,
932 			SZ_4M,
933 		};
934 		int i;
935 
936 		for (i = 0; i < ARRAY_SIZE(sizes); i++) {
937 			struct drm_i915_gem_object *obj;
938 			int err;
939 
940 			obj = i915_gem_object_create_region(mr, sizes[i], 0);
941 			if (obj == ERR_PTR(-ENODEV))
942 				continue;
943 
944 			if (IS_ERR(obj))
945 				return PTR_ERR(obj);
946 
947 			err = __igt_mmap(i915, obj, I915_MMAP_TYPE_GTT);
948 			if (err == 0)
949 				err = __igt_mmap(i915, obj, I915_MMAP_TYPE_WC);
950 
951 			i915_gem_object_put(obj);
952 			if (err)
953 				return err;
954 		}
955 	}
956 
957 	return 0;
958 }
959 
__igt_mmap_gpu(struct drm_i915_private * i915,struct drm_i915_gem_object * obj,enum i915_mmap_type type)960 static int __igt_mmap_gpu(struct drm_i915_private *i915,
961 			  struct drm_i915_gem_object *obj,
962 			  enum i915_mmap_type type)
963 {
964 	struct intel_engine_cs *engine;
965 	struct i915_mmap_offset *mmo;
966 	unsigned long addr;
967 	u32 __user *ux;
968 	u32 bbe;
969 	int err;
970 
971 	/*
972 	 * Verify that the mmap access into the backing store aligns with
973 	 * that of the GPU, i.e. that mmap is indeed writing into the same
974 	 * page as being read by the GPU.
975 	 */
976 
977 	if (!can_mmap(obj, type))
978 		return 0;
979 
980 	err = wc_set(obj);
981 	if (err == -ENXIO)
982 		err = gtt_set(obj);
983 	if (err)
984 		return err;
985 
986 	mmo = mmap_offset_attach(obj, type, NULL);
987 	if (IS_ERR(mmo))
988 		return PTR_ERR(mmo);
989 
990 	addr = igt_mmap_node(i915, &mmo->vma_node, 0, PROT_WRITE, MAP_SHARED);
991 	if (IS_ERR_VALUE(addr))
992 		return addr;
993 
994 	ux = u64_to_user_ptr((u64)addr);
995 	bbe = MI_BATCH_BUFFER_END;
996 	if (put_user(bbe, ux)) {
997 		pr_err("%s: Unable to write to mmap\n", obj->mm.region->name);
998 		err = -EFAULT;
999 		goto out_unmap;
1000 	}
1001 
1002 	if (type == I915_MMAP_TYPE_GTT)
1003 		intel_gt_flush_ggtt_writes(&i915->gt);
1004 
1005 	for_each_uabi_engine(engine, i915) {
1006 		struct i915_request *rq;
1007 		struct i915_vma *vma;
1008 
1009 		vma = i915_vma_instance(obj, engine->kernel_context->vm, NULL);
1010 		if (IS_ERR(vma)) {
1011 			err = PTR_ERR(vma);
1012 			goto out_unmap;
1013 		}
1014 
1015 		err = i915_vma_pin(vma, 0, 0, PIN_USER);
1016 		if (err)
1017 			goto out_unmap;
1018 
1019 		rq = i915_request_create(engine->kernel_context);
1020 		if (IS_ERR(rq)) {
1021 			err = PTR_ERR(rq);
1022 			goto out_unpin;
1023 		}
1024 
1025 		i915_vma_lock(vma);
1026 		err = i915_request_await_object(rq, vma->obj, false);
1027 		if (err == 0)
1028 			err = i915_vma_move_to_active(vma, rq, 0);
1029 		i915_vma_unlock(vma);
1030 
1031 		err = engine->emit_bb_start(rq, vma->node.start, 0, 0);
1032 		i915_request_get(rq);
1033 		i915_request_add(rq);
1034 
1035 		if (i915_request_wait(rq, 0, HZ / 5) < 0) {
1036 			struct drm_printer p =
1037 				drm_info_printer(engine->i915->drm.dev);
1038 
1039 			pr_err("%s(%s, %s): Failed to execute batch\n",
1040 			       __func__, engine->name, obj->mm.region->name);
1041 			intel_engine_dump(engine, &p,
1042 					  "%s\n", engine->name);
1043 
1044 			intel_gt_set_wedged(engine->gt);
1045 			err = -EIO;
1046 		}
1047 		i915_request_put(rq);
1048 
1049 out_unpin:
1050 		i915_vma_unpin(vma);
1051 		if (err)
1052 			goto out_unmap;
1053 	}
1054 
1055 out_unmap:
1056 	vm_munmap(addr, obj->base.size);
1057 	return err;
1058 }
1059 
igt_mmap_gpu(void * arg)1060 static int igt_mmap_gpu(void *arg)
1061 {
1062 	struct drm_i915_private *i915 = arg;
1063 	struct intel_memory_region *mr;
1064 	enum intel_region_id id;
1065 
1066 	for_each_memory_region(mr, i915, id) {
1067 		struct drm_i915_gem_object *obj;
1068 		int err;
1069 
1070 		obj = i915_gem_object_create_region(mr, PAGE_SIZE, 0);
1071 		if (obj == ERR_PTR(-ENODEV))
1072 			continue;
1073 
1074 		if (IS_ERR(obj))
1075 			return PTR_ERR(obj);
1076 
1077 		err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_GTT);
1078 		if (err == 0)
1079 			err = __igt_mmap_gpu(i915, obj, I915_MMAP_TYPE_WC);
1080 
1081 		i915_gem_object_put(obj);
1082 		if (err)
1083 			return err;
1084 	}
1085 
1086 	return 0;
1087 }
1088 
check_present_pte(pte_t * pte,unsigned long addr,void * data)1089 static int check_present_pte(pte_t *pte, unsigned long addr, void *data)
1090 {
1091 	if (!pte_present(*pte) || pte_none(*pte)) {
1092 		pr_err("missing PTE:%lx\n",
1093 		       (addr - (unsigned long)data) >> PAGE_SHIFT);
1094 		return -EINVAL;
1095 	}
1096 
1097 	return 0;
1098 }
1099 
check_absent_pte(pte_t * pte,unsigned long addr,void * data)1100 static int check_absent_pte(pte_t *pte, unsigned long addr, void *data)
1101 {
1102 	if (pte_present(*pte) && !pte_none(*pte)) {
1103 		pr_err("present PTE:%lx; expected to be revoked\n",
1104 		       (addr - (unsigned long)data) >> PAGE_SHIFT);
1105 		return -EINVAL;
1106 	}
1107 
1108 	return 0;
1109 }
1110 
check_present(unsigned long addr,unsigned long len)1111 static int check_present(unsigned long addr, unsigned long len)
1112 {
1113 	return apply_to_page_range(current->mm, addr, len,
1114 				   check_present_pte, (void *)addr);
1115 }
1116 
check_absent(unsigned long addr,unsigned long len)1117 static int check_absent(unsigned long addr, unsigned long len)
1118 {
1119 	return apply_to_page_range(current->mm, addr, len,
1120 				   check_absent_pte, (void *)addr);
1121 }
1122 
prefault_range(u64 start,u64 len)1123 static int prefault_range(u64 start, u64 len)
1124 {
1125 	const char __user *addr, *end;
1126 	char __maybe_unused c;
1127 	int err;
1128 
1129 	addr = u64_to_user_ptr(start);
1130 	end = addr + len;
1131 
1132 	for (; addr < end; addr += PAGE_SIZE) {
1133 		err = __get_user(c, addr);
1134 		if (err)
1135 			return err;
1136 	}
1137 
1138 	return __get_user(c, end - 1);
1139 }
1140 
__igt_mmap_revoke(struct drm_i915_private * i915,struct drm_i915_gem_object * obj,enum i915_mmap_type type)1141 static int __igt_mmap_revoke(struct drm_i915_private *i915,
1142 			     struct drm_i915_gem_object *obj,
1143 			     enum i915_mmap_type type)
1144 {
1145 	struct i915_mmap_offset *mmo;
1146 	unsigned long addr;
1147 	int err;
1148 
1149 	if (!can_mmap(obj, type))
1150 		return 0;
1151 
1152 	mmo = mmap_offset_attach(obj, type, NULL);
1153 	if (IS_ERR(mmo))
1154 		return PTR_ERR(mmo);
1155 
1156 	addr = igt_mmap_node(i915, &mmo->vma_node, 0, PROT_WRITE, MAP_SHARED);
1157 	if (IS_ERR_VALUE(addr))
1158 		return addr;
1159 
1160 	err = prefault_range(addr, obj->base.size);
1161 	if (err)
1162 		goto out_unmap;
1163 
1164 	GEM_BUG_ON(mmo->mmap_type == I915_MMAP_TYPE_GTT &&
1165 		   !atomic_read(&obj->bind_count));
1166 
1167 	err = check_present(addr, obj->base.size);
1168 	if (err) {
1169 		pr_err("%s: was not present\n", obj->mm.region->name);
1170 		goto out_unmap;
1171 	}
1172 
1173 	/*
1174 	 * After unbinding the object from the GGTT, its address may be reused
1175 	 * for other objects. Ergo we have to revoke the previous mmap PTE
1176 	 * access as it no longer points to the same object.
1177 	 */
1178 	err = i915_gem_object_unbind(obj, I915_GEM_OBJECT_UNBIND_ACTIVE);
1179 	if (err) {
1180 		pr_err("Failed to unbind object!\n");
1181 		goto out_unmap;
1182 	}
1183 	GEM_BUG_ON(atomic_read(&obj->bind_count));
1184 
1185 	if (type != I915_MMAP_TYPE_GTT) {
1186 		__i915_gem_object_put_pages(obj);
1187 		if (i915_gem_object_has_pages(obj)) {
1188 			pr_err("Failed to put-pages object!\n");
1189 			err = -EINVAL;
1190 			goto out_unmap;
1191 		}
1192 	}
1193 
1194 	err = check_absent(addr, obj->base.size);
1195 	if (err) {
1196 		pr_err("%s: was not absent\n", obj->mm.region->name);
1197 		goto out_unmap;
1198 	}
1199 
1200 out_unmap:
1201 	vm_munmap(addr, obj->base.size);
1202 	return err;
1203 }
1204 
igt_mmap_revoke(void * arg)1205 static int igt_mmap_revoke(void *arg)
1206 {
1207 	struct drm_i915_private *i915 = arg;
1208 	struct intel_memory_region *mr;
1209 	enum intel_region_id id;
1210 
1211 	for_each_memory_region(mr, i915, id) {
1212 		struct drm_i915_gem_object *obj;
1213 		int err;
1214 
1215 		obj = i915_gem_object_create_region(mr, PAGE_SIZE, 0);
1216 		if (obj == ERR_PTR(-ENODEV))
1217 			continue;
1218 
1219 		if (IS_ERR(obj))
1220 			return PTR_ERR(obj);
1221 
1222 		err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_GTT);
1223 		if (err == 0)
1224 			err = __igt_mmap_revoke(i915, obj, I915_MMAP_TYPE_WC);
1225 
1226 		i915_gem_object_put(obj);
1227 		if (err)
1228 			return err;
1229 	}
1230 
1231 	return 0;
1232 }
1233 
i915_gem_mman_live_selftests(struct drm_i915_private * i915)1234 int i915_gem_mman_live_selftests(struct drm_i915_private *i915)
1235 {
1236 	static const struct i915_subtest tests[] = {
1237 		SUBTEST(igt_partial_tiling),
1238 		SUBTEST(igt_smoke_tiling),
1239 		SUBTEST(igt_mmap_offset_exhaustion),
1240 		SUBTEST(igt_mmap),
1241 		SUBTEST(igt_mmap_revoke),
1242 		SUBTEST(igt_mmap_gpu),
1243 	};
1244 
1245 	return i915_subtests(tests, i915);
1246 }
1247