From: Greg Kroah-Hartman Date: Mon, 22 Jan 2018 07:46:29 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.113~8 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=c6929d36c0eceeae09e669010dbf9c0dbab09b04;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: kprobes-x86-blacklist-indirect-thunk-functions-for-kprobes.patch kprobes-x86-disable-optimizing-on-the-function-jumps-to-indirect-thunk.patch mm-page_vma_mapped-drop-faulty-pointer-arithmetics-in-check_pte.patch net-mvpp2-do-not-disable-gmac-padding.patch retpoline-introduce-start-end-markers-of-indirect-thunk.patch x86-mce-make-machine-check-speculation-protected.patch x86-mm-rework-wbinvd-hlt-operation-in-stop_this_cpu.patch x86-pti-document-fix-wrong-index.patch x86-retpoline-optimize-inline-assembler-for-vmexit_fill_rsb.patch --- diff --git a/queue-4.14/kprobes-x86-blacklist-indirect-thunk-functions-for-kprobes.patch b/queue-4.14/kprobes-x86-blacklist-indirect-thunk-functions-for-kprobes.patch new file mode 100644 index 00000000000..a552f71bc29 --- /dev/null +++ b/queue-4.14/kprobes-x86-blacklist-indirect-thunk-functions-for-kprobes.patch @@ -0,0 +1,40 @@ +From c1804a236894ecc942da7dc6c5abe209e56cba93 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Fri, 19 Jan 2018 01:14:51 +0900 +Subject: kprobes/x86: Blacklist indirect thunk functions for kprobes + +From: Masami Hiramatsu + +commit c1804a236894ecc942da7dc6c5abe209e56cba93 upstream. + +Mark __x86_indirect_thunk_* functions as blacklist for kprobes +because those functions can be called from anywhere in the kernel +including blacklist functions of kprobes. + +Signed-off-by: Masami Hiramatsu +Signed-off-by: Thomas Gleixner +Acked-by: David Woodhouse +Cc: Andi Kleen +Cc: Peter Zijlstra +Cc: Ananth N Mavinakayanahalli +Cc: Arjan van de Ven +Cc: Greg Kroah-Hartman +Link: https://lkml.kernel.org/r/151629209111.10241.5444852823378068683.stgit@devbox +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/lib/retpoline.S | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/x86/lib/retpoline.S ++++ b/arch/x86/lib/retpoline.S +@@ -25,7 +25,8 @@ ENDPROC(__x86_indirect_thunk_\reg) + * than one per register with the correct names. So we do it + * the simple and nasty way... + */ +-#define EXPORT_THUNK(reg) EXPORT_SYMBOL(__x86_indirect_thunk_ ## reg) ++#define __EXPORT_THUNK(sym) _ASM_NOKPROBE(sym); EXPORT_SYMBOL(sym) ++#define EXPORT_THUNK(reg) __EXPORT_THUNK(__x86_indirect_thunk_ ## reg) + #define GENERATE_THUNK(reg) THUNK reg ; EXPORT_THUNK(reg) + + GENERATE_THUNK(_ASM_AX) diff --git a/queue-4.14/kprobes-x86-disable-optimizing-on-the-function-jumps-to-indirect-thunk.patch b/queue-4.14/kprobes-x86-disable-optimizing-on-the-function-jumps-to-indirect-thunk.patch new file mode 100644 index 00000000000..68089fc1c8e --- /dev/null +++ b/queue-4.14/kprobes-x86-disable-optimizing-on-the-function-jumps-to-indirect-thunk.patch @@ -0,0 +1,80 @@ +From c86a32c09f8ced67971a2310e3b0dda4d1749007 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Fri, 19 Jan 2018 01:15:20 +0900 +Subject: kprobes/x86: Disable optimizing on the function jumps to indirect thunk + +From: Masami Hiramatsu + +commit c86a32c09f8ced67971a2310e3b0dda4d1749007 upstream. + +Since indirect jump instructions will be replaced by jump +to __x86_indirect_thunk_*, those jmp instruction must be +treated as an indirect jump. Since optprobe prohibits to +optimize probes in the function which uses an indirect jump, +it also needs to find out the function which jump to +__x86_indirect_thunk_* and disable optimization. + +Add a check that the jump target address is between the +__indirect_thunk_start/end when optimizing kprobe. + +Signed-off-by: Masami Hiramatsu +Signed-off-by: Thomas Gleixner +Acked-by: David Woodhouse +Cc: Andi Kleen +Cc: Peter Zijlstra +Cc: Ananth N Mavinakayanahalli +Cc: Arjan van de Ven +Cc: Greg Kroah-Hartman +Link: https://lkml.kernel.org/r/151629212062.10241.6991266100233002273.stgit@devbox +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/kprobes/opt.c | 23 ++++++++++++++++++++++- + 1 file changed, 22 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/kprobes/opt.c ++++ b/arch/x86/kernel/kprobes/opt.c +@@ -40,6 +40,7 @@ + #include + #include + #include ++#include + + #include "common.h" + +@@ -205,7 +206,7 @@ static int copy_optimized_instructions(u + } + + /* Check whether insn is indirect jump */ +-static int insn_is_indirect_jump(struct insn *insn) ++static int __insn_is_indirect_jump(struct insn *insn) + { + return ((insn->opcode.bytes[0] == 0xff && + (X86_MODRM_REG(insn->modrm.value) & 6) == 4) || /* Jump */ +@@ -239,6 +240,26 @@ static int insn_jump_into_range(struct i + return (start <= target && target <= start + len); + } + ++static int insn_is_indirect_jump(struct insn *insn) ++{ ++ int ret = __insn_is_indirect_jump(insn); ++ ++#ifdef CONFIG_RETPOLINE ++ /* ++ * Jump to x86_indirect_thunk_* is treated as an indirect jump. ++ * Note that even with CONFIG_RETPOLINE=y, the kernel compiled with ++ * older gcc may use indirect jump. So we add this check instead of ++ * replace indirect-jump check. ++ */ ++ if (!ret) ++ ret = insn_jump_into_range(insn, ++ (unsigned long)__indirect_thunk_start, ++ (unsigned long)__indirect_thunk_end - ++ (unsigned long)__indirect_thunk_start); ++#endif ++ return ret; ++} ++ + /* Decode whole function to ensure any instructions don't jump into target */ + static int can_optimize(unsigned long paddr) + { diff --git a/queue-4.14/mm-page_vma_mapped-drop-faulty-pointer-arithmetics-in-check_pte.patch b/queue-4.14/mm-page_vma_mapped-drop-faulty-pointer-arithmetics-in-check_pte.patch new file mode 100644 index 00000000000..3fb1ebac884 --- /dev/null +++ b/queue-4.14/mm-page_vma_mapped-drop-faulty-pointer-arithmetics-in-check_pte.patch @@ -0,0 +1,180 @@ +From 0d665e7b109d512b7cae3ccef6e8654714887844 Mon Sep 17 00:00:00 2001 +From: "Kirill A. Shutemov" +Date: Fri, 19 Jan 2018 15:49:24 +0300 +Subject: mm, page_vma_mapped: Drop faulty pointer arithmetics in check_pte() + +From: Kirill A. Shutemov + +commit 0d665e7b109d512b7cae3ccef6e8654714887844 upstream. + +Tetsuo reported random crashes under memory pressure on 32-bit x86 +system and tracked down to change that introduced +page_vma_mapped_walk(). + +The root cause of the issue is the faulty pointer math in check_pte(). +As ->pte may point to an arbitrary page we have to check that they are +belong to the section before doing math. Otherwise it may lead to weird +results. + +It wasn't noticed until now as mem_map[] is virtually contiguous on +flatmem or vmemmap sparsemem. Pointer arithmetic just works against all +'struct page' pointers. But with classic sparsemem, it doesn't because +each section memap is allocated separately and so consecutive pfns +crossing two sections might have struct pages at completely unrelated +addresses. + +Let's restructure code a bit and replace pointer arithmetic with +operations on pfns. + +Signed-off-by: Kirill A. Shutemov +Reported-and-tested-by: Tetsuo Handa +Acked-by: Michal Hocko +Fixes: ace71a19cec5 ("mm: introduce page_vma_mapped_walk()") +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/swapops.h | 21 ++++++++++++++++ + mm/page_vma_mapped.c | 63 ++++++++++++++++++++++++++++-------------------- + 2 files changed, 59 insertions(+), 25 deletions(-) + +--- a/include/linux/swapops.h ++++ b/include/linux/swapops.h +@@ -124,6 +124,11 @@ static inline bool is_write_device_priva + return unlikely(swp_type(entry) == SWP_DEVICE_WRITE); + } + ++static inline unsigned long device_private_entry_to_pfn(swp_entry_t entry) ++{ ++ return swp_offset(entry); ++} ++ + static inline struct page *device_private_entry_to_page(swp_entry_t entry) + { + return pfn_to_page(swp_offset(entry)); +@@ -154,6 +159,11 @@ static inline bool is_write_device_priva + return false; + } + ++static inline unsigned long device_private_entry_to_pfn(swp_entry_t entry) ++{ ++ return 0; ++} ++ + static inline struct page *device_private_entry_to_page(swp_entry_t entry) + { + return NULL; +@@ -189,6 +199,11 @@ static inline int is_write_migration_ent + return unlikely(swp_type(entry) == SWP_MIGRATION_WRITE); + } + ++static inline unsigned long migration_entry_to_pfn(swp_entry_t entry) ++{ ++ return swp_offset(entry); ++} ++ + static inline struct page *migration_entry_to_page(swp_entry_t entry) + { + struct page *p = pfn_to_page(swp_offset(entry)); +@@ -218,6 +233,12 @@ static inline int is_migration_entry(swp + { + return 0; + } ++ ++static inline unsigned long migration_entry_to_pfn(swp_entry_t entry) ++{ ++ return 0; ++} ++ + static inline struct page *migration_entry_to_page(swp_entry_t entry) + { + return NULL; +--- a/mm/page_vma_mapped.c ++++ b/mm/page_vma_mapped.c +@@ -30,10 +30,29 @@ static bool map_pte(struct page_vma_mapp + return true; + } + ++/** ++ * check_pte - check if @pvmw->page is mapped at the @pvmw->pte ++ * ++ * page_vma_mapped_walk() found a place where @pvmw->page is *potentially* ++ * mapped. check_pte() has to validate this. ++ * ++ * @pvmw->pte may point to empty PTE, swap PTE or PTE pointing to arbitrary ++ * page. ++ * ++ * If PVMW_MIGRATION flag is set, returns true if @pvmw->pte contains migration ++ * entry that points to @pvmw->page or any subpage in case of THP. ++ * ++ * If PVMW_MIGRATION flag is not set, returns true if @pvmw->pte points to ++ * @pvmw->page or any subpage in case of THP. ++ * ++ * Otherwise, return false. ++ * ++ */ + static bool check_pte(struct page_vma_mapped_walk *pvmw) + { ++ unsigned long pfn; ++ + if (pvmw->flags & PVMW_MIGRATION) { +-#ifdef CONFIG_MIGRATION + swp_entry_t entry; + if (!is_swap_pte(*pvmw->pte)) + return false; +@@ -41,37 +60,31 @@ static bool check_pte(struct page_vma_ma + + if (!is_migration_entry(entry)) + return false; +- if (migration_entry_to_page(entry) - pvmw->page >= +- hpage_nr_pages(pvmw->page)) { +- return false; +- } +- if (migration_entry_to_page(entry) < pvmw->page) +- return false; +-#else +- WARN_ON_ONCE(1); +-#endif +- } else { +- if (is_swap_pte(*pvmw->pte)) { +- swp_entry_t entry; + +- entry = pte_to_swp_entry(*pvmw->pte); +- if (is_device_private_entry(entry) && +- device_private_entry_to_page(entry) == pvmw->page) +- return true; +- } ++ pfn = migration_entry_to_pfn(entry); ++ } else if (is_swap_pte(*pvmw->pte)) { ++ swp_entry_t entry; + +- if (!pte_present(*pvmw->pte)) ++ /* Handle un-addressable ZONE_DEVICE memory */ ++ entry = pte_to_swp_entry(*pvmw->pte); ++ if (!is_device_private_entry(entry)) + return false; + +- /* THP can be referenced by any subpage */ +- if (pte_page(*pvmw->pte) - pvmw->page >= +- hpage_nr_pages(pvmw->page)) { +- return false; +- } +- if (pte_page(*pvmw->pte) < pvmw->page) ++ pfn = device_private_entry_to_pfn(entry); ++ } else { ++ if (!pte_present(*pvmw->pte)) + return false; ++ ++ pfn = pte_pfn(*pvmw->pte); + } + ++ if (pfn < page_to_pfn(pvmw->page)) ++ return false; ++ ++ /* THP can be referenced by any subpage */ ++ if (pfn - page_to_pfn(pvmw->page) >= hpage_nr_pages(pvmw->page)) ++ return false; ++ + return true; + } + diff --git a/queue-4.14/net-mvpp2-do-not-disable-gmac-padding.patch b/queue-4.14/net-mvpp2-do-not-disable-gmac-padding.patch new file mode 100644 index 00000000000..b031d4f407c --- /dev/null +++ b/queue-4.14/net-mvpp2-do-not-disable-gmac-padding.patch @@ -0,0 +1,49 @@ +From e749aca84b10f3987b2ee1f76e0c7d8aacc5653c Mon Sep 17 00:00:00 2001 +From: Yan Markman +Date: Tue, 28 Nov 2017 14:19:50 +0100 +Subject: net: mvpp2: do not disable GMAC padding + +From: Yan Markman + +commit e749aca84b10f3987b2ee1f76e0c7d8aacc5653c upstream. + +Short fragmented packets may never be sent by the hardware when padding +is disabled. This patch stop modifying the GMAC padding bits, to leave +them to their reset value (disabled). + +Fixes: 3919357fb0bb ("net: mvpp2: initialize the GMAC when using a port") +Signed-off-by: Yan Markman +[Antoine: commit message] +Signed-off-by: Antoine Tenart +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/marvell/mvpp2.c | 9 --------- + 1 file changed, 9 deletions(-) + +--- a/drivers/net/ethernet/marvell/mvpp2.c ++++ b/drivers/net/ethernet/marvell/mvpp2.c +@@ -4552,11 +4552,6 @@ static void mvpp2_port_mii_gmac_configur + MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE; + val &= ~MVPP22_CTRL4_EXT_PIN_GMII_SEL; + writel(val, port->base + MVPP22_GMAC_CTRL_4_REG); +- +- val = readl(port->base + MVPP2_GMAC_CTRL_2_REG); +- val |= MVPP2_GMAC_DISABLE_PADDING; +- val &= ~MVPP2_GMAC_FLOW_CTRL_MASK; +- writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); + } else if (phy_interface_mode_is_rgmii(port->phy_interface)) { + val = readl(port->base + MVPP22_GMAC_CTRL_4_REG); + val |= MVPP22_CTRL4_EXT_PIN_GMII_SEL | +@@ -4564,10 +4559,6 @@ static void mvpp2_port_mii_gmac_configur + MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE; + val &= ~MVPP22_CTRL4_DP_CLK_SEL; + writel(val, port->base + MVPP22_GMAC_CTRL_4_REG); +- +- val = readl(port->base + MVPP2_GMAC_CTRL_2_REG); +- val &= ~MVPP2_GMAC_DISABLE_PADDING; +- writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); + } + + /* The port is connected to a copper PHY */ diff --git a/queue-4.14/retpoline-introduce-start-end-markers-of-indirect-thunk.patch b/queue-4.14/retpoline-introduce-start-end-markers-of-indirect-thunk.patch new file mode 100644 index 00000000000..098515940ec --- /dev/null +++ b/queue-4.14/retpoline-introduce-start-end-markers-of-indirect-thunk.patch @@ -0,0 +1,70 @@ +From 736e80a4213e9bbce40a7c050337047128b472ac Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Fri, 19 Jan 2018 01:14:21 +0900 +Subject: retpoline: Introduce start/end markers of indirect thunk + +From: Masami Hiramatsu + +commit 736e80a4213e9bbce40a7c050337047128b472ac upstream. + +Introduce start/end markers of __x86_indirect_thunk_* functions. +To make it easy, consolidate .text.__x86.indirect_thunk.* sections +to one .text.__x86.indirect_thunk section and put it in the +end of kernel text section and adds __indirect_thunk_start/end +so that other subsystem (e.g. kprobes) can identify it. + +Signed-off-by: Masami Hiramatsu +Signed-off-by: Thomas Gleixner +Acked-by: David Woodhouse +Cc: Andi Kleen +Cc: Peter Zijlstra +Cc: Ananth N Mavinakayanahalli +Cc: Arjan van de Ven +Cc: Greg Kroah-Hartman +Link: https://lkml.kernel.org/r/151629206178.10241.6828804696410044771.stgit@devbox +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/nospec-branch.h | 3 +++ + arch/x86/kernel/vmlinux.lds.S | 6 ++++++ + arch/x86/lib/retpoline.S | 2 +- + 3 files changed, 10 insertions(+), 1 deletion(-) + +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -194,6 +194,9 @@ enum spectre_v2_mitigation { + SPECTRE_V2_IBRS, + }; + ++extern char __indirect_thunk_start[]; ++extern char __indirect_thunk_end[]; ++ + /* + * On VMEXIT we must ensure that no RSB predictions learned in the guest + * can be followed in the host, by overwriting the RSB completely. Both +--- a/arch/x86/kernel/vmlinux.lds.S ++++ b/arch/x86/kernel/vmlinux.lds.S +@@ -124,6 +124,12 @@ SECTIONS + ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big"); + #endif + ++#ifdef CONFIG_RETPOLINE ++ __indirect_thunk_start = .; ++ *(.text.__x86.indirect_thunk) ++ __indirect_thunk_end = .; ++#endif ++ + /* End of text section */ + _etext = .; + } :text = 0x9090 +--- a/arch/x86/lib/retpoline.S ++++ b/arch/x86/lib/retpoline.S +@@ -9,7 +9,7 @@ + #include + + .macro THUNK reg +- .section .text.__x86.indirect_thunk.\reg ++ .section .text.__x86.indirect_thunk + + ENTRY(__x86_indirect_thunk_\reg) + CFI_STARTPROC diff --git a/queue-4.14/series b/queue-4.14/series index 6044f492843..0bc2b5b8cf1 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -78,3 +78,12 @@ alpha-pci-fix-noname-irq-level-detection.patch mips-cm-drop-warn_on-vp-0.patch kvm-arm-arm64-check-pagesize-when-allocating-a-hugepage-at-stage-2.patch arm64-kvm-fix-smccc-handling-of-unimplemented-smc-hvc-calls.patch +x86-mce-make-machine-check-speculation-protected.patch +retpoline-introduce-start-end-markers-of-indirect-thunk.patch +kprobes-x86-blacklist-indirect-thunk-functions-for-kprobes.patch +kprobes-x86-disable-optimizing-on-the-function-jumps-to-indirect-thunk.patch +x86-pti-document-fix-wrong-index.patch +x86-retpoline-optimize-inline-assembler-for-vmexit_fill_rsb.patch +x86-mm-rework-wbinvd-hlt-operation-in-stop_this_cpu.patch +mm-page_vma_mapped-drop-faulty-pointer-arithmetics-in-check_pte.patch +net-mvpp2-do-not-disable-gmac-padding.patch diff --git a/queue-4.14/x86-mce-make-machine-check-speculation-protected.patch b/queue-4.14/x86-mce-make-machine-check-speculation-protected.patch new file mode 100644 index 00000000000..e140e6a7b9a --- /dev/null +++ b/queue-4.14/x86-mce-make-machine-check-speculation-protected.patch @@ -0,0 +1,63 @@ +From 6f41c34d69eb005e7848716bbcafc979b35037d5 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 18 Jan 2018 16:28:26 +0100 +Subject: x86/mce: Make machine check speculation protected + +From: Thomas Gleixner + +commit 6f41c34d69eb005e7848716bbcafc979b35037d5 upstream. + +The machine check idtentry uses an indirect branch directly from the low +level code. This evades the speculation protection. + +Replace it by a direct call into C code and issue the indirect call there +so the compiler can apply the proper speculation protection. + +Signed-off-by: Thomas Gleixner +Reviewed-by:Borislav Petkov +Reviewed-by: David Woodhouse +Niced-by: Peter Zijlstra +Link: https://lkml.kernel.org/r/alpine.DEB.2.20.1801181626290.1847@nanos +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/entry/entry_64.S | 2 +- + arch/x86/include/asm/traps.h | 1 + + arch/x86/kernel/cpu/mcheck/mce.c | 5 +++++ + 3 files changed, 7 insertions(+), 1 deletion(-) + +--- a/arch/x86/entry/entry_64.S ++++ b/arch/x86/entry/entry_64.S +@@ -1258,7 +1258,7 @@ idtentry async_page_fault do_async_page_ + #endif + + #ifdef CONFIG_X86_MCE +-idtentry machine_check has_error_code=0 paranoid=1 do_sym=*machine_check_vector(%rip) ++idtentry machine_check do_mce has_error_code=0 paranoid=1 + #endif + + /* +--- a/arch/x86/include/asm/traps.h ++++ b/arch/x86/include/asm/traps.h +@@ -88,6 +88,7 @@ dotraplinkage void do_simd_coprocessor_e + #ifdef CONFIG_X86_32 + dotraplinkage void do_iret_error(struct pt_regs *, long); + #endif ++dotraplinkage void do_mce(struct pt_regs *, long); + + static inline int get_si_code(unsigned long condition) + { +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -1788,6 +1788,11 @@ static void unexpected_machine_check(str + void (*machine_check_vector)(struct pt_regs *, long error_code) = + unexpected_machine_check; + ++dotraplinkage void do_mce(struct pt_regs *regs, long error_code) ++{ ++ machine_check_vector(regs, error_code); ++} ++ + /* + * Called for each booted CPU to set up machine checks. + * Must be called with preempt off: diff --git a/queue-4.14/x86-mm-rework-wbinvd-hlt-operation-in-stop_this_cpu.patch b/queue-4.14/x86-mm-rework-wbinvd-hlt-operation-in-stop_this_cpu.patch new file mode 100644 index 00000000000..de890ace526 --- /dev/null +++ b/queue-4.14/x86-mm-rework-wbinvd-hlt-operation-in-stop_this_cpu.patch @@ -0,0 +1,88 @@ +From f23d74f6c66c3697e032550eeef3f640391a3a7d Mon Sep 17 00:00:00 2001 +From: Tom Lendacky +Date: Wed, 17 Jan 2018 17:41:41 -0600 +Subject: x86/mm: Rework wbinvd, hlt operation in stop_this_cpu() + +From: Tom Lendacky + +commit f23d74f6c66c3697e032550eeef3f640391a3a7d upstream. + +Some issues have been reported with the for loop in stop_this_cpu() that +issues the 'wbinvd; hlt' sequence. Reverting this sequence to halt() +has been shown to resolve the issue. + +However, the wbinvd is needed when running with SME. The reason for the +wbinvd is to prevent cache flush races between encrypted and non-encrypted +entries that have the same physical address. This can occur when +kexec'ing from memory encryption active to inactive or vice-versa. The +important thing is to not have outside of kernel text memory references +(such as stack usage), so the usage of the native_*() functions is needed +since these expand as inline asm sequences. So instead of reverting the +change, rework the sequence. + +Move the wbinvd instruction outside of the for loop as native_wbinvd() +and make its execution conditional on X86_FEATURE_SME. In the for loop, +change the asm 'wbinvd; hlt' sequence back to a halt sequence but use +the native_halt() call. + +Fixes: bba4ed011a52 ("x86/mm, kexec: Allow kexec to be used with SME") +Reported-by: Dave Young +Signed-off-by: Tom Lendacky +Signed-off-by: Thomas Gleixner +Tested-by: Dave Young +Cc: Juergen Gross +Cc: Tony Luck +Cc: Yu Chen +Cc: Baoquan He +Cc: Linus Torvalds +Cc: kexec@lists.infradead.org +Cc: ebiederm@redhat.com +Cc: Borislav Petkov +Cc: Rui Zhang +Cc: Arjan van de Ven +Cc: Boris Ostrovsky +Cc: Dan Williams +Link: https://lkml.kernel.org/r/20180117234141.21184.44067.stgit@tlendack-t1.amdoffice.net +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/process.c | 25 +++++++++++++++---------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +--- a/arch/x86/kernel/process.c ++++ b/arch/x86/kernel/process.c +@@ -380,19 +380,24 @@ void stop_this_cpu(void *dummy) + disable_local_APIC(); + mcheck_cpu_clear(this_cpu_ptr(&cpu_info)); + ++ /* ++ * Use wbinvd on processors that support SME. This provides support ++ * for performing a successful kexec when going from SME inactive ++ * to SME active (or vice-versa). The cache must be cleared so that ++ * if there are entries with the same physical address, both with and ++ * without the encryption bit, they don't race each other when flushed ++ * and potentially end up with the wrong entry being committed to ++ * memory. ++ */ ++ if (boot_cpu_has(X86_FEATURE_SME)) ++ native_wbinvd(); + for (;;) { + /* +- * Use wbinvd followed by hlt to stop the processor. This +- * provides support for kexec on a processor that supports +- * SME. With kexec, going from SME inactive to SME active +- * requires clearing cache entries so that addresses without +- * the encryption bit set don't corrupt the same physical +- * address that has the encryption bit set when caches are +- * flushed. To achieve this a wbinvd is performed followed by +- * a hlt. Even if the processor is not in the kexec/SME +- * scenario this only adds a wbinvd to a halting processor. ++ * Use native_halt() so that memory contents don't change ++ * (stack usage and variables) after possibly issuing the ++ * native_wbinvd() above. + */ +- asm volatile("wbinvd; hlt" : : : "memory"); ++ native_halt(); + } + } + diff --git a/queue-4.14/x86-pti-document-fix-wrong-index.patch b/queue-4.14/x86-pti-document-fix-wrong-index.patch new file mode 100644 index 00000000000..cb7b93a790c --- /dev/null +++ b/queue-4.14/x86-pti-document-fix-wrong-index.patch @@ -0,0 +1,32 @@ +From 98f0fceec7f84d80bc053e49e596088573086421 Mon Sep 17 00:00:00 2001 +From: "zhenwei.pi" +Date: Thu, 18 Jan 2018 09:04:52 +0800 +Subject: x86/pti: Document fix wrong index + +From: zhenwei.pi + +commit 98f0fceec7f84d80bc053e49e596088573086421 upstream. + +In section <2. Runtime Cost>, fix wrong index. + +Signed-off-by: zhenwei.pi +Signed-off-by: Thomas Gleixner +Cc: dave.hansen@linux.intel.com +Link: https://lkml.kernel.org/r/1516237492-27739-1-git-send-email-zhenwei.pi@youruncloud.com +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/x86/pti.txt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/Documentation/x86/pti.txt ++++ b/Documentation/x86/pti.txt +@@ -78,7 +78,7 @@ this protection comes at a cost: + non-PTI SYSCALL entry code, so requires mapping fewer + things into the userspace page tables. The downside is + that stacks must be switched at entry time. +- d. Global pages are disabled for all kernel structures not ++ c. Global pages are disabled for all kernel structures not + mapped into both kernel and userspace page tables. This + feature of the MMU allows different processes to share TLB + entries mapping the kernel. Losing the feature means more diff --git a/queue-4.14/x86-retpoline-optimize-inline-assembler-for-vmexit_fill_rsb.patch b/queue-4.14/x86-retpoline-optimize-inline-assembler-for-vmexit_fill_rsb.patch new file mode 100644 index 00000000000..963e73a80a7 --- /dev/null +++ b/queue-4.14/x86-retpoline-optimize-inline-assembler-for-vmexit_fill_rsb.patch @@ -0,0 +1,58 @@ +From 3f7d875566d8e79c5e0b2c9a413e91b2c29e0854 Mon Sep 17 00:00:00 2001 +From: Andi Kleen +Date: Wed, 17 Jan 2018 14:53:28 -0800 +Subject: x86/retpoline: Optimize inline assembler for vmexit_fill_RSB + +From: Andi Kleen + +commit 3f7d875566d8e79c5e0b2c9a413e91b2c29e0854 upstream. + +The generated assembler for the C fill RSB inline asm operations has +several issues: + +- The C code sets up the loop register, which is then immediately + overwritten in __FILL_RETURN_BUFFER with the same value again. + +- The C code also passes in the iteration count in another register, which + is not used at all. + +Remove these two unnecessary operations. Just rely on the single constant +passed to the macro for the iterations. + +Signed-off-by: Andi Kleen +Signed-off-by: Thomas Gleixner +Acked-by: David Woodhouse +Cc: dave.hansen@intel.com +Cc: gregkh@linuxfoundation.org +Cc: torvalds@linux-foundation.org +Cc: arjan@linux.intel.com +Link: https://lkml.kernel.org/r/20180117225328.15414-1-andi@firstfloor.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/nospec-branch.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/arch/x86/include/asm/nospec-branch.h ++++ b/arch/x86/include/asm/nospec-branch.h +@@ -206,16 +206,17 @@ extern char __indirect_thunk_end[]; + static inline void vmexit_fill_RSB(void) + { + #ifdef CONFIG_RETPOLINE +- unsigned long loops = RSB_CLEAR_LOOPS / 2; ++ unsigned long loops; + + asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE + ALTERNATIVE("jmp 910f", + __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)), + X86_FEATURE_RETPOLINE) + "910:" +- : "=&r" (loops), ASM_CALL_CONSTRAINT +- : "r" (loops) : "memory" ); ++ : "=r" (loops), ASM_CALL_CONSTRAINT ++ : : "memory" ); + #endif + } ++ + #endif /* __ASSEMBLY__ */ + #endif /* __NOSPEC_BRANCH_H__ */