Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9efb58de authored by Borislav Petkov's avatar Borislav Petkov Committed by H. Peter Anvin
Browse files

x86: Detect CPUID support early at boot



We detect CPUID function support on each CPU and save it for later use,
obviating the need to play the toggle EFLAGS.ID game every time. C code
is looking at ->cpuid_level anyway.

Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Link: http://lkml.kernel.org/r/1360592538-10643-3-git-send-email-bp@alien8.de


Signed-off-by: default avatarH. Peter Anvin <hpa@linux.intel.com>
parent 166df91d
Loading
Loading
Loading
Loading
+25 −25
Original line number Original line Diff line number Diff line
@@ -307,25 +307,34 @@ default_entry:
	movl %eax,%cr0
	movl %eax,%cr0


/*
/*
 *	New page tables may be in 4Mbyte page mode and may
 * We want to start out with EFLAGS unambiguously cleared. Some BIOSes leave
 *	be using the global pages. 
 * 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!
 * NOTE! If we are on a 486 we may have no cr4 at all! Specifically, cr4 exists
 *	Specifically, cr4 exists if and only if CPUID exists
 * if and only if CPUID exists and has flags other than the FPU flag set.
 *	and has flags other than the FPU flag set.
 */
 */
	movl $-1,pa(X86_CPUID)		# preset CPUID level
	movl $X86_EFLAGS_ID,%ecx
	movl $X86_EFLAGS_ID,%ecx
	pushl %ecx
	pushl %ecx
	popfl
	popfl				# set EFLAGS=ID
	pushfl
	popl %eax
	pushl $0
	popfl
	pushfl
	pushfl
	popl %edx
	popl %eax			# get EFLAGS
	xorl %edx,%eax
	testl $X86_EFLAGS_ID,%eax	# did EFLAGS.ID remained set?
	testl %ecx,%eax
	jz 6f				# hw disallowed setting of ID bit
	jz 6f			# No ID flag = no CPUID = no CR4
					# which means no CPUID and no CR4

	xorl %eax,%eax
	cpuid
	movl %eax,pa(X86_CPUID)		# save largest std CPUID function


	movl $1,%eax
	movl $1,%eax
	cpuid
	cpuid
@@ -377,14 +386,6 @@ default_entry:
	/* Shift the stack pointer to a virtual address */
	/* Shift the stack pointer to a virtual address */
	addl $__PAGE_OFFSET, %esp
	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
 * start system 32-bit setup. We need to re-do some of the things done
 * in 16-bit mode for the "real" operations.
 * 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
	xorl %eax,%eax			# Clear LDT
	lldt %ax
	lldt %ax


	cld			# gcc2 wants the direction flag cleared at all times
	pushl $0		# fake return address for unwinder
	pushl $0		# fake return address for unwinder
	jmp *(initial_code)
	jmp *(initial_code)