From: Dave Airlie <airlied@redhat.com>
Date: Fri, 1 Mar 2024 03:12:32 +0000 (+1000)
Subject: Merge tag 'drm-misc-fixes-2024-02-29' of https://anongit.freedesktop.org/git/drm... 
X-Git-Tag: v6.8-rc7~23^2~5
X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=45046af3d0c2d6f4f1953f7f07cd1b34ffc86498;p=users%2Fdwmw2%2Flinux.git

Merge tag 'drm-misc-fixes-2024-02-29' of https://anongit.freedesktop.org/git/drm/drm-misc into drm-fixes

A reset fix for host1x, a resource leak fix and a probe fix for aux-hpd,
a use-after-free fix and a boot fix for a pmic_glink qcom driver in
drivers/soc, a fix for the simpledrm/tegra transition, a kunit fix for
the TTM tests, a font handling fix for fbcon, two allocation fixes and a
kunit test to cover them for drm/buddy

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240229-angelic-adorable-teal-fbfabb@houat
---

45046af3d0c2d6f4f1953f7f07cd1b34ffc86498
diff --cc drivers/gpu/drm/tests/drm_buddy_test.c
index 2f32fb2f12e7c,1008d5b9d61e4..be2d9d7764be6
--- a/drivers/gpu/drm/tests/drm_buddy_test.c
+++ b/drivers/gpu/drm/tests/drm_buddy_test.c
@@@ -19,10 -21,212 +21,213 @@@ static inline u64 get_size(int order, u
  	return (1 << order) * chunk_size;
  }
  
