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
Unified · Split
| @@ -1128,7 +1128,18 @@ END(error_exit) · 1127 unmodified lines | ||
| 1128 | 1128 | |
| 1129 | 1129 | /* Runs on exception stack */ |
| 1130 | 1130 | 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 | + */ | |
| 1131 | 1141 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1142 | + | |
| 1132 | 1143 | /* |
| 1133 | 1144 | * We allow breakpoints in NMIs. If a breakpoint occurs, then |
| 1134 | 1145 | * the iretq it performs will take us out of NMI context. |
| @@ -1179,9 +1190,12 @@ ENTRY(nmi) · 44 unmodified lines | ||
| 1179 | 1190 | * we don't want to enable interrupts, because then we'll end |
| 1180 | 1191 | * up in an awkward situation in which IRQs are on but NMIs |
| 1181 | 1192 | * are off. |
| 1193 | + * | |
| 1194 | + * We also must not push anything to the stack before switching | |
| 1195 | + * stacks lest we corrupt the "NMI executing" variable. | |
| 1182 | 1196 | */ |
| 1183 | 1197 | |
| 1184 | − SWAPGS | |
| 1198 | + SWAPGS_UNSAFE_STACK | |
| 1185 | 1199 | cld |
| 1186 | 1200 | movq %rsp, %rdx |
| 1187 | 1201 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| @@ -41,10 +41,18 @@ · 40 unmodified lines | ||
| 41 | 41 | #include <asm/timer.h> |
| 42 | 42 | #include <asm/special_insns.h> |
| 43 | 43 | |
| 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"); | |
| 48 | 56 | |
| 49 | 57 | /* identity function, which can be inlined */ |
| 50 | 58 | u32 _paravirt_ident_32(u32 x) |