* WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) @ 2016-12-10 16:17 Borislav Petkov 2016-12-10 17:04 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Borislav Petkov @ 2016-12-10 16:17 UTC (permalink / raw) To: Josh Poimboeuf; +Cc: x86-ml, lkml Hey, I see the line in $Subject on rc8+tip/master. Fixed already? -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-10 16:17 WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) Borislav Petkov @ 2016-12-10 17:04 ` Josh Poimboeuf 2016-12-10 17:28 ` Borislav Petkov 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-10 17:04 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml On Sat, Dec 10, 2016 at 05:17:49PM +0100, Borislav Petkov wrote: > Hey, > > I see the line in $Subject on rc8+tip/master. > > Fixed already? That's a new one. Was there anything else printed? Were you doing anything special when it happened? Do you see it reliably? I should probably figure out a way to dump more data for that warning. -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-10 17:04 ` Josh Poimboeuf @ 2016-12-10 17:28 ` Borislav Petkov 2016-12-12 15:45 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Borislav Petkov @ 2016-12-10 17:28 UTC (permalink / raw) To: Josh Poimboeuf; +Cc: x86-ml, lkml On Sat, Dec 10, 2016 at 11:04:44AM -0600, Josh Poimboeuf wrote: > That's a new one. Was there anything else printed? It is the first line that appears in dmesg when I boot: [ 0.000000] WARNING: kernel stack frame pointer at ffffffffb5e03f40 in swapper:0 has bad value (null) [ 0.000000] Linux version 4.9.0-rc8+ (boris@gondor) (gcc version 6.2.0 20161109 (Debian 6.2.0-13) ) #1 SMP PREEMPT Sat Dec 10 13:25:29 CET 2016 [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-rc8+ root=/dev/sda7 ro earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0 root=/dev/sda7 log_buf_len=10M resume=/dev/sda5 no_console_suspend ignore_loglevel [ 0.000000] KERNEL supported cpus: [ 0.000000] Intel GenuineIntel [ 0.000000] AMD AuthenticAMD [ 0.000000] Centaur CentaurHauls [ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' ... > Were you doing anything special when it happened? Not really - just booting ;-) > Do you see it reliably? 2 of 2 boots. > I should probably figure out a way to dump more data for that warning. Sure, I can test patches. Thanks. -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-10 17:28 ` Borislav Petkov @ 2016-12-12 15:45 ` Josh Poimboeuf 2016-12-12 17:50 ` Borislav Petkov 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-12 15:45 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml On Sat, Dec 10, 2016 at 06:28:02PM +0100, Borislav Petkov wrote: > On Sat, Dec 10, 2016 at 11:04:44AM -0600, Josh Poimboeuf wrote: > > That's a new one. Was there anything else printed? > > It is the first line that appears in dmesg when I boot: > > [ 0.000000] WARNING: kernel stack frame pointer at ffffffffb5e03f40 in swapper:0 has bad value (null) > [ 0.000000] Linux version 4.9.0-rc8+ (boris@gondor) (gcc version 6.2.0 20161109 (Debian 6.2.0-13) ) #1 SMP PREEMPT Sat Dec 10 13:25:29 CET 2016 > [ 0.000000] Command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-rc8+ root=/dev/sda7 ro earlyprintk=ttyS0,115200 console=ttyS0,115200 console=tty0 root=/dev/sda7 log_buf_len=10M resume=/dev/sda5 no_console_suspend ignore_loglevel > [ 0.000000] KERNEL supported cpus: > [ 0.000000] Intel GenuineIntel > [ 0.000000] AMD AuthenticAMD > [ 0.000000] Centaur CentaurHauls > [ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' > ... > > > Were you doing anything special when it happened? > > Not really - just booting ;-) > > > Do you see it reliably? > > 2 of 2 boots. > > > I should probably figure out a way to dump more data for that warning. > > Sure, I can test patches. Can you try with this? diff --git a/arch/x86/include/asm/unwind.h b/arch/x86/include/asm/unwind.h index c5a7f3a..6fa75b1 100644 --- a/arch/x86/include/asm/unwind.h +++ b/arch/x86/include/asm/unwind.h @@ -12,7 +12,7 @@ struct unwind_state { struct task_struct *task; int graph_idx; #ifdef CONFIG_FRAME_POINTER - unsigned long *bp; + unsigned long *bp, *orig_sp; struct pt_regs *regs; #else unsigned long *sp; diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c index ea7b7f9..1c93984 100644 --- a/arch/x86/kernel/unwind_frame.c +++ b/arch/x86/kernel/unwind_frame.c @@ -6,6 +6,36 @@ #define FRAME_HEADER_SIZE (sizeof(long) * 2) +static void unwind_dump(struct unwind_state *state, unsigned long *sp) +{ + static bool dumped_before = false; + bool prev_zero, zero = false; + unsigned long word; + + if (dumped_before) + return; + + dumped_before = true; + + printk_deferred("unwind stack type:%d next_sp:%p mask:%lx graph_idx:%d\n", + state->stack_info.type, state->stack_info.next_sp, + state->stack_mask, state->graph_idx); + + for (sp = state->orig_sp; sp < state->stack_info.end; sp++) { + prev_zero = zero; + word = READ_ONCE_NOCHECK(*sp); + zero = word == 0; + + if (zero) { + if (!prev_zero) + printk_deferred("%p: %016x ...\n", sp, 0); + continue; + } + + printk_deferred("%p: %016lx (%pB)\n", sp, word, (void *)word); + } +} + unsigned long unwind_get_return_address(struct unwind_state *state) { unsigned long addr; @@ -25,6 +55,7 @@ unsigned long unwind_get_return_address(struct unwind_state *state) "WARNING: unrecognized kernel stack return address %p at %p in %s:%d\n", (void *)addr, addr_p, state->task->comm, state->task->pid); + unwind_dump(state, addr_p); return 0; } @@ -67,6 +98,7 @@ static bool update_stack_state(struct unwind_state *state, void *addr, size_t len) { struct stack_info *info = &state->stack_info; + enum stack_type orig_type = info->type; /* * If addr isn't on the current stack, switch to the next one. @@ -80,6 +112,9 @@ static bool update_stack_state(struct unwind_state *state, void *addr, &state->stack_mask)) return false; + if (!state->orig_sp || info->type != orig_type) + state->orig_sp = addr; + return true; } @@ -178,11 +213,13 @@ bool unwind_next_frame(struct unwind_state *state) "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", state->regs, state->task->comm, state->task->pid, next_frame); + unwind_dump(state, (unsigned long *)state->regs); } else { printk_deferred_once(KERN_WARNING "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n", state->bp, state->task->comm, state->task->pid, next_frame); + unwind_dump(state, state->bp); } the_end: state->stack_info.type = STACK_TYPE_UNKNOWN; ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 15:45 ` Josh Poimboeuf @ 2016-12-12 17:50 ` Borislav Petkov 2016-12-12 18:10 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Borislav Petkov @ 2016-12-12 17:50 UTC (permalink / raw) To: Josh Poimboeuf; +Cc: x86-ml, lkml On Mon, Dec 12, 2016 at 09:45:42AM -0600, Josh Poimboeuf wrote: > Can you try with this? That's alot of stack: --- [ 0.000000] WARNING: kernel stack frame pointer at ffffffffbce03f40 in swapper:0 has bad value (null) [ 0.000000] unwind stack type:0 next_sp: (null) mask:2 graph_idx:0 [ 0.000000] ffffffffbce03bc0: ffffffffbce03c40 (init_thread_union+0x3c40/0x4000) [ 0.000000] ffffffffbce03bc8: ffffffffbc027643 (__save_stack_trace+0x73/0xd0) [ 0.000000] ffffffffbce03bd0: 0000000000000000 ... [ 0.000000] ffffffffbce03bd8: ffffffffbce00000 (__end_rodata+0x59000/0x59000) [ 0.000000] ffffffffbce03be0: ffffffffbce04000 (init_thread_union+0x4000/0x4000) [ 0.000000] ffffffffbce03be8: 0000000000000000 ... [ 0.000000] ffffffffbce03bf0: 0000000000000002 (0x2) [ 0.000000] ffffffffbce03bf8: ffffffffbce0e540 (root_mountflags+0x40/0x40) [ 0.000000] ffffffffbce03c00: 0000000000000000 ... [ 0.000000] ffffffffbce03c08: ffffffffbce03f40 (init_thread_union+0x3f40/0x4000) [ 0.000000] ffffffffbce03c10: ffffffffbce03bc0 (init_thread_union+0x3bc0/0x4000) [ 0.000000] ffffffffbce03c18: 0000000000000000 ... [ 0.000000] ffffffffbce03c20: ffffffffbd7b4278 (lock_classes+0x158/0x35fe60) [ 0.000000] ffffffffbce03c28: ffffffffbce0e540 (root_mountflags+0x40/0x40) [ 0.000000] ffffffffbce03c30: ffffffffbcec9080 (primary_crng+0x60/0x80) [ 0.000000] ffffffffbce03c38: 000000000000000c (0xc) [ 0.000000] ffffffffbce03c40: ffffffffbce03c50 (init_thread_union+0x3c50/0x4000) [ 0.000000] ffffffffbce03c48: ffffffffbc0276bb (save_stack_trace+0x1b/0x20) [ 0.000000] ffffffffbce03c50: ffffffffbce03c68 (init_thread_union+0x3c68/0x4000) [ 0.000000] ffffffffbce03c58: ffffffffbc0bf60b (save_trace+0x3b/0xc0) [ 0.000000] ffffffffbce03c60: 000000000000000c (0xc) [ 0.000000] ffffffffbce03c68: ffffffffbce03cb0 (init_thread_union+0x3cb0/0x4000) [ 0.000000] ffffffffbce03c70: ffffffffbc0c1d78 (mark_lock+0x188/0x610) [ 0.000000] ffffffffbce03c78: 0000000000000000 ... [ 0.000000] ffffffffbce03c80: ffffffffbcec9080 (primary_crng+0x60/0x80) [ 0.000000] ffffffffbce03c88: ffffffffbce0ed08 (init_task+0x7c8/0x2340) [ 0.000000] ffffffffbce03c90: 0000000000000000 ... [ 0.000000] ffffffffbce03c98: ffffffffbcec9080 (primary_crng+0x60/0x80) [ 0.000000] ffffffffbce03ca0: ffffffffbce0e540 (root_mountflags+0x40/0x40) [ 0.000000] ffffffffbce03ca8: 0000000000000001 (0x1) [ 0.000000] ffffffffbce03cb0: ffffffffbce03d68 (init_thread_union+0x3d68/0x4000) [ 0.000000] ffffffffbce03cb8: ffffffffbc0c2a6f (__lock_acquire+0x2ff/0x1760) [ 0.000000] ffffffffbce03cc0: 0000000000000000 ... [ 0.000000] ffffffffbce03cd0: 000000000000002d (0x2d) [ 0.000000] ffffffffbce03cd8: ffffffff00000001 (0xffffffff00000001) [ 0.000000] ffffffffbce03ce0: ffffffffbd7b4120 (classhash_table+0x8000/0x8000) [ 0.000000] ffffffffbce03ce8: 0000000000000000 ... [ 0.000000] ffffffffbce03cf0: ffffffffbce0ed08 (init_task+0x7c8/0x2340) [ 0.000000] ffffffffbce03cf8: 0000000000000000 ... [ 0.000000] ffffffffbce03d10: ffffffffbce03e0c (init_thread_union+0x3e0c/0x4000) [ 0.000000] ffffffffbce03d18: ffffffffffffffff (0xffffffffffffffff) [ 0.000000] ffffffffbce03d20: 00000000431fc205 (0x431fc205) [ 0.000000] ffffffffbce03d28: ffffffffbcc881f4 (.LC9+0x10e9/0x1606) [ 0.000000] ffffffffbce03d30: ffffffffbcc881f0 (.LC9+0x10e5/0x1606) [ 0.000000] ffffffffbce03d38: ffffffffbce03d90 (init_thread_union+0x3d90/0x4000) [ 0.000000] ffffffffbce03d40: 0000000000000096 (0x96) [ 0.000000] ffffffffbce03d48: 0000000000000000 ... [ 0.000000] ffffffffbce03d58: 0000000000000001 (0x1) [ 0.000000] ffffffffbce03d60: 0000000000000000 ... [ 0.000000] ffffffffbce03d68: ffffffffbce03dd8 (init_thread_union+0x3dd8/0x4000) [ 0.000000] ffffffffbce03d70: ffffffffbc0c4537 (lock_acquire+0x107/0x210) [ 0.000000] ffffffffbce03d78: 0000000000000000 ... [ 0.000000] ffffffffbce03d80: ffffffffbc498ac0 (_extract_crng+0x40/0xb0) [ 0.000000] ffffffffbce03d88: 0000000000000000 ... [ 0.000000] ffffffffbce03d90: ffffffff00000000 (0xffffffff00000000) [ 0.000000] ffffffffbce03d98: 0000000000000096 (0x96) [ 0.000000] ffffffffbce03da0: 00000000bc3c8673 (0xbc3c8673) [ 0.000000] ffffffffbce03da8: ffffffffbcec9080 (primary_crng+0x60/0x80) [ 0.000000] ffffffffbce03db0: ffffffffbcec9068 (primary_crng+0x48/0x80) [ 0.000000] ffffffffbce03db8: 0000000000000096 (0x96) [ 0.000000] ffffffffbce03dc0: 0000000000000008 (0x8) [ 0.000000] ffffffffbce03dc8: ffffffffbce03e50 (init_thread_union+0x3e50/0x4000) [ 0.000000] ffffffffbce03dd0: ffffffff0000ffff (0xffffffff0000ffff) [ 0.000000] ffffffffbce03dd8: ffffffffbce03e00 (init_thread_union+0x3e00/0x4000) [ 0.000000] ffffffffbce03de0: ffffffffbc873466 (_raw_spin_lock_irqsave+0x46/0x60) [ 0.000000] ffffffffbce03de8: ffffffffbc498ac0 (_extract_crng+0x40/0xb0) [ 0.000000] ffffffffbce03df0: ffffffffbcec9020 (input_pool+0xc0/0xc0) [ 0.000000] ffffffffbce03df8: ffffffffbcec9068 (primary_crng+0x48/0x80) [ 0.000000] ffffffffbce03e00: ffffffffbce03e30 (init_thread_union+0x3e30/0x4000) [ 0.000000] ffffffffbce03e08: ffffffffbc498ac0 (_extract_crng+0x40/0xb0) [ 0.000000] ffffffffbce03e10: ffffffffbce03ec8 (init_thread_union+0x3ec8/0x4000) [ 0.000000] ffffffffbce03e18: ffffffffbce03e50 (init_thread_union+0x3e50/0x4000) [ 0.000000] ffffffffbce03e20: 0000000000000008 (0x8) [ 0.000000] ffffffffbce03e28: ffffffffbcf67b66 (start_kernel+0x2b/0x3d9) [ 0.000000] ffffffffbce03e30: ffffffffbce03e40 (init_thread_union+0x3e40/0x4000) [ 0.000000] ffffffffbce03e38: ffffffffbc498b6f (extract_crng+0x3f/0x50) [ 0.000000] ffffffffbce03e40: ffffffffbce03eb8 (init_thread_union+0x3eb8/0x4000) [ 0.000000] ffffffffbce03e48: ffffffffbc49a6f5 (get_random_bytes+0x95/0x260) [ 0.000000] ffffffffbce03e50: ffffffffbcf67155 (early_idt_handler_common+0x35/0x4c) [ 0.000000] ffffffffbce03e58: ffffffff0000ffff (0xffffffff0000ffff) [ 0.000000] ffffffffbce03e60: fffffff8ffffffff (0xfffffff8ffffffff) [ 0.000000] ffffffffbce03e68: 0000000000055000 (0x55000) [ 0.000000] ffffffffbce03e70: bcf68e0000107117 (0xbcf68e0000107117) [ 0.000000] ffffffffbce03e78: ffffffffbce03f00 (init_thread_union+0x3f00/0x4000) [ 0.000000] ffffffffbce03e80: ffffffffbcb00ef0 (_fw_end+0x4000/0x4000) [ 0.000000] ffffffffbce03e88: 0000000000004400 (0x4400) [ 0.000000] ffffffffbce03e90: 0000000000000000 ... [ 0.000000] ffffffffbce03e98: bcf68e0000107117 (0xbcf68e0000107117) [ 0.000000] ffffffffbce03ea0: bcf68e0000107117 (0xbcf68e0000107117) [ 0.000000] ffffffffbce03ea8: 0000000000055000 (0x55000) [ 0.000000] ffffffffbce03eb0: fffffff8ffffffff (0xfffffff8ffffffff) [ 0.000000] ffffffffbce03eb8: ffffffffbce03ef0 (init_thread_union+0x3ef0/0x4000) [ 0.000000] ffffffffbce03ec0: ffffffffbcf67b66 (start_kernel+0x2b/0x3d9) [ 0.000000] ffffffffbce03ec8: 0000000000000000 ... [ 0.000000] ffffffffbce03ed0: bcf68e0000107117 (0xbcf68e0000107117) [ 0.000000] ffffffffbce03ed8: bcf68e0000107117 (0xbcf68e0000107117) [ 0.000000] ffffffffbce03ee0: 0000000000055000 (0x55000) [ 0.000000] ffffffffbce03ee8: fffffff8ffffffff (0xfffffff8ffffffff) [ 0.000000] ffffffffbce03ef0: ffffffffbce03f00 (init_thread_union+0x3f00/0x4000) [ 0.000000] ffffffffbce03ef8: ffffffffbcf67286 (x86_64_start_reservations+0x24/0x26) [ 0.000000] ffffffffbce03f00: ffffffffbce03f40 (init_thread_union+0x3f40/0x4000) [ 0.000000] ffffffffbce03f08: ffffffffbcf6740a (x86_64_start_kernel+0x182/0x193) [ 0.000000] ffffffffbce03f10: 0000000000000000 ... [ 0.000000] ffffffffbce03f18: ffffffffbce03f58 (init_thread_union+0x3f58/0x4000) [ 0.000000] ffffffffbce03f20: 00000000000000f0 (0xf0) [ 0.000000] ffffffffbce03f28: 00000000ac41fb60 (0xac41fb60) [ 0.000000] ffffffffbce03f30: 00000000ac6c8364 (0xac6c8364) [ 0.000000] ffffffffbce03f38: 00000000ac767740 (0xac767740) [ 0.000000] ffffffffbce03f40: 0000000000000000 ... [ 0.000000] ffffffffbce03f48: ffffffffbc0001b5 (start_cpu+0x5/0x14) [ 0.000000] ffffffffbce03f50: ffffffffbc0001b5 (start_cpu+0x5/0x14) [ 0.000000] ffffffffbce03f58: 0000000000000000 ... [ 0.000000] Linux version 4.9.0-rc8+ (root@gondor) (gcc version 6.2.0 20161109 (Debian 6.2.0-13) ) #2 SMP PREEMPT Mon Dec 12 18:36:48 CET 2016 ... -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 17:50 ` Borislav Petkov @ 2016-12-12 18:10 ` Josh Poimboeuf 2016-12-12 21:16 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-12 18:10 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml On Mon, Dec 12, 2016 at 06:50:23PM +0100, Borislav Petkov wrote: > [ 0.000000] ffffffffbce03f40: 0000000000000000 ... > [ 0.000000] ffffffffbce03f48: ffffffffbc0001b5 (start_cpu+0x5/0x14) > [ 0.000000] ffffffffbce03f50: ffffffffbc0001b5 (start_cpu+0x5/0x14) > [ 0.000000] ffffffffbce03f58: 0000000000000000 ... > [ 0.000000] Linux version 4.9.0-rc8+ (root@gondor) (gcc version 6.2.0 20161109 (Debian 6.2.0-13) ) #2 SMP PREEMPT Mon Dec 12 18:36:48 CET 2016 Something funky is going on in the head code. It looks like start_cpu is getting executed twice somehow. Need to do some more head scratching... -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 18:10 ` Josh Poimboeuf @ 2016-12-12 21:16 ` Josh Poimboeuf 2016-12-12 21:34 ` Borislav Petkov 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-12 21:16 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml, Andy Lutomirski On Mon, Dec 12, 2016 at 12:10:25PM -0600, Josh Poimboeuf wrote: > On Mon, Dec 12, 2016 at 06:50:23PM +0100, Borislav Petkov wrote: > > [ 0.000000] ffffffffbce03f40: 0000000000000000 ... > > [ 0.000000] ffffffffbce03f48: ffffffffbc0001b5 (start_cpu+0x5/0x14) > > [ 0.000000] ffffffffbce03f50: ffffffffbc0001b5 (start_cpu+0x5/0x14) > > [ 0.000000] ffffffffbce03f58: 0000000000000000 ... > > [ 0.000000] Linux version 4.9.0-rc8+ (root@gondor) (gcc version 6.2.0 20161109 (Debian 6.2.0-13) ) #2 SMP PREEMPT Mon Dec 12 18:36:48 CET 2016 > > Something funky is going on in the head code. It looks like start_cpu > is getting executed twice somehow. Need to do some more head > scratching... I still can't figure out what could cause this, nor can I recreate it. Andy, any idea? I'm trying to figure out why a stack trace of the initial task, early in start_kernel(), would show start_cpu() on the stack *twice*. The start_cpu() entry on the stack at ffffffffbce03f50 is right where it's supposed to be. But then there's another start_cpu() entry at 0xffffffffbce03f48 which is pointed to by the frame pointer chain. I can't figure out where that one came from and why the stack is offset by a word, compared to all the other idle task stacks I've seen. Boris, what kind of CPU is it? -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 21:16 ` Josh Poimboeuf @ 2016-12-12 21:34 ` Borislav Petkov 2016-12-12 22:11 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Borislav Petkov @ 2016-12-12 21:34 UTC (permalink / raw) To: Josh Poimboeuf; +Cc: x86-ml, lkml, Andy Lutomirski On Mon, Dec 12, 2016 at 03:16:27PM -0600, Josh Poimboeuf wrote: > I still can't figure out what could cause this, nor can I recreate it. Want my .config? > Andy, any idea? I'm trying to figure out why a stack trace of the > initial task, early in start_kernel(), would show start_cpu() on the > stack *twice*. The start_cpu() entry on the stack at ffffffffbce03f50 > is right where it's supposed to be. But then there's another > start_cpu() entry at 0xffffffffbce03f48 which is pointed to by the frame > pointer chain. I can't figure out where that one came from and why the > stack is offset by a word, compared to all the other idle task stacks > I've seen. Btw, why do you have: call 1f # put return address on stack for unwinder there in start_cpu() instead of push $start_cpu or so? That CALL looks strange there. If you want to put the return address, just push start_cpu's address and that's it. Or am I missing something? > Boris, what kind of CPU is it? [ 0.169371] smpboot: CPU0: Intel(R) Xeon(R) CPU E5-1620 0 @ 3.60GHz (family: 0x6, model: 0x2d, stepping: 0x7) Sandybridge. The model 0x2d corresponds to that INTEL_FAM6_SANDYBRIDGE_X define in intel-family.h. -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 21:34 ` Borislav Petkov @ 2016-12-12 22:11 ` Josh Poimboeuf 2016-12-12 22:33 ` Borislav Petkov 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-12 22:11 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml, Andy Lutomirski On Mon, Dec 12, 2016 at 10:34:46PM +0100, Borislav Petkov wrote: > On Mon, Dec 12, 2016 at 03:16:27PM -0600, Josh Poimboeuf wrote: > > I still can't figure out what could cause this, nor can I recreate it. > > Want my .config? Yes, please. > > Andy, any idea? I'm trying to figure out why a stack trace of the > > initial task, early in start_kernel(), would show start_cpu() on the > > stack *twice*. The start_cpu() entry on the stack at ffffffffbce03f50 > > is right where it's supposed to be. But then there's another > > start_cpu() entry at 0xffffffffbce03f48 which is pointed to by the frame > > pointer chain. I can't figure out where that one came from and why the > > stack is offset by a word, compared to all the other idle task stacks > > I've seen. > > Btw, why do you have: > > call 1f # put return address on stack for unwinder > > there in start_cpu() instead of > > push $start_cpu > > or so? That CALL looks strange there. If you want to put the return > address, just push start_cpu's address and that's it. > > Or am I missing something? Yeah, it's kind of obtuse. The problem with "push $start_cpu" is that it will show up on the stack trace as: secondary_startup_64+0x90/0x90 instead of what you would expect: start_cpu+0x0/0x14 That's because the printk '%pB' modifier is smart enough to know that the beginning of a function isn't a valid function call return address. The only way such an address could end up on the stack would be if the previous function made a tail call. So it shows the end of the previous function instead. That said, the code could probably be made a little clearer by changing "call 1f" to "push $1f" and then move the '1' label to after the lretq instruction, like: pushq $1f # put return address on stack for unwinder xorq %rbp, %rbp # clear frame pointer movq initial_code(%rip), %rax pushq $__KERNEL_CS # set correct cs pushq %rax # target address in negative space lretq 1: ENDPROC(start_cpu) That shows: start_cpu+0x14/0x14 Which is more accurate anyway. I'll make a patch. -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 22:11 ` Josh Poimboeuf @ 2016-12-12 22:33 ` Borislav Petkov 2016-12-12 23:05 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Borislav Petkov @ 2016-12-12 22:33 UTC (permalink / raw) To: Josh Poimboeuf; +Cc: x86-ml, lkml, Andy Lutomirski [-- Attachment #1: Type: text/plain, Size: 855 bytes --] On Mon, Dec 12, 2016 at 04:11:47PM -0600, Josh Poimboeuf wrote: > Yes, please. Attached. > That said, the code could probably be made a little clearer by changing > "call 1f" to "push $1f" and then move the '1' label to after the lretq > instruction, like: > > pushq $1f # put return address on stack for unwinder > xorq %rbp, %rbp # clear frame pointer > movq initial_code(%rip), %rax > pushq $__KERNEL_CS # set correct cs > pushq %rax # target address in negative space > lretq > 1: > ENDPROC(start_cpu) > > That shows: > > start_cpu+0x14/0x14 > > Which is more accurate anyway. I'll make a patch. Yap, makes more sense. I'll run it tomorrow. FWIW, I tried pushq $1f before without moving the 1: label but the thing still fired. -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply. [-- Attachment #2: config.gz --] [-- Type: application/gzip, Size: 26012 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 22:33 ` Borislav Petkov @ 2016-12-12 23:05 ` Josh Poimboeuf 2016-12-13 14:34 ` Josh Poimboeuf 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-12 23:05 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml, Andy Lutomirski On Mon, Dec 12, 2016 at 11:33:54PM +0100, Borislav Petkov wrote: > On Mon, Dec 12, 2016 at 04:11:47PM -0600, Josh Poimboeuf wrote: > > Yes, please. > > Attached. Thanks, I was able to recreate. Will take a look tomorrow. -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-12 23:05 ` Josh Poimboeuf @ 2016-12-13 14:34 ` Josh Poimboeuf 2016-12-13 16:55 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-13 14:34 UTC (permalink / raw) To: Borislav Petkov; +Cc: x86-ml, lkml, Andy Lutomirski On Mon, Dec 12, 2016 at 05:05:11PM -0600, Josh Poimboeuf wrote: > On Mon, Dec 12, 2016 at 11:33:54PM +0100, Borislav Petkov wrote: > > On Mon, Dec 12, 2016 at 04:11:47PM -0600, Josh Poimboeuf wrote: > > > Yes, please. > > > > Attached. > > Thanks, I was able to recreate. Will take a look tomorrow. Figured it out. Your config has CONFIG_PARAVIRT=n, which convinces gcc to create the following preamble for x86_64_start_kernel(): 0000000000000124 <x86_64_start_kernel>: 124: 4c 8d 54 24 08 lea 0x8(%rsp),%r10 129: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 12d: 41 ff 72 f8 pushq -0x8(%r10) 131: 55 push %rbp 132: 48 89 e5 mov %rsp,%rbp It's an unusual pattern which aligns rsp (though in this case it's already aligned) and saves the start_cpu() return address again on the stack before storing the frame pointer. The unwinder assumes the last stack frame header is at a certain offset, but the above code breaks that assumption. I still need to think about the best way to fix it. -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-13 14:34 ` Josh Poimboeuf @ 2016-12-13 16:55 ` Andy Lutomirski 2016-12-13 17:26 ` Josh Poimboeuf 2016-12-13 17:51 ` Borislav Petkov 0 siblings, 2 replies; 15+ messages in thread From: Andy Lutomirski @ 2016-12-13 16:55 UTC (permalink / raw) To: Josh Poimboeuf; +Cc: Borislav Petkov, x86-ml, lkml, Andy Lutomirski On Tue, Dec 13, 2016 at 6:34 AM, Josh Poimboeuf <jpoimboe@redhat.com> wrote: > On Mon, Dec 12, 2016 at 05:05:11PM -0600, Josh Poimboeuf wrote: >> On Mon, Dec 12, 2016 at 11:33:54PM +0100, Borislav Petkov wrote: >> > On Mon, Dec 12, 2016 at 04:11:47PM -0600, Josh Poimboeuf wrote: >> > > Yes, please. >> > >> > Attached. >> >> Thanks, I was able to recreate. Will take a look tomorrow. > > Figured it out. Your config has CONFIG_PARAVIRT=n, which convinces gcc > to create the following preamble for x86_64_start_kernel(): > > 0000000000000124 <x86_64_start_kernel>: > 124: 4c 8d 54 24 08 lea 0x8(%rsp),%r10 > 129: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp > 12d: 41 ff 72 f8 pushq -0x8(%r10) > 131: 55 push %rbp > 132: 48 89 e5 mov %rsp,%rbp > > It's an unusual pattern which aligns rsp (though in this case it's > already aligned) and saves the start_cpu() return address again on the > stack before storing the frame pointer. Um, what? I can reproduce it -- I get: 0000000000000124 <x86_64_start_kernel>: 124: 4c 8d 54 24 08 lea 0x8(%rsp),%r10 129: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 12d: 41 ff 72 f8 pushq -0x8(%r10) 131: 55 push %rbp 132: 48 89 e5 mov %rsp,%rbp 135: 41 57 push %r15 137: 41 56 push %r14 139: 41 55 push %r13 13b: 41 54 push %r12 13d: 41 52 push %r10 13f: 53 push %rbx 140: 48 83 ec 10 sub $0x10,%rsp ... and the epilog looks like: 29c: 58 pop %rax 29d: 5a pop %rdx 29e: 5b pop %rbx 29f: 41 5a pop %r10 2a1: 41 5c pop %r12 2a3: 41 5d pop %r13 2a5: 41 5e pop %r14 2a7: 41 5f pop %r15 2a9: 5d pop %rbp 2aa: 49 8d 62 f8 lea -0x8(%r10),%rsp 2ae: c3 retq This is, I think, *terrible* code. It makes it entirely impossible for the CPU to look through the retq until the instruction right before it finishes because there's no way the CPU can tell what rsp is until the instruction right before the retq. And it's saving and restoring an entire extra register (r10) instead of just using rbp for this purpose. *And* the extra copy of the return address seems totally useless except for unwinding. This does indeed depend on CONFIG_PARAVIRT, but I'm not seeing what changes. Presumably something related to what happens in the function? I want to file a GCC bug, though. This code sucks. > > The unwinder assumes the last stack frame header is at a certain offset, > but the above code breaks that assumption. I still need to think about > the best way to fix it. Have a dummy written-in-asm top-of-the-stack function? Or recognize the end by the final saved RBP? --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-13 16:55 ` Andy Lutomirski @ 2016-12-13 17:26 ` Josh Poimboeuf 2016-12-13 17:51 ` Borislav Petkov 1 sibling, 0 replies; 15+ messages in thread From: Josh Poimboeuf @ 2016-12-13 17:26 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Borislav Petkov, x86-ml, lkml, Andy Lutomirski On Tue, Dec 13, 2016 at 08:55:53AM -0800, Andy Lutomirski wrote: > On Tue, Dec 13, 2016 at 6:34 AM, Josh Poimboeuf <jpoimboe@redhat.com> wrote: > > On Mon, Dec 12, 2016 at 05:05:11PM -0600, Josh Poimboeuf wrote: > >> On Mon, Dec 12, 2016 at 11:33:54PM +0100, Borislav Petkov wrote: > >> > On Mon, Dec 12, 2016 at 04:11:47PM -0600, Josh Poimboeuf wrote: > >> > > Yes, please. > >> > > >> > Attached. > >> > >> Thanks, I was able to recreate. Will take a look tomorrow. > > > > Figured it out. Your config has CONFIG_PARAVIRT=n, which convinces gcc > > to create the following preamble for x86_64_start_kernel(): > > > > 0000000000000124 <x86_64_start_kernel>: > > 124: 4c 8d 54 24 08 lea 0x8(%rsp),%r10 > > 129: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp > > 12d: 41 ff 72 f8 pushq -0x8(%r10) > > 131: 55 push %rbp > > 132: 48 89 e5 mov %rsp,%rbp > > > > It's an unusual pattern which aligns rsp (though in this case it's > > already aligned) and saves the start_cpu() return address again on the > > stack before storing the frame pointer. > > Um, what? I can reproduce it -- I get: > > 0000000000000124 <x86_64_start_kernel>: > 124: 4c 8d 54 24 08 lea 0x8(%rsp),%r10 > 129: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp > 12d: 41 ff 72 f8 pushq -0x8(%r10) > 131: 55 push %rbp > 132: 48 89 e5 mov %rsp,%rbp > 135: 41 57 push %r15 > 137: 41 56 push %r14 > 139: 41 55 push %r13 > 13b: 41 54 push %r12 > 13d: 41 52 push %r10 > 13f: 53 push %rbx > 140: 48 83 ec 10 sub $0x10,%rsp > > ... > > and the epilog looks like: > > 29c: 58 pop %rax > 29d: 5a pop %rdx > 29e: 5b pop %rbx > 29f: 41 5a pop %r10 > 2a1: 41 5c pop %r12 > 2a3: 41 5d pop %r13 > 2a5: 41 5e pop %r14 > 2a7: 41 5f pop %r15 > 2a9: 5d pop %rbp > 2aa: 49 8d 62 f8 lea -0x8(%r10),%rsp > 2ae: c3 retq > > This is, I think, *terrible* code. It makes it entirely impossible > for the CPU to look through the retq until the instruction right > before it finishes because there's no way the CPU can tell what rsp is > until the instruction right before the retq. And it's saving and > restoring an entire extra register (r10) instead of just using rbp for > this purpose. *And* the extra copy of the return address seems > totally useless except for unwinding. > > This does indeed depend on CONFIG_PARAVIRT, but I'm not seeing what > changes. Presumably something related to what happens in the > function? > > I want to file a GCC bug, though. This code sucks. Yeah, I can't figure out why it's doing that. I've seen it align the stack before, but it was always *after* setting up the frame pointer and pushing the registers on the stack. I have no idea what triggered it to do it this way, but it would interesting to know if we can turn it off somehow. > > The unwinder assumes the last stack frame header is at a certain offset, > > but the above code breaks that assumption. I still need to think about > > the best way to fix it. > > Have a dummy written-in-asm top-of-the-stack function? Or recognize > the end by the final saved RBP? Assuming this issue could theoretically show up in *any* function called by entry or head code, I think the least pervasive change would be to just adjust the "last frame" check in the unwinder, aka is_last_task_frame()), to check at the "aligned" off-by-one-word offset in addition to the normal offset. -- Josh ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) 2016-12-13 16:55 ` Andy Lutomirski 2016-12-13 17:26 ` Josh Poimboeuf @ 2016-12-13 17:51 ` Borislav Petkov 1 sibling, 0 replies; 15+ messages in thread From: Borislav Petkov @ 2016-12-13 17:51 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Josh Poimboeuf, x86-ml, lkml, Andy Lutomirski On Tue, Dec 13, 2016 at 08:55:53AM -0800, Andy Lutomirski wrote: > I want to file a GCC bug, though. This code sucks. Looks like it started doing that with gcc-5. gcc-4.9 output looks fine here: .globl x86_64_start_kernel .type x86_64_start_kernel, @function x86_64_start_kernel: .LFB2013: .loc 1 134 0 .cfi_startproc pushq %rbp # .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp #, .cfi_def_cfa_register 6 pushq %rbx # .cfi_offset 3, -24 .loc 1 134 0 movq %rdi, %rbx # real_mode_data, real_mode_data .LBB157: .LBB158: .LBB159: .LBB160: .LBB161: .loc 3 69 0 #APP # 69 "./arch/x86/include/asm/special_insns.h" 1 mov %cr4,%rax # val -- Regards/Gruss, Boris. Good mailing practices for 400: avoid top-posting and trim the reply. ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2016-12-13 17:27 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-12-10 16:17 WARNING: kernel stack frame pointer at ffffffff82e03f40 in swapper:0 has bad value (null) Borislav Petkov 2016-12-10 17:04 ` Josh Poimboeuf 2016-12-10 17:28 ` Borislav Petkov 2016-12-12 15:45 ` Josh Poimboeuf 2016-12-12 17:50 ` Borislav Petkov 2016-12-12 18:10 ` Josh Poimboeuf 2016-12-12 21:16 ` Josh Poimboeuf 2016-12-12 21:34 ` Borislav Petkov 2016-12-12 22:11 ` Josh Poimboeuf 2016-12-12 22:33 ` Borislav Petkov 2016-12-12 23:05 ` Josh Poimboeuf 2016-12-13 14:34 ` Josh Poimboeuf 2016-12-13 16:55 ` Andy Lutomirski 2016-12-13 17:26 ` Josh Poimboeuf 2016-12-13 17:51 ` Borislav Petkov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).