| From 746357d6a526d6da9d89a2ec645b28406e959c2e Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Fri, 20 Nov 2009 12:01:43 +0100 |
| Subject: x86: Prevent GCC 4.4.x (pentium-mmx et al) function prologue wreckage |
| |
| From: Thomas Gleixner <tglx@linutronix.de> |
| |
| commit 746357d6a526d6da9d89a2ec645b28406e959c2e upstream. |
| |
| When the kernel is compiled with -pg for tracing GCC 4.4.x inserts |
| stack alignment of a function _before_ the mcount prologue if the |
| -march=pentium-mmx is set and -mtune=generic is not set. This breaks |
| the assumption of the function graph tracer which expects that the |
| mcount prologue |
| |
| push %ebp |
| mov %esp, %ebp |
| |
| is the first stack operation in a function because it needs to modify |
| the function return address on the stack to trap into the tracer |
| before returning to the real caller. |
| |
| The generated code is: |
| |
| push %edi |
| lea 0x8(%esp),%edi |
| and $0xfffffff0,%esp |
| pushl -0x4(%edi) |
| push %ebp |
| mov %esp,%ebp |
| |
| so the tracer modifies the copy of the return address which is stored |
| after the stack alignment and therefor does not trap the return which |
| in turn breaks the call chain logic of the tracer and leads to a |
| kernel panic. |
| |
| Aside of the fact that the generated code is horrible for no good |
| reason other -march -mtune options generate the expected: |
| |
| push %ebp |
| mov %esp,%ebp |
| and $0xfffffff0,%esp |
| |
| which does the same and keeps everything intact. |
| |
| After some experimenting we found out that this problem is restricted |
| to gcc4.4.x and to the following -march settings: |
| |
| i586, pentium, pentium-mmx, k6, k6-2, k6-3, winchip-c6, winchip2, c3, |
| geode |
| |
| By adding -mtune=generic the code generator produces always the |
| expected code. |
| |
| So forcing -mtune=generic when CONFIG_FUNCTION_GRAPH_TRACER=y is not |
| pretty, but at the moment the only way to prevent that the kernel |
| trips over gcc-shrooms induced code madness. |
| |
| Most distro kernels have CONFIG_X86_GENERIC=y anyway which forces |
| -mtune=generic as well so it will not impact those. |
| |
| References: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42109 |
| http://lkml.org/lkml/2009/11/19/17 |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| LKML-Reference: <alpine.LFD.2.00.0911200206570.24119@localhost.localdomain> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Andrew Morton <akpm@linux-foundation.org> |
| Cc: Ingo Molnar <mingo@elte.hu> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: H. Peter Anvin <hpa@zytor.com> |
| Cc: Steven Rostedt <rostedt@goodmis.org> |
| Cc: Frederic Weisbecker <fweisbec@gmail.com>, |
| Cc: Jeff Law <law@redhat.com> |
| Cc: gcc@gcc.gnu.org |
| Cc: David Daney <ddaney@caviumnetworks.com> |
| Cc: Andrew Haley <aph@redhat.com> |
| Cc: Richard Guenther <richard.guenther@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| arch/x86/Makefile_32.cpu | 6 ++++++ |
| 1 file changed, 6 insertions(+) |
| |
| --- a/arch/x86/Makefile_32.cpu |
| +++ b/arch/x86/Makefile_32.cpu |
| @@ -46,6 +46,12 @@ cflags-$(CONFIG_MGEODEGX1) += -march=pen |
| # cpu entries |
| cflags-$(CONFIG_X86_GENERIC) += $(call tune,generic,$(call tune,i686)) |
| |
| +# Work around the pentium-mmx code generator madness of gcc4.4.x which |
| +# does stack alignment by generating horrible code _before_ the mcount |
| +# prologue (push %ebp, mov %esp, %ebp) which breaks the function graph |
| +# tracer assumptions |
| +cflags-$(CONFIG_FUNCTION_GRAPH_TRACER) += $(call cc-option,-mtune=generic) |
| + |
| # Bug fix for binutils: this option is required in order to keep |
| # binutils from generating NOPL instructions against our will. |
| ifneq ($(CONFIG_X86_P6_NOP),y) |