kernel-ark/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
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
bmips_vec.S
branch.c
cevt-bcm1480.c
cevt-ds1287.c
cevt-gt641xx.c
cevt-r4k.c MIPS: Add EIC support for GIC. 2012-09-13 15:43:49 -05:00
cevt-sb1250.c
cevt-smtc.c
cevt-txx9.c
cpu-bugs64.c
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
csrc-ioasic.c
csrc-powertv.c
csrc-r4k.c
csrc-sb1250.c
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
i8259.c
irq_cpu.c
irq_txx9.c
irq-gic.c MIPS: Make VPE count to be one-based. 2012-09-13 15:43:51 -05:00
irq-gt641xx.c
irq-msc01.c
irq-rm7000.c
irq.c
jump_label.c
kgdb.c mips,kgdb: fix recursive page fault with CONFIG_KPROBES 2012-10-12 06:37:34 -05:00
kprobes.c
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-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
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
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
ptrace.c
r4k_fpu.S
r4k_switch.S MIPS: Don't include <asm/page.h> unnecessarily. 2012-12-28 17:04:04 +01:00
r2300_fpu.S
r2300_switch.S MIPS: Don't include <asm/page.h> unnecessarily. 2012-12-28 17:04:04 +01:00
r6000_fpu.S
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
rtlx.c
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
smp.c MIPS: drivers: remove __dev* attributes. 2013-01-03 15:57:09 -08:00
smtc-asm.S
smtc-proc.c
smtc.c MIPS: SMTC: Support for Multi-threaded FPUs 2012-07-23 13:55:53 +01:00
spinlock_test.c
spram.c
stacktrace.c
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
topology.c
traps.c MIPS: Handle COP3 Unusable exception as COP1X for FP emulation 2012-12-13 18:15:27 +01:00
unaligned.c
vdso.c
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