linux/arch/mips
Al Cooper 58b69401c7 MIPS: Function tracer: Fix broken function tracing
Function tracing is currently broken for all 32 bit MIPS platforms.
When tracing is enabled, the kernel immediately hangs on boot.
This is a result of commit b732d439cb
that changes the kernel/trace/Kconfig file so that is no longer
forces FRAME_POINTER when FUNCTION_TRACING is enabled.

MIPS frame pointers are generally considered to be useless because
they cannot be used to unwind the stack. Unfortunately the MIPS
function tracing code has bugs that are masked by the use of frame
pointers. This commit fixes the bugs so that MIPS frame pointers
don't need to be enabled.

The bugs are a result of the odd calling sequence used to call the trace
routine. This calling sequence is inserted into every traceable function
when the tracing CONFIG option is enabled. This sequence is generated
for 32bit MIPS platforms by the compiler via the "-pg" flag.

Part of the sequence is "addiu sp,sp,-8" in the delay slot after every
call to the trace routine "_mcount" (some legacy thing where 2 arguments
used to be pushed on the stack). The _mcount routine is expected to
adjust the sp by +8 before returning.  So when not disabled, the original
jalr and addiu will be there, so _mcount has to adjust sp.

The problem is that when tracing is disabled for a function, the
"jalr _mcount" instruction is replaced with a nop, but the
"addiu sp,sp,-8" is still executed and the stack pointer is left
trashed. When frame pointers are enabled the problem is masked
because any access to the stack is done through the frame
pointer and the stack pointer is restored from the frame pointer when
the function returns.

This patch writes two nops starting at the address of the "jalr _mcount"
instruction whenever tracing is disabled. This means that the
"addiu sp,sp.-8" will be converted to a nop along with the "jalr".  When
disabled, there will be two nops.

This is SMP safe because the first time this happens is during
ftrace_init() which is before any other processor has been started.
Subsequent calls to enable/disable tracing when other CPUs ARE running
will still be safe because the enable will only change the first nop
to a "jalr" and the disable, while writing 2 nops, will only be changing
the "jalr". This patch also stops using stop_machine() to call the
tracer enable/disable routines and calls them directly because the
routines are SMP safe.

When the kernel first boots we have to be able to handle the gcc
generated jalr, addui sequence until ftrace_init gets a chance to run
and change the sequence. At this point mcount just adjusts the stack
and returns. When ftrace_init runs, we convert the jalr/addui to nops.
Then whenever tracing is enabled we convert the first nop to a "jalr
mcount+8". The mcount+8 entry point skips the stack adjust.

