Parcourir la source

linux: h8300: tell gcc that the inline asm clobbers the condition codes

current_thread_info() computes the pointer with

	mov.l	sp, %0
	and.w	%1, %T0

and declares no clobbers. Both instructions write N and Z, so gcc is
free to schedule the block between an instruction that sets the flags
and the branch that reads them -- and it does. In copy_process():

	mov.l	@(0x148,er4),er2	; p->exit_signal, loaded for its flags
	mov.l	er7,er2			; current_thread_info(), sets N
	and.w	#0xe000,r2		; ditto
	bmi	<else>			; if (thread_group_leader(p))

The branch ends up testing bit 15 of the stack pointer. The swapper
stack sits at 0x50c000, so that bit is set and the thread_group_leader()
block is skipped for every task the swapper creates -- pid 1 and pid 2.
signal->leader_pid stays NULL, it_real_fn() hands that NULL to
kill_pid_info(), and ITIMER_REAL never delivers: alarm() silently does
nothing in init, which is how this was found -- a test runner running as
pid 1 could not time out a stuck test.

The same omission is in __xchg() and in the non-atomic
__test_and_*_bit(); their atomic siblings already carry the clobber.

Not sent upstream: h8300 was removed from Linux in v5.19-rc1
(1c4b5ecb7ea1, 2022-02-23), so 4.4 is where this lives now.

Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
ramin il y a 3 jours
Parent
commit
6f7366bda0
1 fichiers modifiés avec 63 ajouts et 0 suppressions
  1. 63 0
      target/linux/patches/4.4.302/h8300-inline-asm-cc-clobber.patch

+ 63 - 0
target/linux/patches/4.4.302/h8300-inline-asm-cc-clobber.patch

@@ -0,0 +1,63 @@
+diff -Nur linux-4.4.302.orig/arch/h8300/include/asm/bitops.h linux-4.4.302/arch/h8300/include/asm/bitops.h
+--- linux-4.4.302.orig/arch/h8300/include/asm/bitops.h	2022-02-03 09:27:54.000000000 +0100
++++ linux-4.4.302/arch/h8300/include/asm/bitops.h	2026-08-31 00:23:11.784425023 +0200
+@@ -135,7 +135,7 @@
+ 			OP " %3,%1\n\t"					\
+ 			"rotxl.l %0\n\t"				\
+ 			: "=r"(retval), "+WU"(*b_addr)			\
+-			: "0" (retval), "i"(nr & 7));			\
++			: "0" (retval), "i"(nr & 7) : "cc");		\
+ 	} else {							\
+ 		__asm__("btst %s3,%1\n\t"				\
+ 			OP " %s3,%1\n\t"				\
+@@ -143,7 +143,7 @@
+ 			"inc.l #1,%0\n\t"				\
+ 			"1:"						\
+ 			: "=r"(retval), "+WU"(*b_addr)			\
+-			: "0" (retval), "r"(bit));			\
++			: "0" (retval), "r"(bit) : "cc");		\
+ 	}								\
+ 	return retval;							\
+ }
+diff -Nur linux-4.4.302.orig/arch/h8300/include/asm/cmpxchg.h linux-4.4.302/arch/h8300/include/asm/cmpxchg.h
+--- linux-4.4.302.orig/arch/h8300/include/asm/cmpxchg.h	2022-02-03 09:27:54.000000000 +0100
++++ linux-4.4.302/arch/h8300/include/asm/cmpxchg.h	2026-08-31 00:23:11.783013840 +0200
+@@ -22,19 +22,22 @@
+ 		__asm__ __volatile__
+ 			("mov.b %2,%0\n\t"
+ 			 "mov.b %1,%2"
+-			 : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)));
++			 : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr))
++			 : "cc");
+ 		break;
+ 	case 2:
+ 		__asm__ __volatile__
+ 			("mov.w %2,%0\n\t"
+ 			 "mov.w %1,%2"
+-			 : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)));
++			 : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr))
++			 : "cc");
+ 		break;
+ 	case 4:
+ 		__asm__ __volatile__
+ 			("mov.l %2,%0\n\t"
+ 			 "mov.l %1,%2"
+-			 : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr)));
++			 : "=&r" (tmp) : "r" (x), "m" (*__xg(ptr))
++			 : "cc");
+ 		break;
+ 	default:
+ 		tmp = 0;
+diff -Nur linux-4.4.302.orig/arch/h8300/include/asm/thread_info.h linux-4.4.302/arch/h8300/include/asm/thread_info.h
+--- linux-4.4.302.orig/arch/h8300/include/asm/thread_info.h	2022-02-03 09:27:54.000000000 +0100
++++ linux-4.4.302/arch/h8300/include/asm/thread_info.h	2026-08-31 00:23:11.781512536 +0200
+@@ -56,7 +56,8 @@
+ 	__asm__("mov.l	sp, %0\n\t"
+ 		"and.w	%1, %T0"
+ 		: "=&r"(ti)
+-		: "i" (~(THREAD_SIZE-1) & 0xffff));
++		: "i" (~(THREAD_SIZE-1) & 0xffff)
++		: "cc");
+ 	return ti;
+ }
+