Merge branch 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-block.git] / arch / x86 / entry / entry_64.S
index a9ec5d3c6e671ed47a4743107ff9aa351af6e943..7c5ce0a6c4d2623edccda5f3586a591da3abc12e 100644 (file)
@@ -1189,6 +1189,16 @@ ENTRY(paranoid_entry)
        xorl    %ebx, %ebx
 
 1:
+       /*
+        * Always stash CR3 in %r14.  This value will be restored,
+        * verbatim, at exit.  Needed if paranoid_entry interrupted
+        * another entry that already switched to the user CR3 value
+        * but has not yet returned to userspace.
+        *
+        * This is also why CS (stashed in the "iret frame" by the
+        * hardware at entry) can not be used: this may be a return
+        * to kernel code, but with a user CR3 value.
+        */
        SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14
 
        ret
@@ -1213,11 +1223,13 @@ ENTRY(paranoid_exit)
        testl   %ebx, %ebx                      /* swapgs needed? */
        jnz     .Lparanoid_exit_no_swapgs
        TRACE_IRQS_IRETQ
+       /* Always restore stashed CR3 value (see paranoid_entry) */
        RESTORE_CR3     scratch_reg=%rbx save_reg=%r14
        SWAPGS_UNSAFE_STACK
        jmp     .Lparanoid_exit_restore
 .Lparanoid_exit_no_swapgs:
        TRACE_IRQS_IRETQ_DEBUG
+       /* Always restore stashed CR3 value (see paranoid_entry) */
        RESTORE_CR3     scratch_reg=%rbx save_reg=%r14
 .Lparanoid_exit_restore:
        jmp restore_regs_and_return_to_kernel
@@ -1628,6 +1640,7 @@ end_repeat_nmi:
        movq    $-1, %rsi
        call    do_nmi
 
+       /* Always restore stashed CR3 value (see paranoid_entry) */
        RESTORE_CR3 scratch_reg=%r15 save_reg=%r14
 
        testl   %ebx, %ebx                      /* swapgs needed? */