Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c695203 authored by Mikael Pettersson's avatar Mikael Pettersson Committed by Linus Torvalds
Browse files

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: default avatarMikael Pettersson <mikpe@it.uu.se>
Signed-off-by: default avatarKhem Raj <raj.khem@gmail.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: <stable@kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2952095c
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -58,8 +58,12 @@
 * naked functions because then mcount is called without stack and frame pointer
 * being set up and there is no chance to restore the lr register to the value
 * before mcount was called.
 *
 * The asm() bodies of naked functions often depend on standard calling conventions,
 * therefore they must be noinline and noclone.  GCC 4.[56] currently fail to enforce
 * this, so we must do so ourselves.  See GCC PR44290.
 */
#define __naked				__attribute__((naked)) notrace
#define __naked				__attribute__((naked)) noinline __noclone notrace

#define __noreturn			__attribute__((noreturn))

@@ -85,3 +89,7 @@
#define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h)
#define gcc_header(x) _gcc_header(x)
#include gcc_header(__GNUC__)

#if !defined(__noclone)
#define __noclone	/* not needed */
#endif
+4 −0
Original line number Diff line number Diff line
@@ -48,6 +48,10 @@
 * unreleased.  Really, we need to have autoconf for the kernel.
 */
#define unreachable() __builtin_unreachable()

/* Mark a function definition as prohibited from being cloned. */
#define __noclone	__attribute__((__noclone__))

#endif

#endif