diff options
| author | Borislav Petkov <bp@suse.de> | 2018-04-17 12:11:18 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2018-04-26 10:15:26 -0400 |
| commit | f0a1d7c11c3ebe2f601b448d13e7fbc3a0364a03 (patch) | |
| tree | b792e07a725ea960c36bd7e389cd8518ec5b7e0b /arch/x86/kernel/dumpstack.c | |
| parent | 5df61707f0bdf8dce714a14806740e6abf2114c7 (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.c | 57 |
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 | ||
| 73 | static 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 | |||
| 73 | void show_iret_regs(struct pt_regs *regs) | 102 | void 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) | |||
| 359 | void show_regs(struct pt_regs *regs) | 388 | void 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 | } |
