diff options
author | Matt Fleming <matt.fleming@intel.com> | 2014-03-05 12:22:57 -0500 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2014-03-05 12:31:41 -0500 |
commit | 4fd69331ad227a4d8de26592d017b73e00caca9f (patch) | |
tree | bfd95ed518ff0cb44318715432d321a92a7b9a0c /arch/x86/mm | |
parent | 69e608411473ac56358ef35277563982d0565381 (diff) | |
parent | 0ac09f9f8cd1fb028a48330edba6023d347d3cea (diff) |
Merge remote-tracking branch 'tip/x86/urgent' into efi-for-mingo
Conflicts:
arch/x86/include/asm/efi.h
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/fault.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 6dea040cc3a1..e7fa28bf3262 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -1022,11 +1022,11 @@ static inline bool smap_violation(int error_code, struct pt_regs *regs) | |||
1022 | * routines. | 1022 | * routines. |
1023 | */ | 1023 | */ |
1024 | static void __kprobes | 1024 | static void __kprobes |
1025 | __do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1025 | __do_page_fault(struct pt_regs *regs, unsigned long error_code, |
1026 | unsigned long address) | ||
1026 | { | 1027 | { |
1027 | struct vm_area_struct *vma; | 1028 | struct vm_area_struct *vma; |
1028 | struct task_struct *tsk; | 1029 | struct task_struct *tsk; |
1029 | unsigned long address; | ||
1030 | struct mm_struct *mm; | 1030 | struct mm_struct *mm; |
1031 | int fault; | 1031 | int fault; |
1032 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; | 1032 | unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; |
@@ -1034,9 +1034,6 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
1034 | tsk = current; | 1034 | tsk = current; |
1035 | mm = tsk->mm; | 1035 | mm = tsk->mm; |
1036 | 1036 | ||
1037 | /* Get the faulting address: */ | ||
1038 | address = read_cr2(); | ||
1039 | |||
1040 | /* | 1037 | /* |
1041 | * Detect and handle instructions that would cause a page fault for | 1038 | * Detect and handle instructions that would cause a page fault for |
1042 | * both a tracked kernel page and a userspace page. | 1039 | * both a tracked kernel page and a userspace page. |
@@ -1252,9 +1249,11 @@ dotraplinkage void __kprobes | |||
1252 | do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1249 | do_page_fault(struct pt_regs *regs, unsigned long error_code) |
1253 | { | 1250 | { |
1254 | enum ctx_state prev_state; | 1251 | enum ctx_state prev_state; |
1252 | /* Get the faulting address: */ | ||
1253 | unsigned long address = read_cr2(); | ||
1255 | 1254 | ||
1256 | prev_state = exception_enter(); | 1255 | prev_state = exception_enter(); |
1257 | __do_page_fault(regs, error_code); | 1256 | __do_page_fault(regs, error_code, address); |
1258 | exception_exit(prev_state); | 1257 | exception_exit(prev_state); |
1259 | } | 1258 | } |
1260 | 1259 | ||
@@ -1271,9 +1270,16 @@ dotraplinkage void __kprobes | |||
1271 | trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1270 | trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) |
1272 | { | 1271 | { |
1273 | enum ctx_state prev_state; | 1272 | enum ctx_state prev_state; |
1273 | /* | ||
1274 | * The exception_enter and tracepoint processing could | ||
1275 | * trigger another page faults (user space callchain | ||
1276 | * reading) and destroy the original cr2 value, so read | ||
1277 | * the faulting address now. | ||
1278 | */ | ||
1279 | unsigned long address = read_cr2(); | ||
1274 | 1280 | ||
1275 | prev_state = exception_enter(); | 1281 | prev_state = exception_enter(); |
1276 | trace_page_fault_entries(regs, error_code); | 1282 | trace_page_fault_entries(regs, error_code); |
1277 | __do_page_fault(regs, error_code); | 1283 | __do_page_fault(regs, error_code, address); |
1278 | exception_exit(prev_state); | 1284 | exception_exit(prev_state); |
1279 | } | 1285 | } |