From fd3e0bbc6052ca9747a5332b382584ece83aab6d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 17 Apr 2008 14:35:00 +1000 Subject: [PATCH] [POWERPC] Stacktrace support for lockdep This adds stacktrace support for powerpc, which will be needed for lockdep. Signed-off-by: Christoph Hellwig Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/Kconfig | 4 +++ arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/stacktrace.c | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 arch/powerpc/kernel/stacktrace.c diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 7f2f126d1c2..ecca20d17a7 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -49,6 +49,10 @@ config IRQ_PER_CPU bool default y +config STACKTRACE_SUPPORT + bool + default y + config RWSEM_GENERIC_SPINLOCK bool diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index c1baf9d5903..5183a9012a0 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -67,6 +67,7 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o +obj-$(CONFIG_STACKTRACE) += stacktrace.o pci64-$(CONFIG_PPC64) += pci_dn.o isa-bridge.o obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ diff --git a/arch/powerpc/kernel/stacktrace.c b/arch/powerpc/kernel/stacktrace.c new file mode 100644 index 00000000000..e3638eeaaae --- /dev/null +++ b/arch/powerpc/kernel/stacktrace.c @@ -0,0 +1,47 @@ +/* + * Stack trace utility + * + * Copyright 2008 Christoph Hellwig, IBM Corp. + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include + +/* + * Save stack-backtrace addresses into a stack_trace buffer. + */ +void save_stack_trace(struct stack_trace *trace) +{ + unsigned long sp; + + asm("mr %0,1" : "=r" (sp)); + + for (;;) { + unsigned long *stack = (unsigned long *) sp; + unsigned long newsp, ip; + + if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) + return; + + newsp = stack[0]; + ip = stack[STACK_FRAME_LR_SAVE]; + + if (!trace->skip) + trace->entries[trace->nr_entries++] = ip; + else + trace->skip--; + + if (trace->nr_entries >= trace->max_entries) + return; + + sp = newsp; + } +} -- 2.41.1