Skip to content

Commit 9c69520

Browse files
Mikael Petterssontorvalds
authored andcommitted
compiler-gcc.h: gcc-4.5 needs noclone and noinline on __naked functions
A __naked function is defined in C but with a body completely implemented by asm(), including any prologue and epilogue. These asm() bodies expect standard calling conventions for parameter passing. Older GCCs implement that correctly, but 4.[56] currently do not, see GCC PR44290. In the Linux kernel this breaks ARM, causing most arch/arm/mm/copypage-*.c modules to get miscompiled, resulting in kernel crashes during bootup. Part of the kernel fix is to augment the __naked function attribute to also imply noinline and noclone. This patch implements that, and has been verified to fix boot failures with gcc-4.5 compiled 2.6.34 and 2.6.35-rc1 kernels. The patch is a no-op with older GCCs. Signed-off-by: Mikael Pettersson <[email protected]> Signed-off-by: Khem Raj <[email protected]> Cc: Russell King <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2952095 commit 9c69520

File tree

2 files changed

+13
-1
lines changed

2 files changed

+13
-1
lines changed

include/linux/compiler-gcc.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,12 @@
5858
* naked functions because then mcount is called without stack and frame pointer
5959
* being set up and there is no chance to restore the lr register to the value
6060
* before mcount was called.
61+
*
62+
* The asm() bodies of naked functions often depend on standard calling conventions,
63+
* therefore they must be noinline and noclone. GCC 4.[56] currently fail to enforce
64+
* this, so we must do so ourselves. See GCC PR44290.
6165
*/
62-
#define __naked __attribute__((naked)) notrace
66+
#define __naked __attribute__((naked)) noinline __noclone notrace
6367

6468
#define __noreturn __attribute__((noreturn))
6569

@@ -85,3 +89,7 @@
8589
#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
8690
#define gcc_header(x) _gcc_header(x)
8791
#include gcc_header(__GNUC__)
92+
93+
#if !defined(__noclone)
94+
#define __noclone /* not needed */
95+
#endif

include/linux/compiler-gcc4.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
* unreleased. Really, we need to have autoconf for the kernel.
4949
*/
5050
#define unreachable() __builtin_unreachable()
51+
52+
/* Mark a function definition as prohibited from being cloned. */
53+
#define __noclone __attribute__((__noclone__))
54+
5155
#endif
5256

5357
#endif

0 commit comments

Comments
 (0)