diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/dwarf.c | 24 | ||||
-rw-r--r-- | arch/sh/kernel/irq.c | 3 | ||||
-rw-r--r-- | arch/sh/kernel/sh_ksyms_32.c | 14 |
3 files changed, 39 insertions, 2 deletions
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 03b3616c80a..d76a23170db 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -20,6 +20,7 @@ #include <linux/list.h> #include <linux/mempool.h> #include <linux/mm.h> +#include <linux/ftrace.h> #include <asm/dwarf.h> #include <asm/unwinder.h> #include <asm/sections.h> @@ -554,9 +555,30 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, * NOTE: the return address is guaranteed to be setup by the * time this function makes its first function call. */ - if (!pc && !prev) + if (!pc || !prev) pc = (unsigned long)current_text_addr(); +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + /* + * If our stack has been patched by the function graph tracer + * then we might see the address of return_to_handler() where we + * expected to find the real return address. + */ + if (pc == (unsigned long)&return_to_handler) { + int index = current->curr_ret_stack; + + /* + * We currently have no way of tracking how many + * return_to_handler()'s we've seen. If there is more + * than one patched return address on our stack, + * complain loudly. + */ + WARN_ON(index > 0); + + pc = current->ret_stack[index].ret; + } +#endif + frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC); if (!frame) { printk(KERN_ERR "Unable to allocate a dwarf frame\n"); diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c index 7cb933ba495..eac7da772fc 100644 --- a/arch/sh/kernel/irq.c +++ b/arch/sh/kernel/irq.c @@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/kernel_stat.h> #include <linux/seq_file.h> +#include <linux/ftrace.h> #include <asm/processor.h> #include <asm/machvec.h> #include <asm/uaccess.h> @@ -106,7 +107,7 @@ static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly; static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; #endif -asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs) +asmlinkage __irq_entry int do_IRQ(unsigned int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); #ifdef CONFIG_IRQSTACKS diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 86c27042835..444cce3ae92 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c @@ -85,6 +85,20 @@ DECLARE_EXPORT(__movstr_i4_even); DECLARE_EXPORT(__movstr_i4_odd); DECLARE_EXPORT(__movstrSI12_i4); DECLARE_EXPORT(__movmem); +DECLARE_EXPORT(__movmemSI8); +DECLARE_EXPORT(__movmemSI12); +DECLARE_EXPORT(__movmemSI16); +DECLARE_EXPORT(__movmemSI20); +DECLARE_EXPORT(__movmemSI24); +DECLARE_EXPORT(__movmemSI28); +DECLARE_EXPORT(__movmemSI32); +DECLARE_EXPORT(__movmemSI36); +DECLARE_EXPORT(__movmemSI40); +DECLARE_EXPORT(__movmemSI44); +DECLARE_EXPORT(__movmemSI48); +DECLARE_EXPORT(__movmemSI52); +DECLARE_EXPORT(__movmemSI56); +DECLARE_EXPORT(__movmemSI60); DECLARE_EXPORT(__movmem_i4_even); DECLARE_EXPORT(__movmem_i4_odd); DECLARE_EXPORT(__movmemSI12_i4); |