On 23 September 2026 15:49:37 BST, Zhan Xusheng <[email protected]> wrote: >proc_int_k2u_conv_kop() returns the sign through *negp and the magnitude >through *u_ptr. For a negative value it used to convert the >sign-extended int and negate afterwards, so the magnitude came back as a >wrapped 64-bit number. Nothing noticed, because no test wrote a >negative value to a jiffies sysctl. > >Write one to each of the three int converters and require the value to >read back unchanged. Each value is chosen to convert exactly at every >CONFIG_HZ, so the test does not depend on it: > > converter write jiffies stored reads back > jiffies -1 -HZ -1 > ms_jiffies -1000 -HZ -1000 > userhz_jiffies -100 -HZ -100 > >On a kernel without the fix, at CONFIG_HZ=250: > > # int_jiffies: got '-18372957097414713411', want '-1' > # int_ms_jiffies: got '-18446744069414585320', want '-1000' > # int_userhz_jiffies: got '-18446742229035144346', want '-100' > not ok 1 test_int_jiffies_negative > >(paths shortened; the runner prints them under >/proc/sys/debug/test_sysctl) > >Signed-off-by: Zhan Xusheng <[email protected]> >--- > tools/testing/selftests/sysctl/sysctl.sh | 23 +++++++++++++++++++++++ > 1 file changed, 23 insertions(+) > >diff --git a/tools/testing/selftests/sysctl/sysctl.sh >b/tools/testing/selftests/sysctl/sysctl.sh >index ceb5cfa0cfd4..ad1ee0fccd7c 100755 >--- a/tools/testing/selftests/sysctl/sysctl.sh >+++ b/tools/testing/selftests/sysctl/sysctl.sh >@@ -328,6 +328,29 @@ test_int_plain() > assert_int_range "$t" "$baseline" || RET=$KSFT_FAIL > } > >+# The jiffies converters report the sign separately from the magnitude, so a >+# negative value must survive the round trip through the converter. Each >+# value below is chosen to convert exactly at every CONFIG_HZ.
I have a feeling this could be decreased, but I don't care. Reviewed-by: Bradley Morgan <[email protected]> Tested on PowerPC: Tested-by: Bradley Morgan <[email protected]> # POWER10 >+test_int_jiffies_negative() >+{ >+ local t="${SYSCTL}/int_jiffies" >+ local m="${SYSCTL}/int_ms_jiffies" >+ local u="${SYSCTL}/int_userhz_jiffies" >+ >+ [[ -f "$t" && -f "$m" && -f "$u" ]] || { RET=$KSFT_SKIP; return; } >+ >+ printf '%s' "-1" > "$t" >+ assert_content "$t" "-1" || RET=$KSFT_FAIL >+ printf '%s' "-1000" > "$m" >+ assert_content "$m" "-1000" || RET=$KSFT_FAIL >+ printf '%s' "-100" > "$u" >+ assert_content "$u" "-100" || RET=$KSFT_FAIL >+ >+ # The positive path was never broken; keep it covered. >+ printf '%s' "1" > "$t" >+ assert_content "$t" "1" || RET=$KSFT_FAIL >+} >+ > test_uint_plain() > { > local t="${SYSCTL}/uint_0001" > --- Thanks! "I'm not a very positive person" - Linus torvalds

