Commit 1cf8343f authored by Seiichi Ikarashi's avatar Seiichi Ikarashi Committed by Ingo Molnar

x86: Fix rflags in FAKE_STACK_FRAME

The x86_64 kernel pushes the fake kernel stack in
arch/x86/kernel/entry_64.S:FAKE_STACK_FRAME, and
rflags register in it does not conform to the specification.

Although Intel's manual[1] says bit 1 of it shall be set to 1,
this bit is cleared to 0 on pushing the fake stack.

[1] Intel(R) 64 and IA-32 Architectures Software Developer's Manual
    Vol.1 3-21 Figure 3-8. EFLAGS Register

If it is not on purpose, it is better to be fixed, because
it can lead some tools misunderstanding the stack frame. For example,
"crash" utility[2] actually detects it and warns you like
below:

       RIP: ffffffff8005dfa2  RSP: ffff8104ce0c7f58  RFLAGS: 00000200
       [...]

       bt: WARNING: possibly bogus exception frame
Signed-off-by: default avatarSeiichi Ikarashi <s.ikarashi@jp.fujitsu.com>
Tested-by: default avatarMasayoshi MIZUMA <m.mizuma@jp.fujitsu.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent cc3a1bf5
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* EFLAGS bits * EFLAGS bits
*/ */
#define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */
#define X86_EFLAGS_BIT1 0x00000002 /* Bit 1 - always on */
#define X86_EFLAGS_PF 0x00000004 /* Parity Flag */ #define X86_EFLAGS_PF 0x00000004 /* Parity Flag */
#define X86_EFLAGS_AF 0x00000010 /* Auxiliary carry Flag */ #define X86_EFLAGS_AF 0x00000010 /* Auxiliary carry Flag */
#define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */
......
...@@ -221,7 +221,7 @@ ENDPROC(native_usergs_sysret64) ...@@ -221,7 +221,7 @@ ENDPROC(native_usergs_sysret64)
/*CFI_REL_OFFSET ss,0*/ /*CFI_REL_OFFSET ss,0*/
pushq_cfi %rax /* rsp */ pushq_cfi %rax /* rsp */
CFI_REL_OFFSET rsp,0 CFI_REL_OFFSET rsp,0
pushq_cfi $X86_EFLAGS_IF /* eflags - interrupts on */ pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_BIT1) /* eflags - interrupts on */
/*CFI_REL_OFFSET rflags,0*/ /*CFI_REL_OFFSET rflags,0*/
pushq_cfi $__KERNEL_CS /* cs */ pushq_cfi $__KERNEL_CS /* cs */
/*CFI_REL_OFFSET cs,0*/ /*CFI_REL_OFFSET cs,0*/
......
...@@ -293,7 +293,7 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) ...@@ -293,7 +293,7 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
regs.orig_ax = -1; regs.orig_ax = -1;
regs.ip = (unsigned long) kernel_thread_helper; regs.ip = (unsigned long) kernel_thread_helper;
regs.cs = __KERNEL_CS | get_kernel_rpl(); regs.cs = __KERNEL_CS | get_kernel_rpl();
regs.flags = X86_EFLAGS_IF | 0x2; regs.flags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
/* Ok, create the new process.. */ /* Ok, create the new process.. */
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL); return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
......
...@@ -697,7 +697,7 @@ void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start) ...@@ -697,7 +697,7 @@ void lguest_arch_setup_regs(struct lg_cpu *cpu, unsigned long start)
* interrupts are enabled. We always leave interrupts enabled while * interrupts are enabled. We always leave interrupts enabled while
* running the Guest. * running the Guest.
*/ */
regs->eflags = X86_EFLAGS_IF | 0x2; regs->eflags = X86_EFLAGS_IF | X86_EFLAGS_BIT1;
/* /*
* The "Extended Instruction Pointer" register says where the Guest is * The "Extended Instruction Pointer" register says where the Guest is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment