[PATCH v2 00/44] x86/dumpstack: rewrite x86 stack dump code

From: Josh Poimboeuf
Date: Thu Aug 04 2016 - 18:34:13 EST


There are a lot of changes since last time. See the v2 changelog for
more details.

A git branch is available at:

https://github.com/jpoimboe/linux unwind-v2

Based on tip/master.

v2 changelog:
- split up several of the patches and reorder them with lower-risk
patches first
- add a lot more comments
- remove the 64-byte gap at the end of the irq stack
- fix some existing ftrace function graph unwinding issues
- fix an existing bug in kernel_stack_pointer()
- clarify the origins of the stack_info "next stack" pointers
- do visit_mask checking in get_stack_info() instead of in_*_stack()
- add some new unwinder warnings
- remove uses of test_and_set_bit()
- dont print regs->ip twice
- remove unwind_state.sp
- have unwind_get_return_address() validate the return address
- change /proc/pid/stack to use %pB
- several minor cleanups and fixes

----

The x86 stack dump code is a bit of a mess. dump_trace() uses
callbacks, and each user of it seems to have slightly different
requirements, so there are several slightly different callbacks floating
around.

Also there are some upcoming features which will require more changes to
the stack dump code: reliable stack detection for live patching,
hardened user copy, and the DWARF unwinder. Each of those features
would at least need more callbacks and/or callback interfaces, resulting
in a much bigger mess than what we have today.

Before doing all that, we should try to clean things up and replace
dump_trace() with something cleaner and more flexible.

The new unwinder is a simple state machine which was heavily inspired by
a suggestion from Andy Lutomirski:

https://lkml.kernel.org/r/CALCETrUbNTqaM2LRyXGRx=kVLRPeY5A3Pc6k4TtQxF320rUT=w@xxxxxxxxxxxxxx

It's also similar to the libunwind API:

http://www.nongnu.org/libunwind/man/libunwind(3).html

Some if its advantages:

- simplicity: no more callback sprawl and less code duplication.

- flexibility: allows the caller to stop and inspect the stack state at
each step in the unwinding process.

- modularity: the unwinder code, console stack dump code, and stack
metadata analysis code are all better separated so that changing one
of them shouldn't have much of an impact on any of the others.


Josh Poimboeuf (44):
x86/dumpstack: remove show_trace()
x86/asm/head: remove unused init_rsp variable
x86/asm/head: rename 'stack_start' -> 'initial_stack'
x86/asm/head: use a common function for starting CPUs
x86/dumpstack: make printk_stack_address() more generally useful
x86/dumpstack: add IRQ_USABLE_STACK_SIZE define
x86/dumpstack: remove extra brackets around "<EOE>"
x86/dumpstack: fix irq stack bounds calculation in
show_stack_log_lvl()
x86/dumpstack: fix x86_32 kernel_stack_pointer() previous stack access
x86/dumpstack: add get_stack_pointer() and get_frame_pointer()
x86/dumpstack: remove unnecessary stack pointer arguments
x86: move _stext marker to before head code
x86/asm/head: remove useless zeroed word
x86/asm/head: put real return address on idle task stack
perf/x86: check perf_callchain_store() error
oprofile/x86: add regs->ip to oprofile trace
proc: fix return address printk conversion specifer in
/proc/<pid>/stack
ftrace: remove CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST from config
ftrace: only allocate the ret_stack 'fp' field when needed
ftrace: add return address pointer to ftrace_ret_stack
ftrace: add ftrace_graph_ret_addr() stack unwinding helpers
x86/dumpstack/ftrace: convert dump_trace() callbacks to use
ftrace_graph_ret_addr()
ftrace/x86: implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
x86/dumpstack/ftrace: mark function graph handler function as
unreliable
x86/dumpstack/ftrace: don't print unreliable addresses in
print_context_stack_bp()
x86/dumpstack: allow preemption in show_stack_log_lvl() and
dump_trace()
x86/dumpstack: simplify in_exception_stack()
x86/dumpstack: add get_stack_info() interface
x86/dumpstack: add recursion checking for all stacks
x86/unwind: add new unwind interface and implementations
perf/x86: convert perf_callchain_kernel() to use the new unwinder
x86/stacktrace: convert save_stack_trace_*() to use the new unwinder
oprofile/x86: convert x86_backtrace() to use the new unwinder
x86/dumpstack: convert show_trace_log_lvl() to use the new unwinder
x86/dumpstack: remove dump_trace() and related callbacks
x86/entry/unwind: encode pt_regs pointer in frame pointer
x86/unwind: detect syscall entry regs
x86/dumpstack: print stack identifier on its own line
x86/dumpstack: print any pt_regs found on the stack
x86: remove 64-byte gap at end of irq stack
x86/asm/head: standardize the end of the stack for idle tasks
x86/unwind: warn on kernel stack corruption
x86/unwind: warn on bad stack return address
x86/unwind: warn if stack grows up

