diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-21 15:43:14 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-09-21 15:45:27 -0400 |
commit | 40d3cd6695014bf3c44e2ca66b610b18acaf923d (patch) | |
tree | 535ecc7a30ea16221efbd16fcd1717e8ed4b6183 /arch/x86 | |
parent | 52b6179ac87d33c2eeaff5292786a10fe98cff64 (diff) |
x86, smap: A page fault due to SMAP is an oops
If we get a page fault due to SMAP, trigger an oops rather than
spinning forever.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1348256595-29119-11-git-send-email-hpa@linux.intel.com
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/mm/fault.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 76dcd9d8e0bc..f2fb75d46b96 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -995,6 +995,17 @@ static int fault_in_kernel_space(unsigned long address) | |||
995 | return address >= TASK_SIZE_MAX; | 995 | return address >= TASK_SIZE_MAX; |
996 | } | 996 | } |
997 | 997 | ||
998 | static inline bool smap_violation(int error_code, struct pt_regs *regs) | ||
999 | { | ||
1000 | if (error_code & PF_USER) | ||
1001 | return false; | ||
1002 | |||
1003 | if (!user_mode_vm(regs) && (regs->flags & X86_EFLAGS_AC)) | ||
1004 | return false; | ||
1005 | |||
1006 | return true; | ||
1007 | } | ||
1008 | |||
998 | /* | 1009 | /* |
999 | * This routine handles page faults. It determines the address, | 1010 | * This routine handles page faults. It determines the address, |
1000 | * and the problem, and then passes it off to one of the appropriate | 1011 | * and the problem, and then passes it off to one of the appropriate |
@@ -1088,6 +1099,13 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
1088 | if (unlikely(error_code & PF_RSVD)) | 1099 | if (unlikely(error_code & PF_RSVD)) |
1089 | pgtable_bad(regs, error_code, address); | 1100 | pgtable_bad(regs, error_code, address); |
1090 | 1101 | ||
1102 | if (static_cpu_has(X86_FEATURE_SMAP)) { | ||
1103 | if (unlikely(smap_violation(error_code, regs))) { | ||
1104 | bad_area_nosemaphore(regs, error_code, address); | ||
1105 | return; | ||
1106 | } | ||
1107 | } | ||
1108 | |||
1091 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); | 1109 | perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); |
1092 | 1110 | ||
1093 | /* | 1111 | /* |