Commit-ID:  929bacec21478a72c78e4f29f98fb799bd00105a
Gitweb:     https://git.kernel.org/tip/929bacec21478a72c78e4f29f98fb799bd00105a
Author:     Andy Lutomirski <l...@kernel.org>
AuthorDate: Thu, 2 Nov 2017 00:59:08 -0700
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Thu, 2 Nov 2017 11:04:42 +0100

x86/entry/64: De-Xen-ify our NMI code

Xen PV is fundamentally incompatible with our fancy NMI code: it
doesn't use IST at all, and Xen entries clobber two stack slots
below the hardware frame.

Drop Xen PV support from our NMI code entirely.

Signed-off-by: Andy Lutomirski <l...@kernel.org>
Reviewed-by: Borislav Petkov <b...@suse.de>
Acked-by: Juergen Gross <jgr...@suse.com>
Cc: Boris Ostrovsky <boris.ostrov...@oracle.com>
Cc: Borislav Petkov <bpet...@suse.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@intel.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Link: 
http://lkml.kernel.org/r/bfbe711b5ae03f672f8848999a8eb2711efc7f98.1509609304.git.l...@kernel.org
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 arch/x86/entry/entry_64.S | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index a3f76ab..40e9933 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -1240,9 +1240,13 @@ ENTRY(error_exit)
        jmp     retint_user
 END(error_exit)
 
-/* Runs on exception stack */
+/*
+ * Runs on exception stack.  Xen PV does not go through this path at all,
+ * so we can use real assembly here.
+ */
 ENTRY(nmi)
        UNWIND_HINT_IRET_REGS
+
        /*
         * We allow breakpoints in NMIs. If a breakpoint occurs, then
         * the iretq it performs will take us out of NMI context.
@@ -1300,7 +1304,7 @@ ENTRY(nmi)
         * stacks lest we corrupt the "NMI executing" variable.
         */
 
-       SWAPGS_UNSAFE_STACK
+       swapgs
        cld
        movq    %rsp, %rdx
        movq    PER_CPU_VAR(cpu_current_top_of_stack), %rsp
@@ -1465,7 +1469,7 @@ nested_nmi_out:
        popq    %rdx
 
        /* We are returning to kernel mode, so this cannot result in a fault. */
-       INTERRUPT_RETURN
+       iretq
 
 first_nmi:
        /* Restore rdx. */
@@ -1496,7 +1500,7 @@ first_nmi:
        pushfq                  /* RFLAGS */
        pushq   $__KERNEL_CS    /* CS */
        pushq   $1f             /* RIP */
-       INTERRUPT_RETURN        /* continues at repeat_nmi below */
+       iretq                   /* continues at repeat_nmi below */
        UNWIND_HINT_IRET_REGS
 1:
 #endif
@@ -1571,20 +1575,22 @@ nmi_restore:
        /*
         * Clear "NMI executing".  Set DF first so that we can easily
         * distinguish the remaining code between here and IRET from
-        * the SYSCALL entry and exit paths.  On a native kernel, we
-        * could just inspect RIP, but, on paravirt kernels,
-        * INTERRUPT_RETURN can translate into a jump into a
-        * hypercall page.
+        * the SYSCALL entry and exit paths.
+        *
+        * We arguably should just inspect RIP instead, but I (Andy) wrote
+        * this code when I had the misapprehension that Xen PV supported
+        * NMIs, and Xen PV would break that approach.
         */
        std
        movq    $0, 5*8(%rsp)           /* clear "NMI executing" */
 
        /*
-        * INTERRUPT_RETURN reads the "iret" frame and exits the NMI
-        * stack in a single instruction.  We are returning to kernel
-        * mode, so this cannot result in a fault.
+        * iretq reads the "iret" frame and exits the NMI stack in a
+        * single instruction.  We are returning to kernel mode, so this
+        * cannot result in a fault.  Similarly, we don't need to worry
+        * about espfix64 on the way back to kernel mode.
         */
-       INTERRUPT_RETURN
+       iretq
 END(nmi)
 
 ENTRY(ignore_sysret)

Reply via email to