Documentation/trace/ftrace-design.txt | 11 ++
arch/arm/kernel/ftrace.c | 2 +-
arch/arm64/kernel/entry-ftrace.S | 2 +-
arch/arm64/kernel/ftrace.c | 2 +-
arch/blackfin/kernel/ftrace-entry.S | 4 +-
arch/blackfin/kernel/ftrace.c | 2 +-
arch/microblaze/kernel/ftrace.c | 2 +-
arch/mips/kernel/ftrace.c | 4 +-
arch/parisc/kernel/ftrace.c | 2 +-
arch/powerpc/kernel/ftrace.c | 3 +-
arch/s390/kernel/ftrace.c | 3 +-
arch/sh/kernel/ftrace.c | 2 +-
arch/sparc/Kconfig | 1 -
arch/sparc/include/asm/ftrace.h | 4 +
arch/sparc/kernel/ftrace.c | 2 +-
arch/tile/kernel/ftrace.c | 2 +-
arch/x86/Kconfig | 1 -
arch/x86/entry/calling.h | 21 +++
arch/x86/entry/entry_64.S | 10 +-
arch/x86/events/core.c | 36 ++--
arch/x86/include/asm/ftrace.h | 3 +
arch/x86/include/asm/kdebug.h | 2 -
arch/x86/include/asm/page_64_types.h | 16 +-
arch/x86/include/asm/realmode.h | 2 +-
arch/x86/include/asm/smp.h | 3 -
arch/x86/include/asm/stacktrace.h | 114 ++++++------
arch/x86/include/asm/unwind.h | 104 +++++++++++
arch/x86/kernel/Makefile | 6 +
arch/x86/kernel/acpi/sleep.c | 2 +-
arch/x86/kernel/cpu/common.c | 2 +-
arch/x86/kernel/dumpstack.c | 272 ++++++++++++++---------------
arch/x86/kernel/dumpstack_32.c | 138 ++++++++-------
arch/x86/kernel/dumpstack_64.c | 319 ++++++++++------------------------
arch/x86/kernel/ftrace.c | 2 +-
arch/x86/kernel/head_32.S | 8 +-
arch/x86/kernel/head_64.S | 33 ++--
arch/x86/kernel/ptrace.c | 4 +-
arch/x86/kernel/setup_percpu.c | 2 +-
arch/x86/kernel/smpboot.c | 2 +-
arch/x86/kernel/stacktrace.c | 74 ++++----
arch/x86/kernel/unwind_frame.c | 222 +++++++++++++++++++++++
arch/x86/kernel/unwind_guess.c | 40 +++++
arch/x86/kernel/vmlinux.lds.S | 2 +-
arch/x86/oprofile/backtrace.c | 49 +++---
fs/proc/base.c | 2 +-
include/linux/ftrace.h | 17 +-
kernel/trace/Kconfig | 5 -
kernel/trace/trace_functions_graph.c | 67 ++++++-
48 files changed, 977 insertions(+), 651 deletions(-)
create mode 100644 arch/x86/include/asm/unwind.h
create mode 100644 arch/x86/kernel/unwind_frame.c
create mode 100644 arch/x86/kernel/unwind_guess.c

--
2.7.4