diff options
| author | Mikael Pettersson <mikpe@it.uu.se> | 2010-06-29 18:05:25 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-06-29 18:29:31 -0400 |
| commit | 9c695203a7ddbe49dba5f22f4c941d24f47475df (patch) | |
| tree | 0dcfa624ecb7c5810f7062fe950bf3f0de2e55b2 | |
| parent | 2952095c6b2eefd068dda0dee6317cf95155a304 (diff) | |
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 <mikpe@it.uu.se>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Cc: Russell King <rmk@arm.linux.org.uk>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | include/linux/compiler-gcc.h | 10 | ||||
| -rw-r--r-- | include/linux/compiler-gcc4.h | 4 |
2 files changed, 13 insertions, 1 deletions
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 73dcf804bc94..0da5b187f124 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h | |||
| @@ -58,8 +58,12 @@ | |||
| 58 | * naked functions because then mcount is called without stack and frame pointer | 58 | * naked functions because then mcount is called without stack and frame pointer |
| 59 | * being set up and there is no chance to restore the lr register to the value | 59 | * being set up and there is no chance to restore the lr register to the value |
| 60 | * before mcount was called. | 60 | * 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. | ||
| 61 | */ | 65 | */ |
| 62 | #define __naked __attribute__((naked)) notrace | 66 | #define __naked __attribute__((naked)) noinline __noclone notrace |
| 63 | 67 | ||
| 64 | #define __noreturn __attribute__((noreturn)) | 68 | #define __noreturn __attribute__((noreturn)) |
| 65 | 69 | ||
| @@ -85,3 +89,7 @@ | |||
| 85 | #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h) | 89 | #define _gcc_header(x) __gcc_header(linux/compiler-gcc##x.h) |
| 86 | #define gcc_header(x) _gcc_header(x) | 90 | #define gcc_header(x) _gcc_header(x) |
| 87 | #include gcc_header(__GNUC__) | 91 | #include gcc_header(__GNUC__) |
| 92 | |||
| 93 | #if !defined(__noclone) | ||
| 94 | #define __noclone /* not needed */ | ||
| 95 | #endif | ||
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index 94dea3ffbfa1..fcfa5b9a4317 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h | |||
| @@ -48,6 +48,10 @@ | |||
| 48 | * unreleased. Really, we need to have autoconf for the kernel. | 48 | * unreleased. Really, we need to have autoconf for the kernel. |
| 49 | */ | 49 | */ |
| 50 | #define unreachable() __builtin_unreachable() | 50 | #define unreachable() __builtin_unreachable() |
| 51 | |||
| 52 | /* Mark a function definition as prohibited from being cloned. */ | ||
| 53 | #define __noclone __attribute__((__noclone__)) | ||
| 54 | |||
| 51 | #endif | 55 | #endif |
| 52 | 56 | ||
| 53 | #endif | 57 | #endif |
