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 | /* Runs on exception stack */ | 1129 | /* Runs on exception stack */ |
| 1130 | ENTRY(nmi) | 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 | PARAVIRT_ADJUST_EXCEPTION_FRAME | 1141 | PARAVIRT_ADJUST_EXCEPTION_FRAME |
| 1142 | |||
| 1132 | /* | 1143 | /* |
| 1133 | * We allow breakpoints in NMIs. If a breakpoint occurs, then | 1144 | * We allow breakpoints in NMIs. If a breakpoint occurs, then |
| 1134 | * the iretq it performs will take us out of NMI context. | 1145 | * the iretq it performs will take us out of NMI context. |
| @@ -1179,9 +1190,12 @@ ENTRY(nmi) · 44 unmodified lines | |||
| 1179 | * we don't want to enable interrupts, because then we'll end | 1190 | * we don't want to enable interrupts, because then we'll end |
| 1180 | * up in an awkward situation in which IRQs are on but NMIs | 1191 | * up in an awkward situation in which IRQs are on but NMIs |
| 1181 | * are off. | 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 | cld | 1199 | cld |
| 1186 | movq %rsp, %rdx | 1200 | movq %rsp, %rdx |
| 1187 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp | 1201 | movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp |
| @@ -41,10 +41,18 @@ · 40 unmodified lines | |||
| 41 | #include <asm/timer.h> | 41 | #include <asm/timer.h> |
| 42 | #include <asm/special_insns.h> | 42 | #include <asm/special_insns.h> |
| 43 | 43 | ||
| 44 | /* nop stub */ | 44 | /* |
| 45 | void _paravirt_nop(void) | 45 | * nop stub, which must not clobber anything *including the stack* to |
| 46 | { | 46 | * avoid confusing the entry prologues. |
| 47 | } | 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 | /* identity function, which can be inlined */ | 57 | /* identity function, which can be inlined */ |
| 50 | u32 _paravirt_ident_32(u32 x) | 58 | u32 _paravirt_ident_32(u32 x) |