aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2012-06-07 10:21:21 -0400
committerSteven Rostedt <rostedt@goodmis.org>2012-06-07 10:21:21 -0400
commit7fbb98c5cb07563d3ee08714073a8e5452a96be2 (patch)
tree44eb0ef69d4de7c686d2a278c686233d61a6580b
parentc767a54ba0657e52e6edaa97cbe0b0a8bf1c1655 (diff)
x86: Save cr2 in NMI in case NMIs take a page fault
Avi Kivity reported that page faults in NMIs could cause havic if the NMI preempted another page fault handler: The recent changes to NMI allow exceptions to take place in NMI handlers, but I think that a #PF (say, due to access to vmalloc space) is still problematic. Consider the sequence #PF (cr2 set by processor) NMI ... #PF (cr2 clobbered) do_page_fault() IRET ... IRET do_page_fault() address = read_cr2() The last line reads the overwritten cr2 value. Originally I wrote a patch to solve this by saving the cr2 on the stack. Brian Gerst suggested to save it in the r12 register as both r12 and rbx are saved by the do_nmi handler as required by the C standard. But rbx is already used for saving if swapgs needs to be run on exit of the NMI handler. Link: http://lkml.kernel.org/r/4FBB8C40.6080304@redhat.com Link: http://lkml.kernel.org/r/1337763411.13348.140.camel@gandalf.stny.rr.com Reported-by: Avi Kivity <avi@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Thomas Gleixner <tglx@linutronix.de> Suggested-by: Brian Gerst <brgerst@gmail.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--arch/x86/kernel/entry_64.S20
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 7d65133b51be..111f6bbd8b38 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1758,10 +1758,30 @@ end_repeat_nmi:
1758 */ 1758 */
1759 call save_paranoid 1759 call save_paranoid
1760 DEFAULT_FRAME 0 1760 DEFAULT_FRAME 0
1761
1762 /*
1763 * Save off the CR2 register. If we take a page fault in the NMI then
1764 * it could corrupt the CR2 value. If the NMI preempts a page fault
1765 * handler before it was able to read the CR2 register, and then the
1766 * NMI itself takes a page fault, the page fault that was preempted
1767 * will read the information from the NMI page fault and not the
1768 * origin fault. Save it off and restore it if it changes.
1769 * Use the r12 callee-saved register.
1770 */
1771 movq %cr2, %r12
1772
1761 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */ 1773 /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
1762 movq %rsp,%rdi 1774 movq %rsp,%rdi
1763 movq $-1,%rsi 1775 movq $-1,%rsi
1764 call do_nmi 1776 call do_nmi
1777
1778 /* Did the NMI take a page fault? Restore cr2 if it did */
1779 movq %cr2, %rcx
1780 cmpq %rcx, %r12
1781 je 1f
1782 movq %r12, %cr2
17831:
1784
1765 testl %ebx,%ebx /* swapgs needed? */ 1785 testl %ebx,%ebx /* swapgs needed? */
1766 jnz nmi_restore 1786 jnz nmi_restore
1767nmi_swapgs: 1787nmi_swapgs: