aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/dumpstack.c
diff options
context:
space:
mode:
authorBorislav Petkov <bp@suse.de>2018-04-17 12:11:18 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-04-26 10:15:26 -0400
commitf0a1d7c11c3ebe2f601b448d13e7fbc3a0364a03 (patch)
treeb792e07a725ea960c36bd7e389cd8518ec5b7e0b /arch/x86/kernel/dumpstack.c
parent5df61707f0bdf8dce714a14806740e6abf2114c7 (diff)
x86/dumpstack: Carve out code-dumping into a function
No functionality change, carve it out into a separate function for later changes. Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andy Lutomirski <luto@amacapital.net> Link: https://lkml.kernel.org/r/20180417161124.5294-4-bp@alien8.de
Diffstat (limited to 'arch/x86/kernel/dumpstack.c')
-rw-r--r--arch/x86/kernel/dumpstack.c57
1 files changed, 30 insertions, 27 deletions
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 579455c2b91e..eb9d6c00a52f 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -70,6 +70,35 @@ static void printk_stack_address(unsigned long address, int reliable,
70 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address); 70 printk("%s %s%pB\n", log_lvl, reliable ? "" : "? ", (void *)address);
71} 71}
72 72
73static void show_opcodes(u8 *rip)
74{
75 unsigned int code_prologue = OPCODE_BUFSIZE * 43 / 64;
76 unsigned int code_len = OPCODE_BUFSIZE;
77 unsigned char c;
78 u8 *ip;
79 int i;
80
81 printk(KERN_DEFAULT "Code: ");
82
83 ip = (u8 *)rip - code_prologue;
84 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
85 /* try starting at IP */
86 ip = (u8 *)rip;
87 code_len = code_len - code_prologue + 1;
88 }
89 for (i = 0; i < code_len; i++, ip++) {
90 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
91 pr_cont(" Bad RIP value.");
92 break;
93 }
94 if (ip == (u8 *)rip)
95 pr_cont("<%02x> ", c);
96 else
97 pr_cont("%02x ", c);
98 }
99 pr_cont("\n");
100}
101
73void show_iret_regs(struct pt_regs *regs) 102void show_iret_regs(struct pt_regs *regs)
74{ 103{
75 printk(KERN_DEFAULT "RIP: %04x:%pS\n", (int)regs->cs, (void *)regs->ip); 104 printk(KERN_DEFAULT "RIP: %04x:%pS\n", (int)regs->cs, (void *)regs->ip);
@@ -359,7 +388,6 @@ void die(const char *str, struct pt_regs *regs, long err)
359void show_regs(struct pt_regs *regs) 388void show_regs(struct pt_regs *regs)
360{ 389{
361 bool all = true; 390 bool all = true;
362 int i;
363 391
364 show_regs_print_info(KERN_DEFAULT); 392 show_regs_print_info(KERN_DEFAULT);
365 393
@@ -373,32 +401,7 @@ void show_regs(struct pt_regs *regs)
373 * time of the fault.. 401 * time of the fault..
374 */ 402 */
375 if (!user_mode(regs)) { 403 if (!user_mode(regs)) {
376 unsigned int code_prologue = OPCODE_BUFSIZE * 43 / 64;
377 unsigned int code_len = OPCODE_BUFSIZE;
378 unsigned char c;
379 u8 *ip;
380
381 show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT); 404 show_trace_log_lvl(current, regs, NULL, KERN_DEFAULT);
382 405 show_opcodes((u8 *)regs->ip);
383 printk(KERN_DEFAULT "Code: ");
384
385 ip = (u8 *)regs->ip - code_prologue;
386 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
387 /* try starting at IP */
388 ip = (u8 *)regs->ip;
389 code_len = code_len - code_prologue + 1;
390 }
391 for (i = 0; i < code_len; i++, ip++) {
392 if (ip < (u8 *)PAGE_OFFSET ||
393 probe_kernel_address(ip, c)) {
394 pr_cont(" Bad RIP value.");
395 break;
396 }
397 if (ip == (u8 *)regs->ip)
398 pr_cont("<%02x> ", c);
399 else
400 pr_cont("%02x ", c);
401 }
402 } 406 }
403 pr_cont("\n");
404} 407}