From 801ab68891b909140892f3bb443329f171cbd75d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 7 Jun 2012 10:21:21 -0400 Subject: [PATCH] --- yaml --- r: 312401 b: refs/heads/master c: 7fbb98c5cb07563d3ee08714073a8e5452a96be2 h: refs/heads/master i: 312399: 754be7fd32b0f4400ceae3fe8f7cde36832ca003 v: v3 --- [refs] | 2 +- trunk/arch/x86/kernel/entry_64.S | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 90d5fa0f2a1b..0db5e6c5c0e0 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c767a54ba0657e52e6edaa97cbe0b0a8bf1c1655 +refs/heads/master: 7fbb98c5cb07563d3ee08714073a8e5452a96be2 diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index 7d65133b51be..111f6bbd8b38 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -1758,10 +1758,30 @@ end_repeat_nmi: */ call save_paranoid DEFAULT_FRAME 0 + + /* + * Save off the CR2 register. If we take a page fault in the NMI then + * it could corrupt the CR2 value. If the NMI preempts a page fault + * handler before it was able to read the CR2 register, and then the + * NMI itself takes a page fault, the page fault that was preempted + * will read the information from the NMI page fault and not the + * origin fault. Save it off and restore it if it changes. + * Use the r12 callee-saved register. + */ + movq %cr2, %r12 + /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ movq %rsp,%rdi movq $-1,%rsi call do_nmi + + /* Did the NMI take a page fault? Restore cr2 if it did */ + movq %cr2, %rcx + cmpq %rcx, %r12 + je 1f + movq %r12, %cr2 +1: + testl %ebx,%ebx /* swapgs needed? */ jnz nmi_restore nmi_swapgs: