提交 162e6df4 编写于 作者: L Linus Torvalds

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner:
 "Two bugfixes from Andy addressing at least some of the subtle NMI
  related wreckage which has been reported by Sasha Levin"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/nmi/64: Fix a paravirt stack-clobbering bug in the NMI code
  x86/paravirt: Replace the paravirt nop with a bona fide empty function
...@@ -1128,7 +1128,18 @@ END(error_exit) ...@@ -1128,7 +1128,18 @@ END(error_exit)
/* Runs on exception stack */ /* Runs on exception stack */
ENTRY(nmi) ENTRY(nmi)
/*
* Fix up the exception frame if we're on Xen.
* PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most
* one value to the stack on native, so it may clobber the rdx
* scratch slot, but it won't clobber any of the important
* slots past it.
*
* Xen is a different story, because the Xen frame itself overlaps
* the "NMI executing" variable.
*/
PARAVIRT_ADJUST_EXCEPTION_FRAME PARAVIRT_ADJUST_EXCEPTION_FRAME
/* /*
* We allow breakpoints in NMIs. If a breakpoint occurs, then * We allow breakpoints in NMIs. If a breakpoint occurs, then
* the iretq it performs will take us out of NMI context. * the iretq it performs will take us out of NMI context.
...@@ -1179,9 +1190,12 @@ ENTRY(nmi) ...@@ -1179,9 +1190,12 @@ ENTRY(nmi)
* we don't want to enable interrupts, because then we'll end * we don't want to enable interrupts, because then we'll end
* up in an awkward situation in which IRQs are on but NMIs * up in an awkward situation in which IRQs are on but NMIs
* are off. * are off.
*
* We also must not push anything to the stack before switching
* stacks lest we corrupt the "NMI executing" variable.
*/ */
SWAPGS SWAPGS_UNSAFE_STACK
cld cld
movq %rsp, %rdx movq %rsp, %rdx
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
......
...@@ -41,10 +41,18 @@ ...@@ -41,10 +41,18 @@
#include <asm/timer.h> #include <asm/timer.h>
#include <asm/special_insns.h> #include <asm/special_insns.h>
/* nop stub */ /*
void _paravirt_nop(void) * nop stub, which must not clobber anything *including the stack* to
{ * avoid confusing the entry prologues.
} */
extern void _paravirt_nop(void);
asm (".pushsection .entry.text, \"ax\"\n"
".global _paravirt_nop\n"
"_paravirt_nop:\n\t"
"ret\n\t"
".size _paravirt_nop, . - _paravirt_nop\n\t"
".type _paravirt_nop, @function\n\t"
".popsection");
/* identity function, which can be inlined */ /* identity function, which can be inlined */
u32 _paravirt_ident_32(u32 x) u32 _paravirt_ident_32(u32 x)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册