|
@@ -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:
|