Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

list: add kunit test for private list primitives

Add a KUnit test suite for the new private list primitives.

The test defines a struct with a __private list_head and exercises every
macro defined in <linux/list_private.h>.

This ensures that the macros correctly handle the ACCESS_PRIVATE()
abstraction and compile without warnings when acting on private members,
verifying that qualifiers are stripped and offsets are calculated
correctly.

Link: https://lkml.kernel.org/r/20251218155752.3045808-3-pasha.tatashin@soleen.com
Signed-off-by: Pasha Tatashin <pasha.tatashin@soleen.com>
Reviewed-by: David Gow <davidgow@google.com>
Cc: Alexander Graf <graf@amazon.com>
Cc: David Matlack <dmatlack@google.com>
Cc: David Rientjes <rientjes@google.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <kees@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Petr Mladek <pmladek@suse.com>
Cc: Pratyush Yadav <pratyush@kernel.org>
Cc: Samiullah Khawaja <skhawaja@google.com>
Cc: Tamir Duberstein <tamird@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Pasha Tatashin and committed by
Andrew Morton
66bd8501 989b3c5a

+91
+14
lib/Kconfig.debug
··· 2786 2786 2787 2787 If unsure, say N. 2788 2788 2789 + config LIST_PRIVATE_KUNIT_TEST 2790 + tristate "KUnit Test for Kernel Private Linked-list structures" if !KUNIT_ALL_TESTS 2791 + depends on KUNIT 2792 + default KUNIT_ALL_TESTS 2793 + help 2794 + This builds the KUnit test for the private linked-list primitives 2795 + defined in include/linux/list_private.h. 2796 + 2797 + These primitives allow manipulation of list_head members that are 2798 + marked as private and require special accessors (ACCESS_PRIVATE) 2799 + to strip qualifiers or handle encapsulation. 2800 + 2801 + If unsure, say N. 2802 + 2789 2803 config HASHTABLE_KUNIT_TEST 2790 2804 tristate "KUnit Test for Kernel Hashtable structures" if !KUNIT_ALL_TESTS 2791 2805 depends on KUNIT
+1
lib/tests/Makefile
··· 26 26 obj-$(CONFIG_IS_SIGNED_TYPE_KUNIT_TEST) += is_signed_type_kunit.o 27 27 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o 28 28 obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o 29 + obj-$(CONFIG_LIST_PRIVATE_KUNIT_TEST) += list-private-test.o 29 30 obj-$(CONFIG_KFIFO_KUNIT_TEST) += kfifo_kunit.o 30 31 obj-$(CONFIG_TEST_LIST_SORT) += test_list_sort.o 31 32 obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
+76
lib/tests/list-private-test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * KUnit compilation/smoke test for Private list primitives. 4 + * 5 + * Copyright (c) 2025, Google LLC. 6 + * Pasha Tatashin <pasha.tatashin@soleen.com> 7 + */ 8 + #include <linux/list_private.h> 9 + #include <kunit/test.h> 10 + 11 + /* 12 + * This forces compiler to warn if you access it directly, because list 13 + * primitives expect (struct list_head *), not (volatile struct list_head *). 14 + */ 15 + #undef __private 16 + #define __private volatile 17 + 18 + /* Redefine ACCESS_PRIVATE for this test. */ 19 + #undef ACCESS_PRIVATE 20 + #define ACCESS_PRIVATE(p, member) \ 21 + (*((struct list_head *)((unsigned long)&((p)->member)))) 22 + 23 + struct list_test_struct { 24 + int data; 25 + struct list_head __private list; 26 + }; 27 + 28 + static void list_private_compile_test(struct kunit *test) 29 + { 30 + struct list_test_struct entry; 31 + struct list_test_struct *pos, *n; 32 + LIST_HEAD(head); 33 + 34 + INIT_LIST_HEAD(&ACCESS_PRIVATE(&entry, list)); 35 + list_add(&ACCESS_PRIVATE(&entry, list), &head); 36 + pos = &entry; 37 + 38 + pos = list_private_entry(&ACCESS_PRIVATE(&entry, list), struct list_test_struct, list); 39 + pos = list_private_first_entry(&head, struct list_test_struct, list); 40 + pos = list_private_last_entry(&head, struct list_test_struct, list); 41 + pos = list_private_next_entry(pos, list); 42 + pos = list_private_prev_entry(pos, list); 43 + pos = list_private_next_entry_circular(pos, &head, list); 44 + pos = list_private_prev_entry_circular(pos, &head, list); 45 + 46 + if (list_private_entry_is_head(pos, &head, list)) 47 + return; 48 + 49 + list_private_for_each_entry(pos, &head, list) { } 50 + list_private_for_each_entry_reverse(pos, &head, list) { } 51 + list_private_for_each_entry_continue(pos, &head, list) { } 52 + list_private_for_each_entry_continue_reverse(pos, &head, list) { } 53 + list_private_for_each_entry_from(pos, &head, list) { } 54 + list_private_for_each_entry_from_reverse(pos, &head, list) { } 55 + 56 + list_private_for_each_entry_safe(pos, n, &head, list) 57 + list_private_safe_reset_next(pos, n, list); 58 + list_private_for_each_entry_safe_continue(pos, n, &head, list) { } 59 + list_private_for_each_entry_safe_from(pos, n, &head, list) { } 60 + list_private_for_each_entry_safe_reverse(pos, n, &head, list) { } 61 + } 62 + 63 + static struct kunit_case list_private_test_cases[] = { 64 + KUNIT_CASE(list_private_compile_test), 65 + {}, 66 + }; 67 + 68 + static struct kunit_suite list_private_test_module = { 69 + .name = "list-private-kunit-test", 70 + .test_cases = list_private_test_cases, 71 + }; 72 + 73 + kunit_test_suite(list_private_test_module); 74 + 75 + MODULE_DESCRIPTION("KUnit compilation test for private list primitives"); 76 + MODULE_LICENSE("GPL");