+ static void drm_test_buddy_alloc_range_bias(struct kunit *test)
+ {
+ 	u32 mm_size, ps, bias_size, bias_start, bias_end, bias_rem;
+ 	DRM_RND_STATE(prng, random_seed);
+ 	unsigned int i, count, *order;
+ 	struct drm_buddy mm;
+ 	LIST_HEAD(allocated);
+ 
+ 	bias_size = SZ_1M;
+ 	ps = roundup_pow_of_two(prandom_u32_state(&prng) % bias_size);
+ 	ps = max(SZ_4K, ps);
+ 	mm_size = (SZ_8M-1) & ~(ps-1); /* Multiple roots */
+ 
+ 	kunit_info(test, "mm_size=%u, ps=%u\n", mm_size, ps);
+ 
+ 	KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, ps),
+ 			       "buddy_init failed\n");
+ 
+ 	count = mm_size / bias_size;
+ 	order = drm_random_order(count, &prng);
+ 	KUNIT_EXPECT_TRUE(test, order);
+ 
+ 	/*
+ 	 * Idea is to split the address space into uniform bias ranges, and then
+ 	 * in some random order allocate within each bias, using various
+ 	 * patterns within. This should detect if allocations leak out from a
+ 	 * given bias, for example.
+ 	 */
+ 
+ 	for (i = 0; i < count; i++) {
+ 		LIST_HEAD(tmp);
+ 		u32 size;
+ 
+ 		bias_start = order[i] * bias_size;
+ 		bias_end = bias_start + bias_size;
+ 		bias_rem = bias_size;
+ 
+ 		/* internal round_up too big */
+ 		KUNIT_ASSERT_TRUE_MSG(test,
+ 				      drm_buddy_alloc_blocks(&mm, bias_start,
+ 							     bias_end, bias_size + ps, bias_size,
+ 							     &allocated,
+ 							     DRM_BUDDY_RANGE_ALLOCATION),
+ 				      "buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
+ 				      bias_start, bias_end, bias_size, bias_size);
+ 
+ 		/* size too big */
+ 		KUNIT_ASSERT_TRUE_MSG(test,
+ 				      drm_buddy_alloc_blocks(&mm, bias_start,
+ 							     bias_end, bias_size + ps, ps,
+ 							     &allocated,
+ 							     DRM_BUDDY_RANGE_ALLOCATION),
+ 				      "buddy_alloc didn't fail with bias(%x-%x), size=%u, ps=%u\n",
+ 				      bias_start, bias_end, bias_size + ps, ps);
+ 
+ 		/* bias range too small for size */
+ 		KUNIT_ASSERT_TRUE_MSG(test,
+ 				      drm_buddy_alloc_blocks(&mm, bias_start + ps,
+ 							     bias_end, bias_size, ps,
+ 							     &allocated,
+ 							     DRM_BUDDY_RANGE_ALLOCATION),
+ 				      "buddy_alloc didn't fail with bias(%x-%x), size=%u, ps=%u\n",
+ 				      bias_start + ps, bias_end, bias_size, ps);
+ 
+ 		/* bias misaligned */
+ 		KUNIT_ASSERT_TRUE_MSG(test,
+ 				      drm_buddy_alloc_blocks(&mm, bias_start + ps,
+ 							     bias_end - ps,
+ 							     bias_size >> 1, bias_size >> 1,
+ 							     &allocated,
+ 							     DRM_BUDDY_RANGE_ALLOCATION),
+ 				      "buddy_alloc h didn't fail with bias(%x-%x), size=%u, ps=%u\n",
+ 				      bias_start + ps, bias_end - ps, bias_size >> 1, bias_size >> 1);
+ 
+ 		/* single big page */
+ 		KUNIT_ASSERT_FALSE_MSG(test,
+ 				       drm_buddy_alloc_blocks(&mm, bias_start,
+ 							      bias_end, bias_size, bias_size,
+ 							      &tmp,
+ 							      DRM_BUDDY_RANGE_ALLOCATION),
+ 				       "buddy_alloc i failed with bias(%x-%x), size=%u, ps=%u\n",
+ 				       bias_start, bias_end, bias_size, bias_size);
+ 		drm_buddy_free_list(&mm, &tmp);
+ 
+ 		/* single page with internal round_up */
+ 		KUNIT_ASSERT_FALSE_MSG(test,
+ 				       drm_buddy_alloc_blocks(&mm, bias_start,
+ 							      bias_end, ps, bias_size,
+ 							      &tmp,
+ 							      DRM_BUDDY_RANGE_ALLOCATION),
+ 				       "buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
+ 				       bias_start, bias_end, ps, bias_size);
+ 		drm_buddy_free_list(&mm, &tmp);
+ 
+ 		/* random size within */
+ 		size = max(round_up(prandom_u32_state(&prng) % bias_rem, ps), ps);
+ 		if (size)
+ 			KUNIT_ASSERT_FALSE_MSG(test,
+ 					       drm_buddy_alloc_blocks(&mm, bias_start,
+ 								      bias_end, size, ps,
+ 								      &tmp,
+ 								      DRM_BUDDY_RANGE_ALLOCATION),
+ 					       "buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
+ 					       bias_start, bias_end, size, ps);
+ 
+ 		bias_rem -= size;
+ 		/* too big for current avail */
+ 		KUNIT_ASSERT_TRUE_MSG(test,
+ 				      drm_buddy_alloc_blocks(&mm, bias_start,
+ 							     bias_end, bias_rem + ps, ps,
+ 							     &allocated,
+ 							     DRM_BUDDY_RANGE_ALLOCATION),
+ 				      "buddy_alloc didn't fail with bias(%x-%x), size=%u, ps=%u\n",
+ 				      bias_start, bias_end, bias_rem + ps, ps);
+ 
+ 		if (bias_rem) {
+ 			/* random fill of the remainder */
+ 			size = max(round_up(prandom_u32_state(&prng) % bias_rem, ps), ps);
+ 			size = max(size, ps);
+ 
+ 			KUNIT_ASSERT_FALSE_MSG(test,
+ 					       drm_buddy_alloc_blocks(&mm, bias_start,
+ 								      bias_end, size, ps,
+ 								      &allocated,
+ 								      DRM_BUDDY_RANGE_ALLOCATION),
+ 					       "buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
+ 					       bias_start, bias_end, size, ps);
+ 			/*
+ 			 * Intentionally allow some space to be left
+ 			 * unallocated, and ideally not always on the bias
+ 			 * boundaries.
+ 			 */
+ 			drm_buddy_free_list(&mm, &tmp);
+ 		} else {
+ 			list_splice_tail(&tmp, &allocated);
+ 		}
+ 	}
+ 
+ 	kfree(order);
+ 	drm_buddy_free_list(&mm, &allocated);
+ 	drm_buddy_fini(&mm);
+ 
+ 	/*
+ 	 * Something more free-form. Idea is to pick a random starting bias
+ 	 * range within the address space and then start filling it up. Also
+ 	 * randomly grow the bias range in both directions as we go along. This
+ 	 * should give us bias start/end which is not always uniform like above,
+ 	 * and in some cases will require the allocator to jump over already
+ 	 * allocated nodes in the middle of the address space.
+ 	 */
+ 
+ 	KUNIT_ASSERT_FALSE_MSG(test, drm_buddy_init(&mm, mm_size, ps),
+ 			       "buddy_init failed\n");
+ 
+ 	bias_start = round_up(prandom_u32_state(&prng) % (mm_size - ps), ps);
+ 	bias_end = round_up(bias_start + prandom_u32_state(&prng) % (mm_size - bias_start), ps);
+ 	bias_end = max(bias_end, bias_start + ps);
+ 	bias_rem = bias_end - bias_start;
+ 
+ 	do {
+ 		u32 size = max(round_up(prandom_u32_state(&prng) % bias_rem, ps), ps);
+ 
+ 		KUNIT_ASSERT_FALSE_MSG(test,
+ 				       drm_buddy_alloc_blocks(&mm, bias_start,
+ 							      bias_end, size, ps,
+ 							      &allocated,
+ 							      DRM_BUDDY_RANGE_ALLOCATION),
+ 				       "buddy_alloc failed with bias(%x-%x), size=%u, ps=%u\n",
+ 				       bias_start, bias_end, size);
+ 		bias_rem -= size;
+ 
+ 		/*
+ 		 * Try to randomly grow the bias range in both directions, or
+ 		 * only one, or perhaps don't grow at all.
+ 		 */
+ 		do {
+ 			u32 old_bias_start = bias_start;
+ 			u32 old_bias_end = bias_end;
+ 
+ 			if (bias_start)
+ 				bias_start -= round_up(prandom_u32_state(&prng) % bias_start, ps);
+ 			if (bias_end != mm_size)
+ 				bias_end += round_up(prandom_u32_state(&prng) % (mm_size - bias_end), ps);
+ 
+ 			bias_rem += old_bias_start - bias_start;
+ 			bias_rem += bias_end - old_bias_end;
+ 		} while (!bias_rem && (bias_start || bias_end != mm_size));
+ 	} while (bias_rem);
+ 
+ 	KUNIT_ASSERT_EQ(test, bias_start, 0);
+ 	KUNIT_ASSERT_EQ(test, bias_end, mm_size);
+ 	KUNIT_ASSERT_TRUE_MSG(test,
+ 			      drm_buddy_alloc_blocks(&mm, bias_start, bias_end,
+ 						     ps, ps,
+ 						     &allocated,
+ 						     DRM_BUDDY_RANGE_ALLOCATION),
+ 			      "buddy_alloc passed with bias(%x-%x), size=%u\n",
+ 			      bias_start, bias_end, ps);
+ 
+ 	drm_buddy_free_list(&mm, &allocated);
+ 	drm_buddy_fini(&mm);
+ }
+ 
  static void drm_test_buddy_alloc_contiguous(struct kunit *test)
  {
 -	u32 mm_size, ps = SZ_4K, i, n_pages, total;
 +	const unsigned long ps = SZ_4K, mm_size = 16 * 3 * SZ_4K;
 +	unsigned long i, n_pages, total;
  	struct drm_buddy_block *block;
  	struct drm_buddy mm;
  	LIST_HEAD(left);