Blame view

arch/x86/kernel/verify_cpu.S 3.63 KB
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
1
2
3
4
5
6
7
8
9
  /*
   *
   *	verify_cpu.S - Code for cpu long mode and SSE verification. This
   *	code has been borrowed from boot/setup.S and was introduced by
   * 	Andi Kleen.
   *
   *	Copyright (c) 2007  Andi Kleen (ak@suse.de)
   *	Copyright (c) 2007  Eric Biederman (ebiederm@xmission.com)
   *	Copyright (c) 2007  Vivek Goyal (vgoyal@in.ibm.com)
ae84739c2   Kees Cook   x86, cpu: Clear X...
10
   *	Copyright (c) 2010  Kees Cook (kees.cook@canonical.com)
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
11
12
13
14
15
16
17
   *
   * 	This source code is licensed under the GNU General Public License,
   * 	Version 2.  See the file COPYING for more details.
   *
   *	This is a common code for verification whether CPU supports
   * 	long mode and SSE or not. It is not called directly instead this
   *	file is included at various places and compiled in that context.
ae84739c2   Kees Cook   x86, cpu: Clear X...
18
   *	This file is expected to run in 32bit code.  Currently:
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
19
   *
79250af2d   Kees Cook   x86: Fix included...
20
   *	arch/x86/boot/compressed/head_64.S: Boot cpu verification
0d2eb44f6   Lucas De Marchi   x86: Fix common m...
21
   *	arch/x86/kernel/trampoline_64.S: secondary processor verification
79250af2d   Kees Cook   x86: Fix included...
22
   *	arch/x86/kernel/head_32.S: processor startup
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
23
   *
ae84739c2   Kees Cook   x86, cpu: Clear X...
24
   *	verify_cpu, returns the status of longmode and SSE in register %eax.
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
25
26
   *		0: Success    1: Failure
   *
ae84739c2   Kees Cook   x86, cpu: Clear X...
27
28
   *	On Intel, the XD_DISABLE flag will be cleared as a side-effect.
   *
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
29
30
31
   * 	The caller needs to check for the error code and take the action
   * 	appropriately. Either display a message or halt.
   */
72b1b1d01   Andi Kleen   [PATCH] x86-64: U...
32
  #include <asm/cpufeature.h>
cfaa71ee9   Brian Gerst   x86: Use symbolic...
33
  #include <asm/msr-index.h>
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
34

72b1b1d01   Andi Kleen   [PATCH] x86-64: U...
35
  verify_cpu:
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
36
37
38
  	pushfl				# Save caller passed flags
  	pushl	$0			# Kill any dangerous flags
  	popfl
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  	pushfl				# standard way to check for cpuid
  	popl	%eax
  	movl	%eax,%ebx
  	xorl	$0x200000,%eax
  	pushl	%eax
  	popfl
  	pushfl
  	popl	%eax
  	cmpl	%eax,%ebx
  	jz	verify_cpu_no_longmode	# cpu has no cpuid
  
  	movl	$0x0,%eax		# See if cpuid 1 is implemented
  	cpuid
  	cmpl	$0x1,%eax
  	jb	verify_cpu_no_longmode	# no cpuid 1
  
  	xor	%di,%di
  	cmpl	$0x68747541,%ebx	# AuthenticAMD
  	jnz	verify_cpu_noamd
  	cmpl	$0x69746e65,%edx
  	jnz	verify_cpu_noamd
  	cmpl	$0x444d4163,%ecx
  	jnz	verify_cpu_noamd
  	mov	$1,%di			# cpu is from AMD
ae84739c2   Kees Cook   x86, cpu: Clear X...
63
  	jmp	verify_cpu_check
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
64
65
  
  verify_cpu_noamd:
ae84739c2   Kees Cook   x86, cpu: Clear X...
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  	cmpl	$0x756e6547,%ebx        # GenuineIntel?
  	jnz	verify_cpu_check
  	cmpl	$0x49656e69,%edx
  	jnz	verify_cpu_check
  	cmpl	$0x6c65746e,%ecx
  	jnz	verify_cpu_check
  
  	# only call IA32_MISC_ENABLE when:
  	# family > 6 || (family == 6 && model >= 0xd)
  	movl	$0x1, %eax		# check CPU family and model
  	cpuid
  	movl	%eax, %ecx
  
  	andl	$0x0ff00f00, %eax	# mask family and extended family
  	shrl	$8, %eax
  	cmpl	$6, %eax
  	ja	verify_cpu_clear_xd	# family > 6, ok
  	jb	verify_cpu_check	# family < 6, skip
  
  	andl	$0x000f00f0, %ecx	# mask model and extended model
  	shrl	$4, %ecx
  	cmpl	$0xd, %ecx
  	jb	verify_cpu_check	# family == 6, model < 0xd, skip
  
  verify_cpu_clear_xd:
  	movl	$MSR_IA32_MISC_ENABLE, %ecx
  	rdmsr
  	btrl	$2, %edx		# clear MSR_IA32_MISC_ENABLE_XD_DISABLE
  	jnc	verify_cpu_check	# only write MSR if bit was changed
  	wrmsr
  
  verify_cpu_check:
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
98
99
  	movl    $0x1,%eax		# Does the cpu have what it takes
  	cpuid
ec481536b   H. Peter Anvin   Unify the CPU fea...
100
101
  	andl	$REQUIRED_MASK0,%edx
  	xorl	$REQUIRED_MASK0,%edx
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
102
103
104
105
106
107
108
109
110
  	jnz	verify_cpu_no_longmode
  
  	movl    $0x80000000,%eax	# See if extended cpuid is implemented
  	cpuid
  	cmpl    $0x80000001,%eax
  	jb      verify_cpu_no_longmode	# no extended cpuid
  
  	movl    $0x80000001,%eax	# Does the cpu have what it takes
  	cpuid
ec481536b   H. Peter Anvin   Unify the CPU fea...
111
112
  	andl    $REQUIRED_MASK1,%edx
  	xorl    $REQUIRED_MASK1,%edx
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
113
114
115
116
117
118
119
120
121
122
  	jnz     verify_cpu_no_longmode
  
  verify_cpu_sse_test:
  	movl	$1,%eax
  	cpuid
  	andl	$SSE_MASK,%edx
  	cmpl	$SSE_MASK,%edx
  	je	verify_cpu_sse_ok
  	test	%di,%di
  	jz	verify_cpu_no_longmode	# only try to force SSE on AMD
cfaa71ee9   Brian Gerst   x86: Use symbolic...
123
  	movl	$MSR_K7_HWCR,%ecx
a4831e08b   Vivek Goyal   [PATCH] x86-64: M...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
  	rdmsr
  	btr	$15,%eax		# enable SSE
  	wrmsr
  	xor	%di,%di			# don't loop
  	jmp	verify_cpu_sse_test	# try again
  
  verify_cpu_no_longmode:
  	popfl				# Restore caller passed flags
  	movl $1,%eax
  	ret
  verify_cpu_sse_ok:
  	popfl				# Restore caller passed flags
  	xorl %eax, %eax
  	ret