History

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

Linus Torvalds committed 11 years ago

Commit 162e6df2 parents 5a6bdf0 83c133c2 files · +27 −5Browse files

Unified · Split

2 files
  1. arch/x86/entry/entry_64.S +15 −1
  2. arch/x86/kernel/paravirt.c +12 −4
arch/x86/entry/entry_64.S+15−1
@@ -1128,7 +1128,18 @@ END(error_exit) · 1127 unmodified lines
11281128
11291129 /* Runs on exception stack */
11301130 ENTRY(nmi)
1131+ /*
1132+ * Fix up the exception frame if we're on Xen.
1133+ * PARAVIRT_ADJUST_EXCEPTION_FRAME is guaranteed to push at most
1134+ * one value to the stack on native, so it may clobber the rdx
1135+ * scratch slot, but it won't clobber any of the important
1136+ * slots past it.
1137+ *
1138+ * Xen is a different story, because the Xen frame itself overlaps
1139+ * the "NMI executing" variable.
1140+ */
11311141 PARAVIRT_ADJUST_EXCEPTION_FRAME
1142+
11321143 /*
11331144 * We allow breakpoints in NMIs. If a breakpoint occurs, then
11341145 * the iretq it performs will take us out of NMI context.
@@ -1179,9 +1190,12 @@ ENTRY(nmi) · 44 unmodified lines
11791190 * we don't want to enable interrupts, because then we'll end
11801191 * up in an awkward situation in which IRQs are on but NMIs
11811192 * are off.
1193+ *
1194+ * We also must not push anything to the stack before switching
1195+ * stacks lest we corrupt the "NMI executing" variable.
11821196 */
11831197
1184− SWAPGS
1198+ SWAPGS_UNSAFE_STACK
11851199 cld
11861200 movq %rsp, %rdx
11871201 movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
arch/x86/kernel/paravirt.c+12−4
@@ -41,10 +41,18 @@ · 40 unmodified lines
4141 #include <asm/timer.h>
4242 #include <asm/special_insns.h>
4343
44−/* nop stub */
45−void _paravirt_nop(void)
46−{
47−}
44+/*
45+ * nop stub, which must not clobber anything *including the stack* to
46+ * avoid confusing the entry prologues.
47+ */
48+extern void _paravirt_nop(void);
49+asm (".pushsection .entry.text, \"ax\"\n"
50+ ".global _paravirt_nop\n"
51+ "_paravirt_nop:\n\t"
52+ "ret\n\t"
53+ ".size _paravirt_nop, . - _paravirt_nop\n\t"
54+ ".type _paravirt_nop, @function\n\t"
55+ ".popsection");
4856
4957 /* identity function, which can be inlined */
5058 u32 _paravirt_ident_32(u32 x)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t