]>
Commit | Line | Data |
---|---|---|
b18e18e8 GKH |
1 | From 4640c7ee9b8953237d05a61ea3ea93981d1bc961 Mon Sep 17 00:00:00 2001 |
2 | From: "H. Peter Anvin" <hpa@linux.intel.com> | |
3 | Date: Thu, 13 Feb 2014 07:46:04 -0800 | |
4 | Subject: x86, smap: smap_violation() is bogus if CONFIG_X86_SMAP is off | |
5 | ||
6 | From: "H. Peter Anvin" <hpa@linux.intel.com> | |
7 | ||
8 | commit 4640c7ee9b8953237d05a61ea3ea93981d1bc961 upstream. | |
9 | ||
10 | If CONFIG_X86_SMAP is disabled, smap_violation() tests for conditions | |
11 | which are incorrect (as the AC flag doesn't matter), causing spurious | |
12 | faults. | |
13 | ||
14 | The dynamic disabling of SMAP (nosmap on the command line) is fine | |
15 | because it disables X86_FEATURE_SMAP, therefore causing the | |
16 | static_cpu_has() to return false. | |
17 | ||
18 | Found by Fengguang Wu's test system. | |
19 | ||
20 | [ v3: move all predicates into smap_violation() ] | |
21 | [ v2: use IS_ENABLED() instead of #ifdef ] | |
22 | ||
23 | Reported-by: Fengguang Wu <fengguang.wu@intel.com> | |
24 | Link: http://lkml.kernel.org/r/20140213124550.GA30497@localhost | |
25 | Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
27 | ||
28 | --- | |
29 | arch/x86/mm/fault.c | 14 +++++++++----- | |
30 | 1 file changed, 9 insertions(+), 5 deletions(-) | |
31 | ||
32 | --- a/arch/x86/mm/fault.c | |
33 | +++ b/arch/x86/mm/fault.c | |
34 | @@ -989,6 +989,12 @@ static int fault_in_kernel_space(unsigne | |
35 | ||
36 | static inline bool smap_violation(int error_code, struct pt_regs *regs) | |
37 | { | |
38 | + if (!IS_ENABLED(CONFIG_X86_SMAP)) | |
39 | + return false; | |
40 | + | |
41 | + if (!static_cpu_has(X86_FEATURE_SMAP)) | |
42 | + return false; | |
43 | + | |
44 | if (error_code & PF_USER) | |
45 | return false; | |
46 | ||
47 | @@ -1091,11 +1097,9 @@ __do_page_fault(struct pt_regs *regs, un | |
48 | if (unlikely(error_code & PF_RSVD)) | |
49 | pgtable_bad(regs, error_code, address); | |
50 | ||
51 | - if (static_cpu_has(X86_FEATURE_SMAP)) { | |
52 | - if (unlikely(smap_violation(error_code, regs))) { | |
53 | - bad_area_nosemaphore(regs, error_code, address); | |
54 | - return; | |
55 | - } | |
56 | + if (unlikely(smap_violation(error_code, regs))) { | |
57 | + bad_area_nosemaphore(regs, error_code, address); | |
58 | + return; | |
59 | } | |
60 | ||
61 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); |