]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
tools/nolibc: MIPS: fix clobbers of 'lo' and 'hi' registers on different ISAs
authorThomas Weißschuh <thomas.weissschuh@linutronix.de>
Tue, 17 Mar 2026 08:40:36 +0000 (09:40 +0100)
committerThomas Weißschuh <linux@weissschuh.net>
Fri, 20 Mar 2026 16:58:26 +0000 (17:58 +0100)
All MIPS ISAs before r6 use the 'lo' and 'hi' special registers.
These are clobbered by system calls and need to be marked as such to
avoid miscompilations. Currently nolibc ties the clobbers to the ABI.
But this is wrong and leads to ISA<->ABI combinations which are not
handled correctly, leading to compiler errors or miscompilations.

Handle all different combinations of ABI and ISA.

Fixes: a6a2a8a42972 ("tools/nolibc: MIPS: add support for N64 and N32 ABIs")
Fixes: 66b6f755ad45 ("rcutorture: Import a copy of nolibc")
Suggested-by: Maciej W. Rozycki <macro@orcam.me.uk>
Link: https://lore.kernel.org/lkml/alpine.DEB.2.21.2603141744240.55200@angie.orcam.me.uk/
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Link: https://patch.msgid.link/20260317-nolibc-mips-clobber-v2-1-5b9a97761a9e@linutronix.de
Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
tools/include/nolibc/arch-mips.h

index bd4a9b57e1f021dbf5bf7104f039bf3d67a739c3..bb9d580ea1b16d64326c601ffb35ba06717fab27 100644 (file)
  *   - stack is 16-byte aligned
  */
 
+#if !defined(__mips_isa_rev) || __mips_isa_rev < 6
+#define _NOLIBC_SYSCALL_CLOBBER_HI_LO "hi", "lo"
+#else
+#define _NOLIBC_SYSCALL_CLOBBER_HI_LO "$0"
+#endif
+
 #if defined(_ABIO32)
 
 #define _NOLIBC_SYSCALL_CLOBBERLIST \
-       "memory", "cc", "at", "v1", "hi", "lo", \
-       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"
+       "memory", "cc", "at", "v1", \
+       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", \
+       _NOLIBC_SYSCALL_CLOBBER_HI_LO
+
 #define _NOLIBC_SYSCALL_STACK_RESERVE "addiu $sp, $sp, -32\n"
 #define _NOLIBC_SYSCALL_STACK_UNRESERVE "addiu $sp, $sp, 32\n"
 
@@ -52,7 +60,8 @@
 /* binutils, GCC and clang disagree about register aliases, use numbers instead. */
 #define _NOLIBC_SYSCALL_CLOBBERLIST \
        "memory", "cc", "at", "v1", \
-       "10", "11", "12", "13", "14", "15", "24", "25"
+       "10", "11", "12", "13", "14", "15", "24", "25", \
+       _NOLIBC_SYSCALL_CLOBBER_HI_LO
 
 #define _NOLIBC_SYSCALL_STACK_RESERVE
 #define _NOLIBC_SYSCALL_STACK_UNRESERVE