x86/doublefault/32: Move #DF stack and TSS to cpu_entry_area
authorAndy Lutomirski <luto@kernel.org>
Tue, 26 Nov 2019 17:27:16 +0000 (18:27 +0100)
committerIngo Molnar <mingo@kernel.org>
Tue, 26 Nov 2019 20:53:34 +0000 (21:53 +0100)
commitdc4e0021b00b5a4ecba56fae509217776592b0aa
treef62d0813a0fe93bc4aa7612632ec7cd744ccf33f
parente99b6f46ee5c127d39d2f3a2682fdeef10386316
x86/doublefault/32: Move #DF stack and TSS to cpu_entry_area

There are three problems with the current layout of the doublefault
stack and TSS.  First, the TSS is only cacheline-aligned, which is
not enough -- if the hardware portion of the TSS (struct x86_hw_tss)
crosses a page boundary, horrible things happen [0].  Second, the
stack and TSS are global, so simultaneous double faults on different
CPUs will cause massive corruption.  Third, the whole mechanism
won't work if user CR3 is loaded, resulting in a triple fault [1].

Let the doublefault stack and TSS share a page (which prevents the
TSS from spanning a page boundary), make it percpu, and move it into
cpu_entry_area.  Teach the stack dump code about the doublefault
stack.

[0] Real hardware will read past the end of the page onto the next
    *physical* page if a task switch happens.  Virtual machines may
    have any number of bugs, and I would consider it reasonable for
    a VM to summarily kill the guest if it tries to task-switch to
    a page-spanning TSS.

[1] Real hardware triple faults.  At least some VMs seem to hang.
    I'm not sure what's going on.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/include/asm/cpu_entry_area.h
arch/x86/include/asm/doublefault.h [new file with mode: 0644]
arch/x86/include/asm/pgtable_32_types.h
arch/x86/include/asm/processor.h
arch/x86/kernel/cpu/common.c
arch/x86/kernel/doublefault_32.c
arch/x86/kernel/dumpstack_32.c
arch/x86/mm/cpu_entry_area.c