--- zzzz-none-000/linux-3.10.107/arch/um/kernel/sysrq.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/um/kernel/sysrq.c 2021-02-04 17:41:59.000000000 +0000 @@ -1,6 +1,10 @@ /* * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) - * Licensed under the GPL + * Copyright (C) 2013 Richard Weinberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. */ #include @@ -8,59 +12,48 @@ #include #include #include +#include +#include -/* Catch non-i386 SUBARCH's. */ -#if !defined(CONFIG_UML_X86) || defined(CONFIG_64BIT) -void show_trace(struct task_struct *task, unsigned long * stack) +static void _print_addr(void *data, unsigned long address, int reliable) { - unsigned long addr; - - if (!stack) { - stack = (unsigned long*) &stack; - WARN_ON(1); - } - - printk(KERN_INFO "Call Trace: \n"); - while (((long) stack & (THREAD_SIZE-1)) != 0) { - addr = *stack; - if (__kernel_text_address(addr)) { - printk(KERN_INFO "%08lx: [<%08lx>]", - (unsigned long) stack, addr); - print_symbol(KERN_CONT " %s", addr); - printk(KERN_CONT "\n"); - } - stack++; - } - printk(KERN_INFO "\n"); + pr_info(" [<%08lx>]", address); + pr_cont(" %s", reliable ? "" : "? "); + print_symbol("%s", address); + pr_cont("\n"); } -#endif -/*Stolen from arch/i386/kernel/traps.c */ -static const int kstack_depth_to_print = 24; +static const struct stacktrace_ops stackops = { + .address = _print_addr +}; -/* This recently started being used in arch-independent code too, as in - * kernel/sched.c.*/ -void show_stack(struct task_struct *task, unsigned long *esp) +void show_stack(struct task_struct *task, unsigned long *stack) { - unsigned long *stack; + unsigned long *sp = stack; + struct pt_regs *segv_regs = current->thread.segv_regs; int i; - if (esp == NULL) { - if (task != current && task != NULL) { - esp = (unsigned long *) KSTK_ESP(task); - } else { - esp = (unsigned long *) &esp; - } + if (!segv_regs && os_is_signal_stack()) { + pr_err("Received SIGSEGV in SIGSEGV handler," + " aborting stack trace!\n"); + return; } - stack = esp; - for (i = 0; i < kstack_depth_to_print; i++) { + if (!stack) + sp = get_stack_pointer(task, segv_regs); + + pr_info("Stack:\n"); + stack = sp; + for (i = 0; i < 3 * STACKSLOTS_PER_LINE; i++) { if (kstack_end(stack)) break; - if (i && ((i % 8) == 0)) - printk(KERN_INFO " "); - printk(KERN_CONT "%08lx ", *stack++); + if (i && ((i % STACKSLOTS_PER_LINE) == 0)) + pr_cont("\n"); + pr_cont(" %08lx", *stack++); } + pr_cont("\n"); - show_trace(task, esp); + pr_info("Call Trace:\n"); + dump_trace(current, &stackops, NULL); + pr_info("\n"); }