diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0024-kaiser-paranoid_entry-pass-cr3-need-to-paranoid_exit.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0024-kaiser-paranoid_entry-pass-cr3-need-to-paranoid_exit.patch | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0024-kaiser-paranoid_entry-pass-cr3-need-to-paranoid_exit.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0024-kaiser-paranoid_entry-pass-cr3-need-to-paranoid_exit.patch new file mode 100644 index 00000000..bc2cbebd --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0024-kaiser-paranoid_entry-pass-cr3-need-to-paranoid_exit.patch @@ -0,0 +1,172 @@ +From 901d7211374f31ffc00719e75113b958a4ae64d4 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins <hughd@google.com> +Date: Tue, 26 Sep 2017 18:43:07 -0700 +Subject: [PATCH 024/102] kaiser: paranoid_entry pass cr3 need to paranoid_exit + +Neel Natu points out that paranoid_entry() was wrong to assume that +an entry that did not need swapgs would not need SWITCH_KERNEL_CR3: +paranoid_entry (used for debug breakpoint, int3, double fault or MCE; +though I think it's only the MCE case that is cause for concern here) +can break in at an awkward time, between cr3 switch and swapgs, but +its handling always needs kernel gs and kernel cr3. + +Easy to fix in itself, but paranoid_entry() also needs to convey to +paranoid_exit() (and my reading of macro idtentry says paranoid_entry +and paranoid_exit are always paired) how to restore the prior state. +The swapgs state is already conveyed by %ebx (0 or 1), so extend that +also to convey when SWITCH_USER_CR3 will be needed (2 or 3). + +(Yes, I'd much prefer that 0 meant no swapgs, whereas it's the other +way round: and a convention shared with error_entry() and error_exit(), +which I don't want to touch. Perhaps I should have inverted the bit +for switch cr3 too, but did not.) + +paranoid_exit() would be straightforward, except for TRACE_IRQS: it +did TRACE_IRQS_IRETQ when doing swapgs, but TRACE_IRQS_IRETQ_DEBUG +when not: which is it supposed to use when SWITCH_USER_CR3 is split +apart from that? As best as I can determine, commit 5963e317b1e9 +("ftrace/x86: Do not change stacks in DEBUG when calling lockdep") +missed the swapgs case, and should have used TRACE_IRQS_IRETQ_DEBUG +there too (the discrepancy has nothing to do with the liberal use +of _NO_STACK and _UNSAFE_STACK hereabouts: TRACE_IRQS_OFF_DEBUG has +just been used in all cases); discrepancy lovingly preserved across +several paranoid_exit() cleanups, but I'm now removing it. + +Neel further indicates that to use SWITCH_USER_CR3_NO_STACK there in +paranoid_exit() is now not only unnecessary but unsafe: might corrupt +syscall entry's unsafe_stack_register_backup of %rax. Just use +SWITCH_USER_CR3: and delete SWITCH_USER_CR3_NO_STACK altogether, +before we make the mistake of using it again. + +hughd adds: this commit fixes an issue in the Kaiser-without-PCIDs +part of the series, and ought to be moved earlier, if you decided +to make a release of Kaiser-without-PCIDs. + +Signed-off-by: Hugh Dickins <hughd@google.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + arch/x86/entry/entry_64.S | 46 +++++++++++++++++++++++++++++++--------- + arch/x86/entry/entry_64_compat.S | 2 +- + arch/x86/include/asm/kaiser.h | 8 ------- + 3 files changed, 37 insertions(+), 19 deletions(-) + +diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S +index e158fd5..41bf650 100644 +--- a/arch/x86/entry/entry_64.S ++++ b/arch/x86/entry/entry_64.S +@@ -1053,7 +1053,11 @@ idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vec + /* + * Save all registers in pt_regs, and switch gs if needed. + * Use slow, but surefire "are we in kernel?" check. +- * Return: ebx=0: need swapgs on exit, ebx=1: otherwise ++ * ++ * Return: ebx=0: needs swapgs but not SWITCH_USER_CR3 in paranoid_exit ++ * ebx=1: needs neither swapgs nor SWITCH_USER_CR3 in paranoid_exit ++ * ebx=2: needs both swapgs and SWITCH_USER_CR3 in paranoid_exit ++ * ebx=3: needs SWITCH_USER_CR3 but not swapgs in paranoid_exit + */ + ENTRY(paranoid_entry) + cld +@@ -1065,9 +1069,26 @@ ENTRY(paranoid_entry) + testl %edx, %edx + js 1f /* negative -> in kernel */ + SWAPGS +- SWITCH_KERNEL_CR3 + xorl %ebx, %ebx +-1: ret ++1: ++#ifdef CONFIG_KAISER ++ /* ++ * We might have come in between a swapgs and a SWITCH_KERNEL_CR3 ++ * on entry, or between a SWITCH_USER_CR3 and a swapgs on exit. ++ * Do a conditional SWITCH_KERNEL_CR3: this could safely be done ++ * unconditionally, but we need to find out whether the reverse ++ * should be done on return (conveyed to paranoid_exit in %ebx). ++ */ ++ movq %cr3, %rax ++ testl $KAISER_SHADOW_PGD_OFFSET, %eax ++ jz 2f ++ orl $2, %ebx ++ andq $(~(X86_CR3_PCID_ASID_MASK | KAISER_SHADOW_PGD_OFFSET)), %rax ++ orq x86_cr3_pcid_noflush, %rax ++ movq %rax, %cr3 ++2: ++#endif ++ ret + END(paranoid_entry) + + /* +@@ -1080,20 +1101,25 @@ END(paranoid_entry) + * be complicated. Fortunately, we there's no good reason + * to try to handle preemption here. + * +- * On entry, ebx is "no swapgs" flag (1: don't need swapgs, 0: need it) ++ * On entry: ebx=0: needs swapgs but not SWITCH_USER_CR3 ++ * ebx=1: needs neither swapgs nor SWITCH_USER_CR3 ++ * ebx=2: needs both swapgs and SWITCH_USER_CR3 ++ * ebx=3: needs SWITCH_USER_CR3 but not swapgs + */ + ENTRY(paranoid_exit) + DISABLE_INTERRUPTS(CLBR_NONE) + TRACE_IRQS_OFF_DEBUG +- testl %ebx, %ebx /* swapgs needed? */ ++ TRACE_IRQS_IRETQ_DEBUG ++#ifdef CONFIG_KAISER ++ testl $2, %ebx /* SWITCH_USER_CR3 needed? */ ++ jz paranoid_exit_no_switch ++ SWITCH_USER_CR3 ++paranoid_exit_no_switch: ++#endif ++ testl $1, %ebx /* swapgs needed? */ + jnz paranoid_exit_no_swapgs +- TRACE_IRQS_IRETQ +- SWITCH_USER_CR3_NO_STACK + SWAPGS_UNSAFE_STACK +- jmp paranoid_exit_restore + paranoid_exit_no_swapgs: +- TRACE_IRQS_IRETQ_DEBUG +-paranoid_exit_restore: + RESTORE_EXTRA_REGS + RESTORE_C_REGS + REMOVE_PT_GPREGS_FROM_STACK 8 +diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S +index 0eb5801..d76a976 100644 +--- a/arch/x86/entry/entry_64_compat.S ++++ b/arch/x86/entry/entry_64_compat.S +@@ -343,7 +343,7 @@ ENTRY(entry_INT80_compat) + + /* Go back to user mode. */ + TRACE_IRQS_ON +- SWITCH_USER_CR3_NO_STACK ++ SWITCH_USER_CR3 + SWAPGS + jmp restore_regs_and_iret + END(entry_INT80_compat) +diff --git a/arch/x86/include/asm/kaiser.h b/arch/x86/include/asm/kaiser.h +index 48d8d70..3dc5f4c 100644 +--- a/arch/x86/include/asm/kaiser.h ++++ b/arch/x86/include/asm/kaiser.h +@@ -63,20 +63,12 @@ _SWITCH_TO_KERNEL_CR3 %rax + movq PER_CPU_VAR(unsafe_stack_register_backup), %rax + .endm + +-.macro SWITCH_USER_CR3_NO_STACK +-movq %rax, PER_CPU_VAR(unsafe_stack_register_backup) +-_SWITCH_TO_USER_CR3 %rax %al +-movq PER_CPU_VAR(unsafe_stack_register_backup), %rax +-.endm +- + #else /* CONFIG_KAISER */ + + .macro SWITCH_KERNEL_CR3 reg + .endm + .macro SWITCH_USER_CR3 reg regb + .endm +-.macro SWITCH_USER_CR3_NO_STACK +-.endm + .macro SWITCH_KERNEL_CR3_NO_STACK + .endm + +-- +2.7.4 + |