aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKees Cook <kees.cook@canonical.com>2010-11-10 13:35:52 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2010-11-10 18:42:54 -0500
commitae84739c27b6b3725993202fe02ff35ab86468e1 (patch)
treeda5c217456d38e56218d059154186287a9d1e54a
parentc5cbac69422a9bffe7c7fd9a115130e272b547f5 (diff)
x86, cpu: Clear XD_DISABLED flag on Intel to regain NX
Intel CPUs have an additional MSR bit to indicate if the BIOS was configured to disable the NX cpu feature. This bit was traditionally used for operating systems that did not understand how to handle the NX bit. Since Linux understands this, this BIOS flag should be ignored by default. In a review[1] of reported hardware being used by Ubuntu bug reporters, almost 10% of systems had an incorrectly configured BIOS, leaving their systems unable to use the NX features of their CPU. This change will clear the MSR_IA32_MISC_ENABLE_XD_DISABLE bit so that NX cannot be inappropriately controlled by the BIOS on Intel CPUs. If, under very strange hardware configurations, NX actually needs to be disabled, "noexec=off" can be used to restore the prior behavior. [1] http://www.outflux.net/blog/archives/2010/02/18/data-mining-for-nx-bit/ Signed-off-by: Kees Cook <kees.cook@canonical.com> LKML-Reference: <1289414154-7829-3-git-send-email-kees.cook@canonical.com> Acked-by: Pekka Enberg <penberg@kernel.org> Acked-by: Alan Cox <alan@lxorguk.ukuu.org.uk> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--arch/x86/kernel/verify_cpu.S48
1 files changed, 40 insertions, 8 deletions
diff --git a/arch/x86/kernel/verify_cpu.S b/arch/x86/kernel/verify_cpu.S
index 56a8c2a867d9..ccb4136da0aa 100644
--- a/arch/x86/kernel/verify_cpu.S
+++ b/arch/x86/kernel/verify_cpu.S
@@ -7,6 +7,7 @@
7 * Copyright (c) 2007 Andi Kleen (ak@suse.de) 7 * Copyright (c) 2007 Andi Kleen (ak@suse.de)
8 * Copyright (c) 2007 Eric Biederman (ebiederm@xmission.com) 8 * Copyright (c) 2007 Eric Biederman (ebiederm@xmission.com)
9 * Copyright (c) 2007 Vivek Goyal (vgoyal@in.ibm.com) 9 * Copyright (c) 2007 Vivek Goyal (vgoyal@in.ibm.com)
10 * Copyright (c) 2010 Kees Cook (kees.cook@canonical.com)
10 * 11 *
11 * This source code is licensed under the GNU General Public License, 12 * This source code is licensed under the GNU General Public License,
12 * Version 2. See the file COPYING for more details. 13 * Version 2. See the file COPYING for more details.
@@ -14,18 +15,16 @@
14 * This is a common code for verification whether CPU supports 15 * This is a common code for verification whether CPU supports
15 * long mode and SSE or not. It is not called directly instead this 16 * long mode and SSE or not. It is not called directly instead this
16 * file is included at various places and compiled in that context. 17 * file is included at various places and compiled in that context.
17 * Following are the current usage. 18 * This file is expected to run in 32bit code. Currently:
18 * 19 *
19 * This file is included by both 16bit and 32bit code. 20 * arch/x86_64/boot/compressed/head_64.S: Boot cpu verification
21 * arch/x86_64/kernel/trampoline_64.S: secondary processor verfication
20 * 22 *
21 * arch/x86_64/boot/setup.S : Boot cpu verification (16bit) 23 * verify_cpu, returns the status of longmode and SSE in register %eax.
22 * arch/x86_64/boot/compressed/head.S: Boot cpu verification (32bit)
23 * arch/x86_64/kernel/trampoline.S: secondary processor verfication (16bit)
24 * arch/x86_64/kernel/acpi/wakeup.S:Verfication at resume (16bit)
25 *
26 * verify_cpu, returns the status of cpu check in register %eax.
27 * 0: Success 1: Failure 24 * 0: Success 1: Failure
28 * 25 *
26 * On Intel, the XD_DISABLE flag will be cleared as a side-effect.
27 *
29 * The caller needs to check for the error code and take the action 28 * The caller needs to check for the error code and take the action
30 * appropriately. Either display a message or halt. 29 * appropriately. Either display a message or halt.
31 */ 30 */
@@ -62,8 +61,41 @@ verify_cpu:
62 cmpl $0x444d4163,%ecx 61 cmpl $0x444d4163,%ecx
63 jnz verify_cpu_noamd 62 jnz verify_cpu_noamd
64 mov $1,%di # cpu is from AMD 63 mov $1,%di # cpu is from AMD
64 jmp verify_cpu_check
65 65
66verify_cpu_noamd: 66verify_cpu_noamd:
67 cmpl $0x756e6547,%ebx # GenuineIntel?
68 jnz verify_cpu_check
69 cmpl $0x49656e69,%edx
70 jnz verify_cpu_check
71 cmpl $0x6c65746e,%ecx
72 jnz verify_cpu_check
73
74 # only call IA32_MISC_ENABLE when:
75 # family > 6 || (family == 6 && model >= 0xd)
76 movl $0x1, %eax # check CPU family and model
77 cpuid
78 movl %eax, %ecx
79
80 andl $0x0ff00f00, %eax # mask family and extended family
81 shrl $8, %eax
82 cmpl $6, %eax
83 ja verify_cpu_clear_xd # family > 6, ok
84 jb verify_cpu_check # family < 6, skip
85
86 andl $0x000f00f0, %ecx # mask model and extended model
87 shrl $4, %ecx
88 cmpl $0xd, %ecx
89 jb verify_cpu_check # family == 6, model < 0xd, skip
90
91verify_cpu_clear_xd:
92 movl $MSR_IA32_MISC_ENABLE, %ecx
93 rdmsr
94 btrl $2, %edx # clear MSR_IA32_MISC_ENABLE_XD_DISABLE
95 jnc verify_cpu_check # only write MSR if bit was changed
96 wrmsr
97
98verify_cpu_check:
67 movl $0x1,%eax # Does the cpu have what it takes 99 movl $0x1,%eax # Does the cpu have what it takes
68 cpuid 100 cpuid
69 andl $REQUIRED_MASK0,%edx 101 andl $REQUIRED_MASK0,%edx