x86: Fix rflags in FAKE_STACK_FRAME
authorSeiichi Ikarashi <s.ikarashi@jp.fujitsu.com>
Tue, 6 Dec 2011 08:58:14 +0000 (17:58 +0900)
committerIngo Molnar <mingo@elte.hu>
Tue, 6 Dec 2011 09:02:38 +0000 (10:02 +0100)
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: Seiichi Ikarashi <s.ikarashi@jp.fujitsu.com>
Tested-by: Masayoshi 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: Ingo Molnar <mingo@elte.hu>
arch/x86/include/asm/processor-flags.h
arch/x86/kernel/entry_64.S
arch/x86/kernel/process.c
drivers/lguest/x86/core.c

index 2dddb317bb39c7e9693d56f52a2264e81e6837fb..f8ab3eaad128dd32b485563855612ebede463711 100644 (file)
@@ -6,6 +6,7 @@
  * EFLAGS bits
  */
 #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_AF  0x00000010 /* Auxiliary carry Flag */
 #define X86_EFLAGS_ZF  0x00000040 /* Zero Flag */
index cfad7fce6163f81990002db7610f0423781e212b..a20e1cb9dc87fea597cbd69cda747d314f4ad68e 100644 (file)
@@ -221,7 +221,7 @@ ENDPROC(native_usergs_sysret64)
        /*CFI_REL_OFFSET        ss,0*/
        pushq_cfi %rax /* rsp */
        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*/
        pushq_cfi $__KERNEL_CS /* cs */
        /*CFI_REL_OFFSET        cs,0*/
index ee5d4fbd53b4bac72d19e3aa3000e77467f0c25e..15763af7bfe3b6202af28810c3aafbeaf14d2a0c 100644 (file)
@@ -293,7 +293,7 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
        regs.orig_ax = -1;
        regs.ip = (unsigned long) kernel_thread_helper;
        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.. */
        return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
index 65af42f2d593cbc352b5d65318ed90ff0cc6ac92..39809035320a89c468809a5efe5ff824cfb93a27 100644 (file)
@@ -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
         * 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