From: Sasha Levin Date: Thu, 25 Mar 2021 20:35:13 +0000 (-0400) Subject: Fixes for 4.9 X-Git-Tag: v5.11.11~70 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8858a948bb85d3ee95bf28da74fe123b2bc8c554;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.9 Signed-off-by: Sasha Levin --- diff --git a/queue-4.9/series b/queue-4.9/series index 699b3c7b7de..a06f8dd7b9e 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -14,3 +14,4 @@ u64_stats-lockdep-fix-u64_stats_init-vs-lockdep.patch nfs-we-don-t-support-removing-system.nfs4_acl.patch ia64-fix-ia64_syscall_get_set_arguments-for-break-ba.patch ia64-fix-ptrace-ptrace_syscall_info_exit-sign.patch +x86-tlb-flush-global-mappings-when-kaiser-is-disable.patch diff --git a/queue-4.9/x86-tlb-flush-global-mappings-when-kaiser-is-disable.patch b/queue-4.9/x86-tlb-flush-global-mappings-when-kaiser-is-disable.patch new file mode 100644 index 00000000000..d2adf9ff3c4 --- /dev/null +++ b/queue-4.9/x86-tlb-flush-global-mappings-when-kaiser-is-disable.patch @@ -0,0 +1,102 @@ +From 811d1a7a0b07d4ebf56b2f8a940fc1a08651cb26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Mar 2021 11:02:31 +0100 +Subject: x86/tlb: Flush global mappings when KAISER is disabled + +From: Borislav Petkov + +Jim Mattson reported that Debian 9 guests using a 4.9-stable kernel +are exploding during alternatives patching: + + kernel BUG at /build/linux-dqnRSc/linux-4.9.228/arch/x86/kernel/alternative.c:709! + invalid opcode: 0000 [#1] SMP + Modules linked in: + CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.9.0-13-amd64 #1 Debian 4.9.228-1 + Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 + Call Trace: + swap_entry_free + swap_entry_free + text_poke_bp + swap_entry_free + arch_jump_label_transform + set_debug_rodata + __jump_label_update + static_key_slow_inc + frontswap_register_ops + init_zswap + init_frontswap + do_one_initcall + set_debug_rodata + kernel_init_freeable + rest_init + kernel_init + ret_from_fork + +triggering the BUG_ON in text_poke() which verifies whether patched +instruction bytes have actually landed at the destination. + +Further debugging showed that the TLB flush before that check is +insufficient because there could be global mappings left in the TLB, +leading to a stale mapping getting used. + +I say "global mappings" because the hardware configuration is a new one: +machine is an AMD, which means, KAISER/PTI doesn't need to be enabled +there, which also means there's no user/kernel pagetables split and +therefore the TLB can have global mappings. + +And the configuration is new one for a second reason: because that AMD +machine supports PCID and INVPCID, which leads the CPU detection code to +set the synthetic X86_FEATURE_INVPCID_SINGLE flag. + +Now, __native_flush_tlb_single() does invalidate global mappings when +X86_FEATURE_INVPCID_SINGLE is *not* set and returns. + +When X86_FEATURE_INVPCID_SINGLE is set, however, it invalidates the +requested address from both PCIDs in the KAISER-enabled case. But if +KAISER is not enabled and the machine has global mappings in the TLB, +then those global mappings do not get invalidated, which would lead to +the above mismatch from using a stale TLB entry. + +So make sure to flush those global mappings in the KAISER disabled case. + +Co-debugged by Babu Moger . + +Reported-by: Jim Mattson +Signed-off-by: Borislav Petkov +Acked-by: Hugh Dickins +Reviewed-by: Paolo Bonzini +Tested-by: Babu Moger +Tested-by: Jim Mattson +Link: https://lkml.kernel.org/r/CALMp9eRDSW66%2BXvbHVF4ohL7XhThoPoT0BrB0TcS0cgk=dkcBg@mail.gmail.com +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/tlbflush.h | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h +index f5ca15622dc9..2bfa4deb8cae 100644 +--- a/arch/x86/include/asm/tlbflush.h ++++ b/arch/x86/include/asm/tlbflush.h +@@ -245,12 +245,15 @@ static inline void __native_flush_tlb_single(unsigned long addr) + * ASID. But, userspace flushes are probably much more + * important performance-wise. + * +- * Make sure to do only a single invpcid when KAISER is +- * disabled and we have only a single ASID. ++ * In the KAISER disabled case, do an INVLPG to make sure ++ * the mapping is flushed in case it is a global one. + */ +- if (kaiser_enabled) ++ if (kaiser_enabled) { + invpcid_flush_one(X86_CR3_PCID_ASID_USER, addr); +- invpcid_flush_one(X86_CR3_PCID_ASID_KERN, addr); ++ invpcid_flush_one(X86_CR3_PCID_ASID_KERN, addr); ++ } else { ++ asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); ++ } + } + + static inline void __flush_tlb_all(void) +-- +2.30.1 +