From nobody Sat Sep 26 14:39:24 2026 Received: from out-2z4y-a139.jellyfish.systems (out-2z4y-a139.jellyfish.systems [198.54.127.139]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BFB1449B3F for ; Mon, 31 Aug 2026 16:27:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.54.127.139 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788193628; cv=none; b=Bq9f/Q4Lu5o2Gxsh0bej6GomdylAthWQQ+/+Neqd5FtZm1ozTysGo5nOOmeB8LWzS6KFd5j3zr5KKkh1icly0XPeN6onwpi7nTbWYOVzHb2qnC499k2j/OyuOexWZ5wTTst9LZ5UB4Aj/4JXDwhF2GAjeCKG1IAmVhnWxnAErt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788193628; c=relaxed/simple; bh=u0ZYjtGavKENeI/zuz5EwiNMeDpPPUy2TMwMLV6oW/Q=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ZYTdYf6NbAVYmna/lMs+YZwxtSnfrFVIxOHXaikDqYRoH4k9qewZM3kmKFScsY0IC+gtuV4E3JGrFwGf6kL8S6AZpWnhRTiYxZzbidc/C21RmYW8mOXzW9P0pPrhMa0lHpEP42c9cHUptcu2K+YKVp82LUMoHH2bhqjtUPC0KfI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gurudas.dev; spf=pass smtp.mailfrom=gurudas.dev; dkim=pass (2048-bit key) header.d=gurudas.dev header.i=@gurudas.dev header.b=bchoTgCq; arc=none smtp.client-ip=198.54.127.139 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gurudas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gurudas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gurudas.dev header.i=@gurudas.dev header.b="bchoTgCq" Received: from [192.168.1.106] (107-194-158-19.lightspeed.sntcca.sbcglobal.net [107.194.158.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.spacemail.com (Postfix) with ESMTPSA id 4hYZBm0DLxz2xB6; Mon, 31 Aug 2026 16:26:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gurudas.dev; s=spacemail; t=1788193617; bh=4TrA4xk009bAyQNQJy3hZYrjYVb5oA/qPg/Plwj2IlA=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=bchoTgCqgtpnzSJgUlUawhsI5ypoQPgCJ2VeLI4l9ZxumhH1LUhDmKRjyjFDAI+nm U5HcFAMV0LCmQt6ARF+0RjY4rLIbB6BOWF53KQmGad6nrj4Vok6X6I729CCljYxTBM ksKDnm5TKJHjvzabxZDu5bH0TfByrIO/zGlL/hNHreZfRqw/xcbbyOIVZnbKYLH1ql aS/+O0eleig1m2jQ0f0tRI2cUJ3Z/bJtTVjXkok7jHqAV02u/YOL7ggeYmz0S2Qu5F AbEtCNhT8CHWPIBzLtkwXrQ5WuRmjToMXIdMtyZ2HXxWAkL2xNIIrao90i4xV/VTeY pN+FVvMLix2Ow== From: Guru Das Srinagesh Date: Mon, 31 Aug 2026 09:26:28 -0700 Subject: [PATCH v3 1/3] minmax: Add in_range_inclusive() for inclusive range checks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-minmax-in-range-incl-v3-1-30444a2fd2a5@gurudas.dev> References: <20260831-minmax-in-range-incl-v3-0-30444a2fd2a5@gurudas.dev> In-Reply-To: <20260831-minmax-in-range-incl-v3-0-30444a2fd2a5@gurudas.dev> To: Alex Lanzano , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matthew Wilcox , Andrew Morton , Gustavo Silva Cc: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, Guru Das Srinagesh X-Mailer: b4 0.15.2 X-Envelope-From: linux@gurudas.dev Extend the logic in in_range() to support checking for an inclusive range [min, max]. The condition in the check is derived as follows, starting from the in_range() macro with len =3D (max - min + 1): (val - min) < (max - min + 1) // overflows for [0, U32/U64_MAX] (val - min) <=3D (max - min) // no overflow The behaviour of the macro from the signedness perspective is documented in the kernel-doc and in the in_range_inclusive KUnit test suite. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Guru Das Srinagesh --- include/linux/minmax.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index a0158db54a04..dce3a8bea9e2 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -299,6 +299,45 @@ static inline bool in_range32(u32 val, u32 start, u32 = len) ((sizeof(start) | sizeof(len) | sizeof(val)) <=3D sizeof(u32) ? \ in_range32(val, start, len) : in_range64(val, start, len)) =20 +static inline bool in_range_inclusive64(u64 val, u64 min, u64 max) +{ + return (val - min) <=3D (max - min); +} + +static inline bool in_range_inclusive32(u32 val, u32 min, u32 max) +{ + return (val - min) <=3D (max - min); +} + +/** + * in_range_inclusive - Determine if a value lies within an inclusive rang= e. + * @val: Value to test. + * @min: First value in range. + * @max: Last value in range. + * + * This checks if a value lies within the closed range of [@min, @max]. No= te that + * "range" refers to values counting up from @min with wraparound at + * unsigned-datatype max if encountered, continuing on till @max is reache= d. + * + * This macro is not a drop-in replacement for "if (val >=3D min && val <= =3D max)". + * Unsigned arithmetic determines what the 'true' range exactly is dependi= ng on + * whether @min <=3D @max holds, and in which reading (signed vs unsigned)= as follows:: + * + * Valid in reading Example 'True' range is + * Both readings [5, 10] interval as written in either reading + * Signed only [-10, 5] signed interval + * Unsigned only [5, -10] unsigned interval + * Neither reading [-5, -10] neither; all values except [unsigned= (-9), unsigned(-6)] + * + * The last two cases provide "surprising" results and are to be used care= fully, if + * at all. Further, if @max =3D @min - 1, every @val is in range. + * + * Return: true or false as described above. + */ +#define in_range_inclusive(val, min, max) \ + ((sizeof(val) | sizeof(min) | sizeof(max)) <=3D sizeof(u32) ? \ + in_range_inclusive32(val, min, max) : in_range_inclusive64(val, min, max= )) + /** * swap - swap values of @a and @b * @a: first value --=20 2.55.0 From nobody Sat Sep 26 14:39:24 2026 Received: from out-2z4y-a139.jellyfish.systems (out-2z4y-a139.jellyfish.systems [198.54.127.139]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DCDA44A725 for ; Mon, 31 Aug 2026 16:32:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.54.127.139 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788193930; cv=none; b=JCpaYzw6AdHBu0rsfkz1qHUOaj2lVpSXMgBzk+f8JdmBmMwpv8LzToJaS3mR+XR5+P4hhHX3B2UyGYSqDYAnm+tDLdj1NTTjHYO+GK9sy0ewjoyR+BYHtj/pzDOpaMG6D8ItcxLx1tJU2q5Dh6p4erOZ5ut/pB1hLpobm8kKGjM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788193930; c=relaxed/simple; bh=cT4su7834oe1cDhDtm3Z1O0puBE9pZtp7GN8lB5AtNk=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=FWKWH7V1Eb3l3PL8P7TcVDJVsyKVVj9CqG9jHVC5Cb1io03T112VMwUMsnC58+ETbxRMW3ggYgx+uJ/kErErpXwBQKSi5cuZhoaOJuvqCMPL3yPVnFrkrSkOHNp8yde2bkHfqbOOjsmMGsUZNnC5BsC24KzAhlYs9nt/tLgnoQA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gurudas.dev; spf=pass smtp.mailfrom=gurudas.dev; dkim=pass (2048-bit key) header.d=gurudas.dev header.i=@gurudas.dev header.b=Q53sFcUD; arc=none smtp.client-ip=198.54.127.139 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gurudas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gurudas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gurudas.dev header.i=@gurudas.dev header.b="Q53sFcUD" Received: from [192.168.1.106] (107-194-158-19.lightspeed.sntcca.sbcglobal.net [107.194.158.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.spacemail.com (Postfix) with ESMTPSA id 4hYZBn4W5mz2xB0; Mon, 31 Aug 2026 16:26:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gurudas.dev; s=spacemail; t=1788193619; bh=9/pnXXu42c1SsaCh/C97k7+pe5SrUF1Y0XulTf+Z6Sw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Q53sFcUDU9QoHj+3ujyMg5B+ZhjI5OOEraNNrB5lXiBnacWzeWB3FJg/uSNBsR7nY vgy05s4W+4be6F9Z30XqrPbnGQYU+kxZQ2WTSCd5fu2nOseGSaeu2iTycZMd7FOhE2 kc1SJ2CRN8TisGYgQRuO5ke8dHKFAi93Xs4alzqVrVtdOL24wkADna/9OXUUYnDwDx JwEcdMZPBP1jSsS65rWJBp5oHcyoxRfrA/i45NRQQba9MvEa9u6eVMEEQqV04FtTmd YgyCD7nSSYbkpD+oo1Nh50YSGSw+sHbTfuZxxZyz4DWDY7ivCndZPCEV4/xwdRq7Rx o77HyzrlZTUxQ== From: Guru Das Srinagesh Date: Mon, 31 Aug 2026 09:26:29 -0700 Subject: [PATCH v3 2/3] lib/tests: Add in_range_inclusive() KUnit test Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-minmax-in-range-incl-v3-2-30444a2fd2a5@gurudas.dev> References: <20260831-minmax-in-range-incl-v3-0-30444a2fd2a5@gurudas.dev> In-Reply-To: <20260831-minmax-in-range-incl-v3-0-30444a2fd2a5@gurudas.dev> To: Alex Lanzano , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matthew Wilcox , Andrew Morton , Gustavo Silva Cc: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, Guru Das Srinagesh X-Mailer: b4 0.15.2 X-Envelope-From: linux@gurudas.dev Add a KUnit test for the minmax.h in_range_inclusive() logic. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Guru Das Srinagesh --- lib/Kconfig.debug | 18 +++ lib/tests/Makefile | 1 + lib/tests/in_range_inclusive_kunit.c | 249 +++++++++++++++++++++++++++++++= ++++ 3 files changed, 268 insertions(+) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1244dcac2294..88f5abc70266 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -3031,6 +3031,24 @@ config MIN_HEAP_KUNIT_TEST =20 If unsure, say N =20 +config IN_RANGE_INCLUSIVE_KUNIT_TEST + tristate "Test minmax in_range_inclusive() logic" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + Enable this option to build the in_range_inclusive KUnit module. + It tests the in_range_inclusive() logic. + + KUnit tests run during boot and output the results to the debug log + in TAP format (http://testanything.org/). Only useful for kernel devs + running the KUnit test harness, and not intended for inclusion into a + production build. + + For more information on KUnit and unit tests in general please refer + to the KUnit documentation in Documentation/dev-tools/kunit/. + + If unsure, say N. + config IS_SIGNED_TYPE_KUNIT_TEST tristate "Test is_signed_type() macro" if !KUNIT_ALL_TESTS depends on KUNIT diff --git a/lib/tests/Makefile b/lib/tests/Makefile index 4ead57602eac..866b6006413d 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_GLOB_KUNIT_TEST) +=3D glob_kunit.o obj-$(CONFIG_HASHTABLE_KUNIT_TEST) +=3D hashtable_test.o obj-$(CONFIG_HASH_KUNIT_TEST) +=3D test_hash.o obj-$(CONFIG_TEST_IOV_ITER) +=3D kunit_iov_iter.o +obj-$(CONFIG_IN_RANGE_INCLUSIVE_KUNIT_TEST) +=3D in_range_inclusive_kunit.o obj-$(CONFIG_IS_SIGNED_TYPE_KUNIT_TEST) +=3D is_signed_type_kunit.o obj-$(CONFIG_KPROBES_SANITY_TEST) +=3D test_kprobes.o obj-$(CONFIG_LIST_KUNIT_TEST) +=3D list-test.o diff --git a/lib/tests/in_range_inclusive_kunit.c b/lib/tests/in_range_incl= usive_kunit.c new file mode 100644 index 000000000000..83e8d48684f2 --- /dev/null +++ b/lib/tests/in_range_inclusive_kunit.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Test cases for minmax in_range_inclusive() helpers. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include + +/* + * When @min <=3D @max is valid in: + * Valid in reading Example 'True' range is + * Case 1 Both readings [5, 10] interval as written in either rea= ding + * Case 2 Signed only [-10, 5] signed interval + * Case 3 Unsigned only [5, -10] unsigned interval + * Case 4 Neither reading [-5, -10] neither; all values except [unsig= ned(-9), unsigned(-6)] + * + * Visualizing the wraparound-continuous unsigned number scale as a full c= ircle with + * 0 at 12 o'clock and S32_MAX/S64_MAX at 6 o'clock, with ranges being cal= culated + * only clockwise starting from @min until @max might help greatly in unde= rstanding + * the following true and false ranges. + */ +static void u32_tests(struct kunit *test) +{ + /* Case 1 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5, 5, 10)); + /* Case 1 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(10, 5, 10)); + /* Case 1 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(11, 5, 10)); + /* Case 1 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(4, 5, 10)); + /* Case 1 0 not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(0, 5, 10)); + /* Case 1 U32_MAX not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(U32_MAX, 5, 10)); + + /* Case 2 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-10, -10, 5)); + /* Case 2 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5, -10, 5)); + /* Case 2 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(6, -10, 5)); + /* Case 2 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-11, -10, 5)); + /* Case 2 0 in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0, -10, 5)); + /* Case 2 U32_MAX in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U32_MAX, -10, 5)); + + /* Case 3 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5, 5, -10)); + /* Case 3 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-10, 5, -10)); + /* Case 3 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-9, 5, -10)); + /* Case 3 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(4, 5, -10)); + /* Case 3 0 not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(0, 5, -10)); + /* Case 3 U32_MAX not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(U32_MAX, 5, -10)); + + /* Case 4 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-5, -5, -10)); + /* Case 4 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-10, -5, -10)); + /* Case 4 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-9, -5, -10)); + /* Case 4 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-6, -5, -10)); + /* Case 4 0 in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0, -5, -10)); + /* Case 4 U32_MAX in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U32_MAX, -5, -10)); +} + +static void u64_tests(struct kunit *test) +{ + /* Case 1 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5ULL, 5ULL, 10ULL)); + /* Case 1 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(10ULL, 5ULL, 10ULL)); + /* Case 1 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(11ULL, 5ULL, 10ULL)); + /* Case 1 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(4ULL, 5ULL, 10ULL)); + /* Case 1 0 not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(0ULL, 5ULL, 10ULL)); + /* Case 1 U64_MAX not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(U64_MAX, 5ULL, 10ULL)); + + /* Case 2 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-10ULL, -10ULL, 5ULL)); + /* Case 2 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5ULL, -10ULL, 5ULL)); + /* Case 2 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(6ULL, -10ULL, 5ULL)); + /* Case 2 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-11ULL, -10ULL, 5ULL)); + /* Case 2 0 in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0ULL, -10ULL, 5ULL)); + /* Case 2 U64_MAX in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U64_MAX, -10ULL, 5ULL)); + + /* Case 3 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5ULL, 5ULL, -10ULL)); + /* Case 3 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-10ULL, 5ULL, -10ULL)); + /* Case 3 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-9ULL, 5ULL, -10ULL)); + /* Case 3 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(4ULL, 5ULL, -10ULL)); + /* Case 3 0 not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(0ULL, 5ULL, -10ULL)); + /* Case 3 U64_MAX not in range */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(U64_MAX, 5ULL, -10ULL)); + + /* Case 4 first true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-5ULL, -5ULL, -10ULL)); + /* Case 4 last true value */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(-10ULL, -5ULL, -10ULL)); + /* Case 4 first false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-9ULL, -5ULL, -10ULL)); + /* Case 4 last false value */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(-6ULL, -5ULL, -10ULL)); + /* Case 4 0 in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0ULL, -5ULL, -10ULL)); + /* Case 4 U64_MAX in range */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U64_MAX, -5ULL, -10ULL)); +} + +/* Check whether sizeof logic to select 32- vs 64-bit comparisons works */ +static void sizeof_logic_tests(struct kunit *test) +{ + u64 u64_val =3D BIT_ULL(32) | 7; + u64 u64_minval =3D BIT_ULL(32) | 5; + u64 u64_maxval =3D BIT_ULL(32) | 10; + u32 u32_minval =3D 5, u32_maxval =3D 10, u32_val =3D 100; + + /* If sizeof trick does not work: + * - u64_val will get truncated to 7 + * - 7 is in [5, 10] so test should pass. + */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(u64_val, u32_minval, u32_maxv= al)); + + /* + * If sizeof trick does not work: + * - u64_maxval will get truncated to 10 + * - 100 is not in [5, 10], so test should fail. + */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(u32_val, u32_minval, u64_maxva= l)); + + /* + * If sizeof trick does not work: + * - u64_minval gets truncated to 5 + * - 0 is not in [5, 10], so test should fail. + * Otherwise: + * - @min > @max here, so this is Case 4 + * - 0 should be in range and test should pass. + */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0, u64_minval, u32_maxval)); +} + +/* + * Each argument is widened to the selected width according to its own typ= e: + * signed arguments sign-extend, unsigned ones zero-extend. The same writt= en + * values can therefore give opposite answers depending on the declared ty= pes. + */ +static void sign_extension_tests(struct kunit *test) +{ + u32 u32_val =3D -9; + s32 s32_val =3D -9; + s32 s32_minval =3D 5, s32_maxval =3D -10; + s64 s64_minval =3D 5, s64_maxval =3D -10; + + /* Case 3 range. -9 is out of range in both readings */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(u32_val, s32_minval, s32_maxv= al)); + KUNIT_EXPECT_FALSE(test, in_range_inclusive(s32_val, s32_minval, s32_maxv= al)); + + /* + * Sign extension kicks in due to sizeof logic. minval "stays in place" + * because it is positive and maxval "moves" because it is negative and + * signed, thereby increasing the True range. + * Negative unsigned -9 "stays in place", so it becomes in range. + * Negative signed -9 "moves", so it still remains out of range. + */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(u32_val, s64_minval, s64_maxva= l)); + KUNIT_EXPECT_FALSE(test, in_range_inclusive(s32_val, s64_minval, s64_maxv= al)); +} + +#define TEST_RANGE_MIN 0 +#define TEST_RANGE_MAX 100 +static void misc_tests(struct kunit *test) +{ + s32 s32_val =3D -5; + + /* + * Test common device driver use case of rejecting negative input from + * userspace. + */ + KUNIT_EXPECT_FALSE(test, in_range_inclusive(s32_val, TEST_RANGE_MIN, TEST= _RANGE_MAX)); + + /* If min =3D=3D max, only one true solution exists, val =3D min */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5, 5, 5)); + KUNIT_EXPECT_FALSE(test, in_range_inclusive(0, 5, 5)); + KUNIT_EXPECT_FALSE(test, in_range_inclusive(U32_MAX, 5, 5)); + KUNIT_EXPECT_FALSE(test, in_range_inclusive(U64_MAX, 5, 5)); + + /* + * When max =3D (min - 1), Case 4 kicks in, and there is no 'false' range, + * i.e. all values of val result in 'true'. + */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(5, 5, 4)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(4, 5, 4)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0, 5, 4)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U32_MAX, 5, 4)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U64_MAX, 5, 4)); + + /* + * [0, U32_MAX] and [0, U64_MAX] are both the same case as above with + * min =3D 0 and max =3D (min - 1) + */ + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0, 0, U32_MAX)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U32_MAX, 0, U32_MAX)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(0, 0, U64_MAX)); + KUNIT_EXPECT_TRUE(test, in_range_inclusive(U64_MAX, 0, U64_MAX)); +} + +static struct kunit_case in_range_incl_test_cases[] =3D { + KUNIT_CASE(u32_tests), + KUNIT_CASE(u64_tests), + KUNIT_CASE(sizeof_logic_tests), + KUNIT_CASE(sign_extension_tests), + KUNIT_CASE(misc_tests), + {} +}; + +static struct kunit_suite in_range_incl_test_suite =3D { + .name =3D "in_range_inclusive", + .test_cases =3D in_range_incl_test_cases, +}; + +kunit_test_suites(&in_range_incl_test_suite); + +MODULE_AUTHOR("Guru Das Srinagesh "); +MODULE_DESCRIPTION("Test cases for in_range_inclusive()"); +MODULE_LICENSE("GPL"); --=20 2.55.0 From nobody Sat Sep 26 14:39:24 2026 Received: from out-zbxj-a74.jellyfish.systems (out-zbxj-a74.jellyfish.systems [198.54.127.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D779455619 for ; Mon, 31 Aug 2026 16:27:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.54.127.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788193630; cv=none; b=NO+OCv4zRbi4sEd1kIRquyRHIytSrtyM0ZgpOM6qO1kK7aWQ1a08+gugMS7oef/yUuFwTW6wX6aT7EOZb2lQsUmgSXofDFbD2/aGrxmdFNsS9lwrqCct2r4UIqj7FWhtNmoDJfLIXZ3QRzcjd0uqrKDAAXjVrCxDLtBGEHv8fBA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788193630; c=relaxed/simple; bh=KzPvc7CmYgesOOtbeUQCIr7Dh7m2v5p9kHcd+JzBsd0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=uBlPBqpqByQOM5aTK3awKCMsLTwYUFN6yTvPvC92QefeRbWNu6lb6jvPCvcxXoPsnmZuJCcZocym/5LecaIa8gwAVMCGqNEAVc70A+KHzKtdjRqsHEgSqBf/MmMlAy9Mab//lQUUU97qSwakMSqIB0yCbKa+w4KyaFOulhCtSyQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gurudas.dev; spf=pass smtp.mailfrom=gurudas.dev; dkim=pass (2048-bit key) header.d=gurudas.dev header.i=@gurudas.dev header.b=e3PXBqEb; arc=none smtp.client-ip=198.54.127.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=gurudas.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gurudas.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gurudas.dev header.i=@gurudas.dev header.b="e3PXBqEb" Received: from [192.168.1.106] (107-194-158-19.lightspeed.sntcca.sbcglobal.net [107.194.158.19]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.spacemail.com (Postfix) with ESMTPSA id 4hYZBq15Ydz2xBB; Mon, 31 Aug 2026 16:26:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gurudas.dev; s=spacemail; t=1788193620; bh=5tddOBd7dVOrv6zV3NixClhiHGTuWK8xZ1nqIYt6MhI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=e3PXBqEb4ZqVUXQJGU2eTcPPA0CkCRq4xZEoBpXKC8I+bhiR3zLjmvaB9Twwj3yGd 8betetBYBRoGR34YiDYpxq8nv0e4bK5cldjD8BjCqwEPyRvTaqhclH3HJHXWSOhNcG FU80g0bvo6fdQ4y0wQzxBDS6cQtWEts3jYDV/AO/tdcvHhIDO9nklnP7xHhhyvor+m BduTvHXZUydH0sbaud2yVtVzaoJNfDHHjuG2MQYnDkpRp6UJ1rXW0/RKG9CgQTetra LzX6iIaXT2tlnZGnZJJq+aVqaCCQVe761Z1FYOw8CapwVzyv9J0sYV7kWUCD2oUGRM KU1VmUhzrOOeQ== From: Guru Das Srinagesh Date: Mon, 31 Aug 2026 09:26:30 -0700 Subject: [PATCH v3 3/3] iio: imu: bmi270: Use in_range_inclusive() in bmi270_write_event_value() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260831-minmax-in-range-incl-v3-3-30444a2fd2a5@gurudas.dev> References: <20260831-minmax-in-range-incl-v3-0-30444a2fd2a5@gurudas.dev> In-Reply-To: <20260831-minmax-in-range-incl-v3-0-30444a2fd2a5@gurudas.dev> To: Alex Lanzano , Jonathan Cameron , David Lechner , =?utf-8?q?Nuno_S=C3=A1?= , Andy Shevchenko , Matthew Wilcox , Andrew Morton , Gustavo Silva Cc: linux-kernel@vger.kernel.org, linux-iio@vger.kernel.org, Guru Das Srinagesh X-Mailer: b4 0.15.2 X-Envelope-From: linux@gurudas.dev Replace the three "in_range(val, 0, MAX + 1)" checks with the new in_range_inclusive() helper, expressing each as the inclusive [0, MAX] range it actually validates. No functional changes are introduced by this change because @min <=3D @max in the inclusive range in both signed and unsigned readings and hence the check correctly continues to hold and is unchanged in behaviour. Assisted-by: Claude-Code:claude-sonnet-5 Signed-off-by: Guru Das Srinagesh Reviewed-by: Andy Shevchenko --- drivers/iio/imu/bmi270/bmi270_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iio/imu/bmi270/bmi270_core.c b/drivers/iio/imu/bmi270/= bmi270_core.c index 2ad230788532..7f386a615b39 100644 --- a/drivers/iio/imu/bmi270/bmi270_core.c +++ b/drivers/iio/imu/bmi270/bmi270_core.c @@ -1132,7 +1132,7 @@ static int bmi270_write_event_value(struct iio_dev *i= ndio_dev, guard(mutex)(&data->mutex); =20 if (type =3D=3D IIO_EV_TYPE_CHANGE) { - if (!in_range(val, 0, BMI270_STEP_COUNTER_MAX + 1)) + if (!in_range_inclusive(val, 0, BMI270_STEP_COUNTER_MAX)) return -EINVAL; =20 raw =3D val / BMI270_STEP_COUNTER_FACTOR; @@ -1152,7 +1152,7 @@ static int bmi270_write_event_value(struct iio_dev *i= ndio_dev, if (ret) return ret; =20 - if (!in_range(val, 0, (BMI270_G_MICRO_M_S_2 / uscale) + 1)) + if (!in_range_inclusive(val, 0, BMI270_G_MICRO_M_S_2 / uscale)) return -EINVAL; =20 tmp =3D (u64)val * BMI270_MOTION_THRES_FULL_SCALE * uscale; @@ -1161,7 +1161,7 @@ static int bmi270_write_event_value(struct iio_dev *i= ndio_dev, regval =3D FIELD_PREP(BMI270_FEAT_MOTION_THRESHOLD_MSK, raw); return bmi270_update_feature_reg(data, reg, mask, regval); case IIO_EV_INFO_PERIOD: - if (!in_range(val, 0, BMI270_MOTION_DURAT_MAX + 1)) + if (!in_range_inclusive(val, 0, BMI270_MOTION_DURAT_MAX)) return -EINVAL; =20 raw =3D BMI270_INT_MICRO_TO_RAW(val, val2, --=20 2.55.0