linux/arch/mips/kernel
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
..
cpufreq MIPS: Loongson 2: Sort out clock managment. 2012-08-01 18:10:06 +02:00
.gitignore
8250-platform.c mips: remove needless include of module.h from core kernel files. 2011-10-31 19:30:57 -04:00
asm-offsets.c MIPS: Include PAGE_S{IZE,HIFT} in <asm/offset.h>. 2012-12-28 17:04:10 +01:00
binfmt_elfn32.c
binfmt_elfo32.c MIPS: 64-bit: Fix o32 core dump 2009-07-03 15:45:27 +01:00
bmips_vec.S MIPS: BMIPS: Add SMP support code for BMIPS43xx/BMIPS5000 2011-12-07 22:03:18 +00:00
branch.c MIPS Kprobes: Refactor branch emulation 2011-12-07 22:04:03 +00:00
cevt-bcm1480.c MIPS: irq: Remove IRQF_DISABLED 2011-12-07 22:03:45 +00:00
cevt-ds1287.c MIPS: irq: Remove IRQF_DISABLED 2011-12-07 22:03:45 +00:00
cevt-gt641xx.c MIPS: irq: Remove IRQF_DISABLED 2011-12-07 22:03:45 +00:00
cevt-r4k.c MIPS: Add EIC support for GIC. 2012-09-13 15:43:49 -05:00
cevt-sb1250.c MIPS: irq: Remove IRQF_DISABLED 2011-12-07 22:03:45 +00:00
cevt-smtc.c MIPS: Add missing #inclusions of <linux/irq.h> 2010-10-07 14:08:54 +01:00
cevt-txx9.c MIPS: irq: Remove IRQF_DISABLED 2011-12-07 22:03:45 +00:00
cpu-bugs64.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
cpu-probe.c MIPS: R3000/R3081: Fix CPU detection. 2012-12-05 19:58:54 +01:00
crash_dump.c MIPS: Octeon: Add kexec and kdump support 2012-12-13 17:00:39 +01:00
crash.c MIPS: kdump: Add support 2012-12-13 16:46:47 +01:00
csrc-bcm1480.c mips: convert to clocksource_register_hz/khz 2011-02-21 13:33:50 -08:00
csrc-ioasic.c mips: convert to clocksource_register_hz/khz 2011-02-21 13:33:50 -08:00
csrc-powertv.c mips: convert to clocksource_register_hz/khz 2011-02-21 13:33:50 -08:00
csrc-r4k.c mips: convert to clocksource_register_hz/khz 2011-02-21 13:33:50 -08:00
csrc-sb1250.c mips: convert to clocksource_register_hz/khz 2011-02-21 13:33:50 -08:00
early_printk.c
entry.S Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal 2012-12-12 12:22:13 -08:00
ftrace.c MIPS: Function tracer: Fix broken function tracing 2013-01-31 15:28:48 +01:00
genex.S MIPS: Switch remaining assembler PAGE_SIZE users to <asm/asm-offsets.h>. 2012-12-28 17:04:16 +01:00
gpio_txx9.c
head.S MIPS: Don't include <asm/page.h> unnecessarily. 2012-12-28 17:04:04 +01:00
i8253.c MIPS: irq: Remove IRQF_DISABLED 2011-12-07 22:03:45 +00:00
i8259.c MIPS: i8259: Mark cascade interrupt non-threaded 2011-09-21 17:52:28 +02:00
irq_cpu.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
irq_txx9.c MIPS: Convert the irq functions to the new names 2011-03-29 14:48:07 +02:00
irq-gic.c MIPS: Make VPE count to be one-based. 2012-09-13 15:43:51 -05:00
irq-gt641xx.c MIPS: Convert the irq functions to the new names 2011-03-29 14:48:07 +02:00
irq-msc01.c mips: remove needless include of module.h from core kernel files. 2011-10-31 19:30:57 -04:00
irq-rm7000.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
irq.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
jump_label.c MIPS: jump label: Add MIPS support. 2011-01-18 19:30:24 +01:00
kgdb.c mips,kgdb: fix recursive page fault with CONFIG_KPROBES 2012-10-12 06:37:34 -05:00
kprobes.c MIPS Kprobes: Support branch instructions probing 2011-12-07 22:04:03 +00:00
linux32.c flagday: kill pt_regs argument of do_fork() 2012-11-29 00:01:08 -05:00
machine_kexec.c MIPS: kdump: Add support 2012-12-13 16:46:47 +01:00
Makefile MIPS: PMC-Sierra Yosemite: Remove support. 2012-12-13 18:15:30 +01:00
mcount.S MIPS: Function tracer: Fix broken function tracing 2013-01-31 15:28:48 +01:00
mips_ksyms.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2012-12-14 14:27:45 -08:00
mips_machine.c MIPS: Add generic support for multiple machines within a single kernel 2011-01-18 19:30:21 +01:00
mips-mt-fpaff.c MIPS: MT: Fix build with CONFIG_UIDGID_STRICT_TYPE_CHECKS=y 2012-12-13 18:15:26 +01:00
mips-mt.c Merge branch 'master' into for-next 2012-04-08 21:48:52 +02:00
module-rela.c MIPS: Fix module.c build for 32 bit 2012-09-28 14:31:02 +09:30
module.c MIPS: Fix module.c build for 32 bit 2012-09-28 14:31:02 +09:30
octeon_switch.S MIPS: Don't include <asm/page.h> unnecessarily. 2012-12-28 17:04:04 +01:00
perf_event_mipsxx.c MIPS: perf: Fix build failure in XLP perf support. 2012-12-27 16:27:35 +01:00
perf_event.c MIPS: perf: Reorganize contents of perf support files. 2011-10-24 23:34:26 +01:00
proc.c MIPS: proc: Cleanup printing of ASEs. 2012-10-11 11:10:43 +02:00
process.c Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2012-12-14 14:27:45 -08:00
prom.c MIPS: Prune some target specific code out of prom.c 2012-07-23 13:54:52 +01:00
ptrace32.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
ptrace.c seccomp: ignore secure_computing return values 2012-04-18 12:24:50 +10:00
r4k_fpu.S update David Miller's old email address 2011-04-06 06:19:38 -07:00
r4k_switch.S MIPS: Don't include <asm/page.h> unnecessarily. 2012-12-28 17:04:04 +01:00
r2300_fpu.S update David Miller's old email address 2011-04-06 06:19:38 -07:00
r2300_switch.S MIPS: Don't include <asm/page.h> unnecessarily. 2012-12-28 17:04:04 +01:00
r6000_fpu.S update David Miller's old email address 2011-04-06 06:19:38 -07:00
relocate_kernel.S MIPS: Switch remaining assembler PAGE_SIZE users to <asm/asm-offsets.h>. 2012-12-28 17:04:16 +01:00
reset.c mips: migrate core kernel file from module.h --> export.h 2011-10-31 19:30:56 -04:00
rtlx.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
scall32-o32.S MIPS: Wire up finit_module syscall. 2012-12-28 17:04:38 +01:00
scall64-64.S MIPS: Wire up finit_module syscall. 2012-12-28 17:04:38 +01:00
scall64-n32.S MIPS: Wire up finit_module syscall. 2012-12-28 17:04:38 +01:00
scall64-o32.S MIPS: Wire up finit_module syscall. 2012-12-28 17:04:38 +01:00
setup.c MIPS: kdump: Add support 2012-12-13 16:46:47 +01:00
signal32.c most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set 2012-06-01 12:58:51 -04:00
signal_n32.c most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set 2012-06-01 12:58:51 -04:00
signal-common.h most of set_current_blocked() callers want SIGKILL/SIGSTOP removed from set 2012-06-01 12:58:51 -04:00
signal.c MIPS: Fix harmlessly missing else statement. 2012-12-12 16:52:07 +01:00
smp-bmips.c MIPS: BMIPS: delay irq enable to ->smp_finish() 2012-07-19 11:23:44 +02:00
smp-cmp.c MIPS: CMP: Fix physical core number calculation logic 2012-10-18 11:45:41 +02:00
smp-mt.c MIPS: Fix build error for non-malta VSMP kernel 2012-08-22 23:46:38 +02:00
smp-up.c cpumask: arch_send_call_function_ipi_mask: mips 2009-09-24 09:34:45 +09:30
smp.c MIPS: drivers: remove __dev* attributes. 2013-01-03 15:57:09 -08:00
smtc-asm.S
smtc-proc.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
smtc.c MIPS: SMTC: Support for Multi-threaded FPUs 2012-07-23 13:55:53 +01:00
spinlock_test.c mips: migrate core kernel file from module.h --> export.h 2011-10-31 19:30:56 -04:00
spram.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
stacktrace.c mips: migrate core kernel file from module.h --> export.h 2011-10-31 19:30:56 -04:00
sync-r4k.c MIPS: Synchronize MIPS count one CPU at a time 2012-08-17 10:57:28 +02:00
syscall.c flagday: kill pt_regs argument of do_fork() 2012-11-29 00:01:08 -05:00
time.c mips: migrate core kernel file from module.h --> export.h 2011-10-31 19:30:56 -04:00
topology.c MIPS: Add arch generic CPU hotplug 2009-06-24 18:34:40 +01:00
traps.c MIPS: Handle COP3 Unusable exception as COP1X for FP emulation 2012-12-13 18:15:27 +01:00
unaligned.c Disintegrate asm/system.h for MIPS 2012-03-28 18:30:02 +01:00
vdso.c coredump: remove VM_ALWAYSDUMP flag 2012-03-23 16:58:42 -07:00
vmlinux.lds.S MIPS: Switch remaining assembler PAGE_SIZE users to <asm/asm-offsets.h>. 2012-12-28 17:04:16 +01:00
vpe.c MIPS: vpe.c: Fix null pointer dereference in print arguments. 2013-01-16 16:29:23 +01:00
watch.c