[ralf@linux-mips.org: Folded in  Steven Rostedt's build fix.]

Signed-off-by: Al Cooper <alcooperx@gmail.com>
Cc: rostedt@goodmis.org
Cc: ddaney.cavm@gmail.com
Cc: linux-mips@linux-mips.org
Cc: linux-kernel@vger.kernel.org
Patchwork: https://patchwork.linux-mips.org/patch/4806/
Patchwork: https://patchwork.linux-mips.org/patch/4841/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2013-01-31 15:28:48 +01:00
..
alchemy MIPS: Alchemy: Make 32kHz and r4k timer coexist peacefully 2012-12-27 16:27:35 +01:00
ar7 MIPS: AR7: use part_probe_types to specificy the partition parser to use 2012-12-13 18:15:23 +01:00
ath79 USB: EHCI: remove ehci_port_power() routine 2012-10-31 12:48:07 -07:00
bcm47xx MIPS: BCM47xx: Enable SSB prerequisite SSB_DRIVER_PCICORE. 2013-01-16 16:29:36 +01:00
bcm63xx MIPS: BCM63XX: fix nvram checksum calculation 2012-12-12 18:57:49 +01:00
boot MIPS: Alchemy: Single kernel for DB1200/1300/1550 2012-10-11 11:11:20 +02:00
cavium-octeon MIPS: Octeon: Fix warning. 2013-01-22 18:07:46 +01:00
cobalt MIPS: Mark cascade and low level interrupts IRQF_NO_THREAD 2011-09-21 17:52:15 +02:00
configs Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2012-12-14 14:27:45 -08:00
dec MIPS: DEC: use IS_ENABLED() 2012-07-23 13:55:54 +01:00
emma Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
fw MIPS: Kconfig: Rename several firmware related config symbols. 2012-12-13 17:02:14 +01:00
include MIPS: DSP: Fix DSP mask for registers. 2013-01-24 13:20:09 +01:00
jazz Merge branch 'next/generic' into mips-for-linux-next 2012-01-11 15:41:47 +01:00
jz4740 MIPS: JZ4740: Forward declare struct uart_port in header. 2012-10-17 17:00:50 +02:00
kernel MIPS: Function tracer: Fix broken function tracing 2013-01-31 15:28:48 +01:00
lantiq MIPS: Lantiq: Fix cp0_perfcount_irq mapping 2013-01-30 21:28:28 +01:00
lasat Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
lib MIPS: delay.c: Check BITS_PER_LONG instead of __SIZEOF_LONG__ 2013-01-22 16:53:48 +01:00
loongson MIPS: Loongson 2: Sort out clock managment. 2012-08-01 18:10:06 +02:00
loongson1 Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2012-12-14 14:27:45 -08:00
math-emu MIPS: Fix for warning from FPU emulation code 2012-12-13 18:15:27 +01:00
mm mips: Move __virt_addr_valid() to a place for MIPS 64 2013-01-31 15:14:59 +01:00
mti-malta MIPS: Malta: Fix interupt number of CBUS UART. 2012-11-13 14:50:15 +01:00
mti-sead3 MIPS: drivers: remove __dev* attributes. 2013-01-03 15:57:09 -08:00
netlogic MIPS: Netlogic: Fix UP compilation on XLR 2013-01-30 21:44:18 +01:00
oprofile Merge branch 'mips-next' of http://dev.phrozen.org/githttp/mips-next into mips-for-linux-next 2012-12-13 19:40:13 +01:00
pci MIPS: AR71xx: Fix AR71XX_PCI_MEM_SIZE 2013-01-30 21:43:11 +01:00
pmc-sierra MIPS: PMC-Sierra Yosemite: Remove support. 2012-12-13 18:15:30 +01:00
pnx833x MIPS: PNX833x: use IS_ENABLED() macro 2012-07-23 13:55:53 +01:00
pnx8550 MIPS: PNX8550: use OHCI platform driver 2012-10-22 11:24:11 -07:00
power MIPS: Switch remaining assembler PAGE_SIZE users to <asm/asm-offsets.h>. 2012-12-28 17:04:16 +01:00
powertv MIPS: PowerTV: Fix build. 2012-12-13 18:15:28 +01:00
rb532 MIPS: RB532: Fix build of prom code. 2012-12-13 18:15:28 +01:00
sgi-ip22 MIPS: IP22/IP28: Fix build of EISA code. 2012-12-13 18:15:28 +01:00
sgi-ip27 mips: zero out pg_data_t when it's allocated 2012-07-31 18:42:49 -07:00
sgi-ip32 Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
sibyte MIPS: Kconfig: Rename several firmware related config symbols. 2012-12-13 17:02:14 +01:00
sni MIPS: drivers: remove __dev* attributes. 2013-01-03 15:57:09 -08:00
txx9 MIPS: drivers: remove __dev* attributes. 2013-01-03 15:57:09 -08:00
vr41xx Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
wrppmc MIPS: wrppmc: Fix build of PCI code. 2012-12-13 18:15:29 +01:00
Kbuild MIPS: Repair Kbuild make clean breakage. 2010-10-19 18:32:39 +01:00
Kbuild.platforms Merge branch 'ralf-3.7' of git://git.linux-mips.org/pub/scm/sjhill/linux-sjhill into mips-for-linux-next 2012-09-28 16:29:55 +02:00
Kconfig MIPS: 64-bit: Fix build if !CONFIG_MODULES 2013-01-03 00:03:08 +01:00
Kconfig.debug Fix typo in various Kconfig file 2012-04-16 14:40:08 +02:00
Makefile MIPS: PMC-Sierra Yosemite: Remove support. 2012-12-13 18:15:30 +01:00