From 8c2a221fa8b1c00df51f5330f2bfc8fa4b5cda9f Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 11 Feb 2013 15:22:16 +0100 Subject: [PATCH] --- yaml --- r: 350215 b: refs/heads/master c: 9efb58de919efa8312861d454be014094f6f0ffc h: refs/heads/master i: 350213: 4b33185fdd214b7b47c6834dd577747414f9da7f 350211: b1960e2a4c4b26ba6f4e62183176b33d1c572794 350207: 6c7141741b5137b3ed310db312ad47e6436285fe v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/head_32.S | 50 ++++++++++++++++----------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/[refs] b/[refs] index 9312e42fc978..9287c7789a5b 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 166df91daf38f619d4ca90b58ff90983de6e40d2 +refs/heads/master: 9efb58de919efa8312861d454be014094f6f0ffc diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S index a9c5cc851285..e3725a0f4327 100644 --- a/trunk/arch/x86/kernel/head_32.S +++ b/trunk/arch/x86/kernel/head_32.S @@ -307,30 +307,39 @@ default_entry: movl %eax,%cr0 /* - * New page tables may be in 4Mbyte page mode and may - * be using the global pages. + * We want to start out with EFLAGS unambiguously cleared. Some BIOSes leave + * bits like NT set. This would confuse the debugger if this code is traced. So + * initialize them properly now before switching to protected mode. That means + * DF in particular (even though we have cleared it earlier after copying the + * command line) because GCC expects it. + */ + pushl $0 + popfl + +/* + * New page tables may be in 4Mbyte page mode and may be using the global pages. * - * NOTE! If we are on a 486 we may have no cr4 at all! - * Specifically, cr4 exists if and only if CPUID exists - * and has flags other than the FPU flag set. + * NOTE! If we are on a 486 we may have no cr4 at all! Specifically, cr4 exists + * if and only if CPUID exists and has flags other than the FPU flag set. */ + movl $-1,pa(X86_CPUID) # preset CPUID level movl $X86_EFLAGS_ID,%ecx pushl %ecx - popfl - pushfl - popl %eax - pushl $0 - popfl + popfl # set EFLAGS=ID pushfl - popl %edx - xorl %edx,%eax - testl %ecx,%eax - jz 6f # No ID flag = no CPUID = no CR4 + popl %eax # get EFLAGS + testl $X86_EFLAGS_ID,%eax # did EFLAGS.ID remained set? + jz 6f # hw disallowed setting of ID bit + # which means no CPUID and no CR4 + + xorl %eax,%eax + cpuid + movl %eax,pa(X86_CPUID) # save largest std CPUID function movl $1,%eax cpuid - andl $~1,%edx # Ignore CPUID.FPU - jz 6f # No flags or only CPUID.FPU = no CR4 + andl $~1,%edx # Ignore CPUID.FPU + jz 6f # No flags or only CPUID.FPU = no CR4 movl pa(mmu_cr4_features),%eax movl %eax,%cr4 @@ -377,14 +386,6 @@ default_entry: /* Shift the stack pointer to a virtual address */ addl $__PAGE_OFFSET, %esp -/* - * Initialize eflags. Some BIOS's leave bits like NT set. This would - * confuse the debugger if this code is traced. - * XXX - best to initialize before switching to protected mode. - */ - pushl $0 - popfl - /* * start system 32-bit setup. We need to re-do some of the things done * in 16-bit mode for the "real" operations. @@ -461,7 +462,6 @@ is486: movl $0x50022,%ecx # set AM, WP, NE and MP xorl %eax,%eax # Clear LDT lldt %ax - cld # gcc2 wants the direction flag cleared at all times pushl $0 # fake return address for unwinder jmp *(initial_code)