From: Kees Cook <kees@kernel.org>
To: linux-arch@vger.kernel.org
Cc: Kees Cook <kees@kernel.org>,
linux-kernel@vger.kernel.org, x86@kernel.org,
linux-alpha@vger.kernel.org, linux-csky@vger.kernel.org,
linux-hexagon@vger.kernel.org, linux-m68k@lists.linux-m68k.org,
linux-mips@vger.kernel.org, linux-openrisc@vger.kernel.org,
linux-parisc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org,
linux-sh@vger.kernel.org, sparclinux@vger.kernel.org,
llvm@lists.linux.dev, linux-hardening@vger.kernel.org
Subject: [PATCH 17/17] KUnit: ffs: Validate all the __attribute_const__ annotations
Date: Mon, 4 Aug 2025 09:44:13 -0700 [thread overview]
Message-ID: <20250804164417.1612371-17-kees@kernel.org> (raw)
In-Reply-To: <20250804163910.work.929-kees@kernel.org>
While tracking down a problem where constant expressions used by
BUILD_BUG_ON() suddenly stopped working[1], we found that an added static
initializer was convincing the compiler that it couldn't track the state
of the prior statically initialized value. Tracing this down found that
ffs() was used in the initializer macro, but since it wasn't marked with
__attribute_const__, the compiler had to assume the function might
change variable states as a side-effect (which is not true for ffs(),
which provides deterministic math results).
Validate all the __attibute_const__ annotations were found for all
architectures by reproducing the specific problem encountered in the
original bug report.
Build and run tested with everything I could reach with KUnit:
$ ./tools/testing/kunit/kunit.py run --arch=x86_64 ffs
$ ./tools/testing/kunit/kunit.py run --arch=i386 ffs
$ ./tools/testing/kunit/kunit.py run --arch=arm64 --make_options "CROSS_COMPILE=aarch64-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=arm --make_options "CROSS_COMPILE=arm-linux-gnueabi-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=powerpc ffs
$ ./tools/testing/kunit/kunit.py run --arch=powerpc32 ffs
$ ./tools/testing/kunit/kunit.py run --arch=powerpcle ffs
$ ./tools/testing/kunit/kunit.py run --arch=m68k ffs
$ ./tools/testing/kunit/kunit.py run --arch=loongarch ffs
$ ./tools/testing/kunit/kunit.py run --arch=s390 --make_options "CROSS_COMPILE=s390x-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=riscv --make_options "CROSS_COMPILE=riscv64-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=riscv32 --make_options "CROSS_COMPILE=riscv64-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=sparc --make_options "CROSS_COMPILE=sparc64-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=sparc64 --make_options "CROSS_COMPILE=sparc64-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=alpha --make_options "CROSS_COMPILE=alpha-linux-gnu-" ffs
$ ./tools/testing/kunit/kunit.py run --arch=sh --make_options "CROSS_COMPILE=sh4-linux-gnu-" ffs
Closes: https://github.com/KSPP/linux/issues/364
Signed-off-by: Kees Cook <kees@kernel.org>
---
lib/tests/ffs_kunit.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/lib/tests/ffs_kunit.c b/lib/tests/ffs_kunit.c
index ed11456b116e..9a329cdc09c2 100644
--- a/lib/tests/ffs_kunit.c
+++ b/lib/tests/ffs_kunit.c
@@ -496,6 +496,46 @@ static void ffz_edge_cases_test(struct kunit *test)
}
}
+/*
+ * To have useful build error output, split the tests into separate
+ * functions so it's clear which are missing __attribute_const__.
+ */
+#define CREATE_WRAPPER(func) \
+static noinline bool build_test_##func(void) \
+{ \
+ int init_##func = 32; \
+ int result_##func = func(6); \
+ \
+ /* Does the static initializer vanish after calling func? */ \
+ BUILD_BUG_ON(init_##func < 32); \
+ \
+ /* "Consume" the results so optimizer doesn't drop them. */ \
+ barrier_data(&init_##func); \
+ barrier_data(&result_##func); \
+ \
+ return true; \
+}
+CREATE_WRAPPER(ffs)
+CREATE_WRAPPER(fls)
+CREATE_WRAPPER(__ffs)
+CREATE_WRAPPER(__fls)
+CREATE_WRAPPER(ffz)
+#undef CREATE_WRAPPER
+
+/*
+ * Make sure that __attribute_const__ has be applied to all the
+ * functions. This is a regression test for:
+ * https://github.com/KSPP/linux/issues/364
+ */
+static void ffs_attribute_const_test(struct kunit *test)
+{
+ KUNIT_EXPECT_TRUE(test, build_test_ffs());
+ KUNIT_EXPECT_TRUE(test, build_test_fls());
+ KUNIT_EXPECT_TRUE(test, build_test___ffs());
+ KUNIT_EXPECT_TRUE(test, build_test___fls());
+ KUNIT_EXPECT_TRUE(test, build_test_ffz());
+}
+
/*
* KUnit test case definitions
*/
--
2.34.1
next prev parent reply other threads:[~2025-08-04 16:44 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-04 16:43 [PATCH 00/17] Add __attribute_const__ to ffs()-family implementations Kees Cook
2025-08-04 16:43 ` [PATCH 01/17] KUnit: Introduce ffs()-family tests Kees Cook
2025-08-04 16:43 ` [PATCH 02/17] bitops: Add __attribute_const__ to generic ffs()-family implementations Kees Cook
2025-08-04 16:43 ` [PATCH 03/17] csky: Add __attribute_const__ to " Kees Cook
2025-08-04 16:44 ` [PATCH 04/17] x86: " Kees Cook
2025-08-04 16:44 ` [PATCH 05/17] powerpc: " Kees Cook
2025-08-07 9:46 ` Madhavan Srinivasan
2025-08-15 16:34 ` Segher Boessenkool
2025-08-15 16:41 ` Segher Boessenkool
2025-08-04 16:44 ` [PATCH 06/17] sh: " Kees Cook
2025-08-04 16:44 ` [PATCH 07/17] alpha: " Kees Cook
2025-08-04 16:44 ` [PATCH 08/17] hexagon: " Kees Cook
2025-08-04 16:44 ` [PATCH 09/17] riscv: " Kees Cook
2025-08-07 14:43 ` Alexandre Ghiti
2025-08-04 16:44 ` [PATCH 10/17] openrisc: " Kees Cook
2025-08-04 17:15 ` Stafford Horne
2025-08-04 16:44 ` [PATCH 11/17] m68k: " Kees Cook
2025-08-05 8:12 ` Geert Uytterhoeven
2025-08-04 16:44 ` [PATCH 12/17] mips: " Kees Cook
2025-08-04 16:44 ` [PATCH 13/17] parisc: " Kees Cook
2025-08-04 16:44 ` [PATCH 14/17] s390: " Kees Cook
2025-08-06 10:33 ` Heiko Carstens
2025-08-04 16:44 ` [PATCH 15/17] xtensa: " Kees Cook
2025-08-04 16:44 ` [PATCH 16/17] sparc: " Kees Cook
2025-08-04 16:44 ` Kees Cook [this message]
2025-08-15 14:16 ` [PATCH 00/17] " Peter Zijlstra
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250804164417.1612371-17-kees@kernel.org \
--to=kees@kernel.org \
--cc=linux-alpha@vger.kernel.org \
--cc=linux-arch@vger.kernel.org \
--cc=linux-csky@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-hexagon@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-m68k@lists.linux-m68k.org \
--cc=linux-mips@vger.kernel.org \
--cc=linux-openrisc@vger.kernel.org \
--cc=linux-parisc@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-s390@vger.kernel.org \
--cc=linux-sh@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=llvm@lists.linux.dev \
--cc=sparclinux@vger.kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).