x86/debug changes for v4.8
Subsystems (4)
Linus,
Please pull the latest x86-debug-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-debug-for-linus
# HEAD: 81c2949f7fdcf8ff681326669afde24962232670 x86/dumpstack: Add show_stack_regs() and use it
A number of stackdump enhancements.
out-of-topic modifications in x86-debug-for-linus:
----------------------------------------------------
include/linux/printk.h # 069f0cd00df0: printk: Make the printk*once
Thanks,
Ingo
------------------>
Andy Lutomirski (1):
x86/dumpstack: Honor supplied @regs arg
Borislav Petkov (2):
printk: Make the printk*once() variants return a value x86/dumpstack: Add show_stack_regs() and use it
arch/x86/include/asm/kdebug.h | 1 + arch/x86/kernel/dumpstack.c | 5 +++++ arch/x86/kernel/dumpstack_32.c | 4 +++- arch/x86/kernel/dumpstack_64.c | 4 +++- arch/x86/mm/extable.c | 13 ++++++++----- include/linux/printk.h | 17 ++++++++++++----- 6 files changed, 32 insertions(+), 12 deletions(-)
arch/x86/include/asm/kdebug.h +1 -0
@@ -26,6 +26,7 @@ extern void die(const char *, struct pt_regs *,long);extern int __must_check __die (const char *,struct pt_regs *,long );extern void show_trace (struct task_struct *t,struct pt_regs *regs,unsigned long *sp,unsigned long bp); +extern void show_stack_regs (struct pt_regs *regs);extern void __show_regs (struct pt_regs *regs,int all);extern unsigned long oops_begin (void );extern void oops_end (unsigned long ,struct pt_regs *,int signr);
arch/x86/kernel/dumpstack.c +5 -0
@@ -197,6 +197,11 @@ void show_stack(struct task_struct *task, unsigned long *sp)show_stack_log_lvl (task,NULL , sp, bp,"" ); } +void show_stack_regs (struct pt_regs *regs) +{ +show_stack_log_lvl (current, regs, (unsigned long *)regs->sp, regs->bp,"" ); +} +static arch_spinlock_t die_lock = __ARCH_SPIN_LOCK_UNLOCKED;static int die_owner =-1 ;static unsigned int die_nest_count;
arch/x86/kernel/dumpstack_32.c +3 -1
@@ -96,7 +96,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,int i;if (sp ==NULL ) { -if (task) +if (regs) + sp = (unsigned long *)regs->sp; +else if (task) sp = (unsigned long *)task->thread.sp;else sp = (unsigned long *)&sp;
arch/x86/kernel/dumpstack_64.c +3 -1
@@ -264,7 +264,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,* back trace for this cpu: */ if (sp ==NULL ) { -if (task) +if (regs) + sp = (unsigned long *)regs->sp; +else if (task) sp = (unsigned long *)task->thread.sp;else sp = (unsigned long *)&sp;
arch/x86/mm/extable.c +8 -5
@@ -1,6 +1,7 @@#include <linux/module.h> #include <asm/uaccess.h> #include <asm/traps.h> +#include <asm/kdebug.h> typedef bool (*ex_handler_t )(const struct exception_table_entry *,struct pt_regs *,int );
@@ -46,8 +47,9 @@ EXPORT_SYMBOL(ex_handler_ext);bool ex_handler_rdmsr_unsafe (const struct exception_table_entry *fixup,struct pt_regs *regs,int trapnr) { -WARN_ONCE (1 ,"unchecked MSR access error: RDMSR from 0x%x\n" , - (unsigned int )regs->cx); +if (pr_warn_once ("unchecked MSR access error: RDMSR from 0x%x at rIP: 0x%lx (%pF)\n" , + (unsigned int )regs->cx, regs->ip, (void *)regs->ip)) +show_stack_regs (regs);/* Pretend that the read succeeded and returned 0. */ regs->ip =ex_fixup_addr (fixup);
@@ -60,9 +62,10 @@ EXPORT_SYMBOL(ex_handler_rdmsr_unsafe);bool ex_handler_wrmsr_unsafe (const struct exception_table_entry *fixup,struct pt_regs *regs,int trapnr) { -WARN_ONCE (1 ,"unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x)\n" , - (unsigned int )regs->cx, - (unsigned int )regs->dx, (unsigned int )regs->ax); +if (pr_warn_once ("unchecked MSR access error: WRMSR to 0x%x (tried to write 0x%08x%08x) at rIP: 0x%lx (%pF)\n" , + (unsigned int )regs->cx, (unsigned int )regs->dx, + (unsigned int )regs->ax, regs->ip, (void *)regs->ip)) +show_stack_regs (regs);/* Pretend that the write succeeded. */ regs->ip =ex_fixup_addr (fixup);
include/linux/printk.h +12 -5
@@ -108,11 +108,14 @@ struct va_format {* Dummy printk for disabled debugging statements to use whilst maintaining * gcc's format checking. */ -#define no_printk (fmt, ...) \ -do { \ - if (0) \ - printk(fmt, ##__VA_ARGS__); \ -} while (0) +#define no_printk (fmt, ...) \ +({ \ + do { \ + if (0) \ + printk(fmt, ##__VA_ARGS__); \ + } while (0); \ + 0; \ +})#ifdef CONFIG_EARLY_PRINTK extern asmlinkage __printf(1, 2)
@@ -309,20 +312,24 @@ extern asmlinkage void dump_stack(void) __cold;#define printk_once (fmt, ...) \ ({ \ static bool __print_once __read_mostly; \ + bool __ret_print_once = !__print_once; \ \ if (!__print_once) { \ __print_once = true; \ printk(fmt, ##__VA_ARGS__); \ } \ + unlikely(__ret_print_once); \ })#define printk_deferred_once (fmt, ...) \ ({ \ static bool __print_once __read_mostly; \ + bool __ret_print_once = !__print_once; \ \ if (!__print_once) { \ __print_once = true; \ printk_deferred(fmt, ##__VA_ARGS__); \ } \ + unlikely(__ret_print_once); \ })#else #define printk_once (fmt, ...) \