From: Christoph Hellwig Date: Mon, 18 May 2026 05:17:58 +0000 (+0200) Subject: raid6_kunit: dynamically allocate data buffers using vmalloc X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d67c25712fe3c5d78fea03827771c49debb89c80;p=thirdparty%2Flinux.git raid6_kunit: dynamically allocate data buffers using vmalloc Use vmalloc for the data buffers instead of using static .data allocations. This provides for better out of bounds checking and avoids wasting kernel memory after the test has run. vmalloc is used instead of kmalloc to provide for better out of bounds access checking as in other kunit tests. Link: https://lore.kernel.org/20260518051804.462141-16-hch@lst.de Signed-off-by: Christoph Hellwig Acked-by: Ard Biesheuvel Tested-by: Ard Biesheuvel # kunit only on arm64 Cc: Albert Ou Cc: Alexander Gordeev Cc: Alexandre Ghiti Cc: Arnd Bergmann Cc: "Borislav Petkov (AMD)" Cc: Catalin Marinas Cc: Chris Mason Cc: Christian Borntraeger Cc: Dan Williams Cc: David Sterba Cc: Heiko Carstens Cc: Herbert Xu Cc: "H. Peter Anvin" Cc: Huacai Chen Cc: Ingo Molnar Cc: Li Nan Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nicholas Piggin Cc: Palmer Dabbelt Cc: Song Liu Cc: Sven Schnelle Cc: Vasily Gorbik Cc: WANG Xuerui Cc: Will Deacon Signed-off-by: Andrew Morton --- diff --git a/lib/raid/raid6/tests/raid6_kunit.c b/lib/raid/raid6/tests/raid6_kunit.c index 9d06ed9b90e4..72c78834df7f 100644 --- a/lib/raid/raid6/tests/raid6_kunit.c +++ b/lib/raid/raid6/tests/raid6_kunit.c @@ -7,19 +7,20 @@ #include #include +#include #include "../algos.h" MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); #define RAID6_KUNIT_SEED 42 +#define RAID6_KUNIT_MAX_FAILURES 2 #define NDISKS 16 /* Including P and Q */ static struct rnd_state rng; static void *dataptrs[NDISKS]; -static char data[NDISKS][PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); -static char recovi[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); -static char recovj[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); +static void *test_buffers[NDISKS]; +static void *test_recov_buffers[RAID6_KUNIT_MAX_FAILURES]; struct test_args { unsigned int recov_idx; @@ -35,8 +36,8 @@ static void makedata(int start, int stop) int i; for (i = start; i <= stop; i++) { - prandom_bytes_state(&rng, data[i], PAGE_SIZE); - dataptrs[i] = data[i]; + prandom_bytes_state(&rng, test_buffers[i], PAGE_SIZE); + dataptrs[i] = test_buffers[i]; } } @@ -55,12 +56,13 @@ static char member_type(int d) static void test_recover(struct kunit *test, int faila, int failb) { const struct test_args *ta = test->param_value; + int i; - memset(recovi, 0xf0, PAGE_SIZE); - memset(recovj, 0xba, PAGE_SIZE); + for (i = 0; i < RAID6_KUNIT_MAX_FAILURES; i++) + memset(test_recov_buffers[i], 0xf0, PAGE_SIZE); - dataptrs[faila] = recovi; - dataptrs[failb] = recovj; + dataptrs[faila] = test_recov_buffers[0]; + dataptrs[failb] = test_recov_buffers[1]; if (failb == NDISKS - 1) { /* @@ -80,18 +82,20 @@ static void test_recover(struct kunit *test, int faila, int failb) ta->recov->data2(NDISKS, PAGE_SIZE, faila, failb, dataptrs); } - KUNIT_EXPECT_MEMEQ_MSG(test, data[faila], recovi, PAGE_SIZE, + KUNIT_EXPECT_MEMEQ_MSG(test, test_buffers[faila], test_recov_buffers[0], + PAGE_SIZE, "faila miscompared: %3d[%c] (failb=%3d[%c])\n", faila, member_type(faila), failb, member_type(failb)); - KUNIT_EXPECT_MEMEQ_MSG(test, data[failb], recovj, PAGE_SIZE, + KUNIT_EXPECT_MEMEQ_MSG(test, test_buffers[failb], test_recov_buffers[1], + PAGE_SIZE, "failb miscompared: %3d[%c] (faila=%3d[%c])\n", failb, member_type(failb), faila, member_type(faila)); skip: - dataptrs[faila] = data[faila]; - dataptrs[failb] = data[failb]; + dataptrs[faila] = test_buffers[faila]; + dataptrs[failb] = test_buffers[failb]; } static void raid6_test(struct kunit *test) @@ -100,8 +104,8 @@ static void raid6_test(struct kunit *test) int i, j, p1, p2; /* Nuke syndromes */ - memset(data[NDISKS - 2], 0xee, PAGE_SIZE); - memset(data[NDISKS - 1], 0xee, PAGE_SIZE); + memset(test_buffers[NDISKS - 2], 0xee, PAGE_SIZE); + memset(test_buffers[NDISKS - 1], 0xee, PAGE_SIZE); /* Generate assumed good syndrome */ ta->gen->gen_syndrome(NDISKS, PAGE_SIZE, (void **)&dataptrs); @@ -161,15 +165,58 @@ static struct kunit_case raid6_test_cases[] = { static int raid6_suite_init(struct kunit_suite *suite) { + int i; + prandom_seed_state(&rng, RAID6_KUNIT_SEED); + + /* + * Allocate the test buffer using vmalloc() with a page-aligned length + * so that it is immediately followed by a guard page. This allows + * buffer overreads to be detected, even in assembly code. + */ + for (i = 0; i < RAID6_KUNIT_MAX_FAILURES; i++) { + test_recov_buffers[i] = vmalloc(PAGE_SIZE); + if (!test_recov_buffers[i]) + goto out_free_recov_buffers; + } + for (i = 0; i < NDISKS; i++) { + test_buffers[i] = vmalloc(PAGE_SIZE); + if (!test_buffers[i]) + goto out_free_buffers; + } + makedata(0, NDISKS - 1); + return 0; + +out_free_buffers: + for (i = 0; i < NDISKS; i++) + vfree(test_buffers[i]); + memset(test_buffers, 0, sizeof(test_buffers)); +out_free_recov_buffers: + for (i = 0; i < RAID6_KUNIT_MAX_FAILURES; i++) + vfree(test_recov_buffers[i]); + memset(test_recov_buffers, 0, sizeof(test_recov_buffers)); + return -ENOMEM; +} + +static void raid6_suite_exit(struct kunit_suite *suite) +{ + int i; + + for (i = 0; i < NDISKS; i++) + vfree(test_buffers[i]); + memset(test_buffers, 0, sizeof(test_buffers)); + for (i = 0; i < RAID6_KUNIT_MAX_FAILURES; i++) + vfree(test_recov_buffers[i]); + memset(test_recov_buffers, 0, sizeof(test_recov_buffers)); } static struct kunit_suite raid6_test_suite = { .name = "raid6", .test_cases = raid6_test_cases, .suite_init = raid6_suite_init, + .suite_exit = raid6_suite_exit, }; kunit_test_suite(raid6_test_suite);