[PATCH 2/2] selftests/user_events: Fix pointer casts for 32-bit builds
flat view
DORMANTno replies
From: Danish Khateeb <hidden>
Date: 2026-09-28 17:14:30
Also in:
linux-kselftest, lkml
Subsystem:
kernel selftest framework, the rest · Maintainers:
Shuah Khan, Shuah Khan, Linus Torvalds
The tests cast pointers directly to __u64. On 32-bit builds GCC
sign-extends such casts, so addresses above 2 GiB, like the stack of a
32-bit task on a 64-bit kernel, become 0xffffffffxxxxxxxx and every
registration fails.
Cast through uintptr_t so the tests also work when built for 32-bit and
cover the compat ioctl path.
Assisted-by: LLM
Signed-off-by: Danish Khateeb <redacted>
---
Notes:
Built with and without -m32. With 1/2 applied, the 32-bit tests pass on
x86_64; the 64-bit binaries are unchanged in behaviour and still pass.
The -Wpointer-to-int-cast warnings left in a 32-bit build come from
kselftest_harness.h, not from these tests.
.../testing/selftests/user_events/abi_test.c | 10 +++---
.../testing/selftests/user_events/dyn_test.c | 6 ++--
.../selftests/user_events/ftrace_test.c | 32 +++++++++----------
.../testing/selftests/user_events/perf_test.c | 10 +++---
4 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/tools/testing/selftests/user_events/abi_test.c b/tools/testing/selftests/user_events/abi_test.c
index b71813eaf5c0..21e1e3cca197 100644
--- a/tools/testing/selftests/user_events/abi_test.c
+++ b/tools/testing/selftests/user_events/abi_test.c@@ -179,10 +179,10 @@ static int reg_enable_multi(void *enable, int size, int bit, int flags, } reg.size = sizeof(reg); - reg.name_args = (__u64)full_args; + reg.name_args = (__u64)(uintptr_t)full_args; reg.flags = USER_EVENT_REG_MULTI_FORMAT | flags; reg.enable_bit = bit; - reg.enable_addr = (__u64)enable; + reg.enable_addr = (__u64)(uintptr_t)enable; reg.enable_size = size; ret = ioctl(fd, DIAG_IOCSREG, ®);
@@ -202,10 +202,10 @@ static int reg_enable_flags(void *enable, int size, int bit, int flags) return -1; reg.size = sizeof(reg); - reg.name_args = (__u64)"__abi_event"; + reg.name_args = (__u64)(uintptr_t)"__abi_event"; reg.flags = flags; reg.enable_bit = bit; - reg.enable_addr = (__u64)enable; + reg.enable_addr = (__u64)(uintptr_t)enable; reg.enable_size = size; ret = ioctl(fd, DIAG_IOCSREG, ®);
@@ -231,7 +231,7 @@ static int reg_disable(void *enable, int bit) reg.size = sizeof(reg); reg.disable_bit = bit; - reg.disable_addr = (__u64)enable; + reg.disable_addr = (__u64)(uintptr_t)enable; ret = ioctl(fd, DIAG_IOCSUNREG, ®);
diff --git a/tools/testing/selftests/user_events/dyn_test.c b/tools/testing/selftests/user_events/dyn_test.c
index 78e3c33f4015..32f159544d0b 100644
--- a/tools/testing/selftests/user_events/dyn_test.c
+++ b/tools/testing/selftests/user_events/dyn_test.c@@ -58,9 +58,9 @@ static int reg_event(int fd, int *check, int bit, const char *value) struct user_reg reg = {0}; reg.size = sizeof(reg); - reg.name_args = (__u64)value; + reg.name_args = (__u64)(uintptr_t)value; reg.enable_bit = bit; - reg.enable_addr = (__u64)check; + reg.enable_addr = (__u64)(uintptr_t)check; reg.enable_size = sizeof(*check); if (ioctl(fd, DIAG_IOCSREG, ®) == -1)
@@ -75,7 +75,7 @@ static int unreg_event(int fd, int *check, int bit) unreg.size = sizeof(unreg); unreg.disable_bit = bit; - unreg.disable_addr = (__u64)check; + unreg.disable_addr = (__u64)(uintptr_t)check; return ioctl(fd, DIAG_IOCSUNREG, &unreg); }
diff --git a/tools/testing/selftests/user_events/ftrace_test.c b/tools/testing/selftests/user_events/ftrace_test.c
index decce06b9ba8..b9c75202f0bd 100644
--- a/tools/testing/selftests/user_events/ftrace_test.c
+++ b/tools/testing/selftests/user_events/ftrace_test.c@@ -127,7 +127,7 @@ static int clear(int *check) unreg.size = sizeof(unreg); unreg.disable_bit = 31; - unreg.disable_addr = (__u64)check; + unreg.disable_addr = (__u64)(uintptr_t)check; fd = open(data_file, O_RDWR);
@@ -174,9 +174,9 @@ static int check_print_fmt(const char *event, const char *expected, int *check) return fd; reg.size = sizeof(reg); - reg.name_args = (__u64)event; + reg.name_args = (__u64)(uintptr_t)event; reg.enable_bit = 31; - reg.enable_addr = (__u64)check; + reg.enable_addr = (__u64)(uintptr_t)check; reg.enable_size = sizeof(*check); /* Register should work */
@@ -239,14 +239,14 @@ TEST_F(user, register_events) { struct user_unreg unreg = {0}; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; + reg.name_args = (__u64)(uintptr_t)"__test_event u32 field1; u32 field2"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); unreg.size = sizeof(unreg); unreg.disable_bit = 31; - unreg.disable_addr = (__u64)&self->check; + unreg.disable_addr = (__u64)(uintptr_t)&self->check; /* Register should work */ ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®));
@@ -263,13 +263,13 @@ TEST_F(user, register_events) { /* Register without separator spacing should still match */ reg.enable_bit = 29; - reg.name_args = (__u64)"__test_event u32 field1;u32 field2"; + reg.name_args = (__u64)(uintptr_t)"__test_event u32 field1;u32 field2"; ASSERT_EQ(0, ioctl(self->data_fd, DIAG_IOCSREG, ®)); ASSERT_EQ(0, reg.write_index); /* Multiple registers to same name but different args should fail */ reg.enable_bit = 29; - reg.name_args = (__u64)"__test_event u32 field1;"; + reg.name_args = (__u64)(uintptr_t)"__test_event u32 field1;"; ASSERT_EQ(-1, ioctl(self->data_fd, DIAG_IOCSREG, ®)); ASSERT_EQ(EADDRINUSE, errno);
@@ -310,9 +310,9 @@ TEST_F(user, write_events) { int before = 0, after = 0; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; + reg.name_args = (__u64)(uintptr_t)"__test_event u32 field1; u32 field2"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); field1 = 1;
@@ -367,9 +367,9 @@ TEST_F(user, write_empty_events) { int before = 0, after = 0; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event"; + reg.name_args = (__u64)(uintptr_t)"__test_event"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); io[0].iov_base = ®.write_index;
@@ -401,9 +401,9 @@ TEST_F(user, write_fault) { void *anon; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event u64 anon"; + reg.name_args = (__u64)(uintptr_t)"__test_event u64 anon"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); anon = mmap(NULL, l, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -439,9 +439,9 @@ TEST_F(user, write_validator) { int before = 0, after = 0; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event __rel_loc char[] data"; + reg.name_args = (__u64)(uintptr_t)"__test_event __rel_loc char[] data"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); /* Register should work */
diff --git a/tools/testing/selftests/user_events/perf_test.c b/tools/testing/selftests/user_events/perf_test.c
index 5727cb5b914c..b444d114b2f0 100644
--- a/tools/testing/selftests/user_events/perf_test.c
+++ b/tools/testing/selftests/user_events/perf_test.c@@ -89,7 +89,7 @@ static int clear(int *check) unreg.size = sizeof(unreg); unreg.disable_bit = 31; - unreg.disable_addr = (__u64)check; + unreg.disable_addr = (__u64)(uintptr_t)check; int fd = open(data_file, O_RDWR);
@@ -160,9 +160,9 @@ TEST_F(user, perf_write) { __u32 *val; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event u32 field1; u32 field2"; + reg.name_args = (__u64)(uintptr_t)"__test_event u32 field1; u32 field2"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); /* Register should work */
@@ -224,9 +224,9 @@ TEST_F(user, perf_empty_events) { __u32 *val; reg.size = sizeof(reg); - reg.name_args = (__u64)"__test_event"; + reg.name_args = (__u64)(uintptr_t)"__test_event"; reg.enable_bit = 31; - reg.enable_addr = (__u64)&self->check; + reg.enable_addr = (__u64)(uintptr_t)&self->check; reg.enable_size = sizeof(self->check); /* Register should work */
--
2.55.0