aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/dumpstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
-rw-r--r--arch/x86/kernel/dumpstack.c49
1 files changed, 48 insertions, 1 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index a2d8a3908670..18fa9d74c182 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -24,7 +24,7 @@
int panic_on_unrecovered_nmi;
int panic_on_io_nmi;
-unsigned int code_bytes = 64;
+static unsigned int code_bytes = 64;
static int die_counter;
bool in_task_stack(unsigned long *stack, struct task_struct *task,
@@ -375,3 +375,50 @@ static int __init code_bytes_setup(char *s)
return 1;
}
__setup("code_bytes=", code_bytes_setup);
+
+void show_regs(struct pt_regs *regs)
+{
+ bool all = true;
+ int i;
+
+ show_regs_print_info(KERN_DEFAULT);
+
+ if (IS_ENABLED(CONFIG_X86_32))
+ all = !user_mode(regs);
+
+ __show_regs(regs, all);
+
+ /*
+ * When in-kernel, we also print out the stack and code at the
+ * time of the fault..
+ */
+ if (!user_mode(regs)) {
+ unsigned int code_prologue = code_bytes * 43 / 64;
+ unsigned int code_len = code_bytes;
+ unsigned char c;
+ u8 *ip;
+
+ show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT);
+
+ printk(KERN_DEFAULT "Code: ");
+
+ ip = (u8 *)regs->ip - code_prologue;
+ if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
+ /* try starting at IP */
+ ip = (u8 *)regs->ip;
+ code_len = code_len - code_prologue + 1;
+ }
+ for (i = 0; i < code_len; i++, ip++) {
+ if (ip < (u8 *)PAGE_OFFSET ||
+ probe_kernel_address(ip, c)) {
+ pr_cont(" Bad RIP value.");
+ break;
+ }
+ if (ip == (u8 *)regs->ip)
+ pr_cont("<%02x> ", c);
+ else
+ pr_cont("%02x ", c);
+ }
+ }
+ pr_cont("\n");
+}