]> git.ipfire.org Git - people/ms/linux.git/blobdiff - arch/x86/kernel/traps.c
Merge tag 'v5.5-rc1' into core/kprobes, to resolve conflicts
[people/ms/linux.git] / arch / x86 / kernel / traps.c
index 3451a004e16257cff9cb3cf6dcd9327f158fe069..f19de6f45d48912b4be166830842a3cce5b380a2 100644 (file)
@@ -306,8 +306,23 @@ __visible void __noreturn handle_stack_overflow(const char *message,
 }
 #endif
 
-#ifdef CONFIG_X86_64
-/* Runs on IST stack */
+#if defined(CONFIG_X86_64) || defined(CONFIG_DOUBLEFAULT)
+/*
+ * Runs on an IST stack for x86_64 and on a special task stack for x86_32.
+ *
+ * On x86_64, this is more or less a normal kernel entry.  Notwithstanding the
+ * SDM's warnings about double faults being unrecoverable, returning works as
+ * expected.  Presumably what the SDM actually means is that the CPU may get
+ * the register state wrong on entry, so returning could be a bad idea.
+ *
+ * Various CPU engineers have promised that double faults due to an IRET fault
+ * while the stack is read-only are, in fact, recoverable.
+ *
+ * On x86_32, this is entered through a task gate, and regs are synthesized
+ * from the TSS.  Returning is, in principle, okay, but changes to regs will
+ * be lost.  If, for some reason, we need to return to a context with modified
+ * regs, the shim code could be adjusted to synchronize the registers.
+ */
 dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsigned long cr2)
 {
        static const char str[] = "double fault";
@@ -411,15 +426,9 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsign
                handle_stack_overflow("kernel stack overflow (double-fault)", regs, cr2);
 #endif
 
-#ifdef CONFIG_DOUBLEFAULT
-       df_debug(regs, error_code);
-#endif
-       /*
-        * This is always a kernel trap and never fixable (and thus must
-        * never return).
-        */
-       for (;;)
-               die(str, regs, error_code);
+       pr_emerg("PANIC: double fault, error_code: 0x%lx\n", error_code);
+       die("double fault", regs, error_code);
+       panic("Machine halted.");
 }
 #endif