]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.9.169/powerpc-fsl-add-infrastructure-to-fixup-branch-predi.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.9.169 / powerpc-fsl-add-infrastructure-to-fixup-branch-predi.patch
CommitLineData
45d80ddf
SL
1From 331d7fa8c50f1a30d0a1eb925aa94396e036a0fd Mon Sep 17 00:00:00 2001
2From: Diana Craciun <diana.craciun@nxp.com>
3Date: Thu, 11 Apr 2019 21:46:18 +1000
4Subject: powerpc/fsl: Add infrastructure to fixup branch predictor flush
5
6commit 76a5eaa38b15dda92cd6964248c39b5a6f3a4e9d upstream.
7
8In order to protect against speculation attacks (Spectre
9variant 2) on NXP PowerPC platforms, the branch predictor
10should be flushed when the privillege level is changed.
11This patch is adding the infrastructure to fixup at runtime
12the code sections that are performing the branch predictor flush
13depending on a boot arg parameter which is added later in a
14separate patch.
15
16Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
17Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
18Signed-off-by: Sasha Levin <sashal@kernel.org>
19---
20 arch/powerpc/include/asm/feature-fixups.h | 12 ++++++++++++
21 arch/powerpc/include/asm/setup.h | 2 ++
22 arch/powerpc/kernel/vmlinux.lds.S | 8 ++++++++
23 arch/powerpc/lib/feature-fixups.c | 23 +++++++++++++++++++++++
24 4 files changed, 45 insertions(+)
25
26diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h
27index afd3efd38938..175128e19025 100644
28--- a/arch/powerpc/include/asm/feature-fixups.h
29+++ b/arch/powerpc/include/asm/feature-fixups.h
30@@ -221,6 +221,17 @@ void setup_feature_keys(void);
31 FTR_ENTRY_OFFSET 953b-954b; \
32 .popsection;
33
34+#define START_BTB_FLUSH_SECTION \
35+955: \
36+
37+#define END_BTB_FLUSH_SECTION \
38+956: \
39+ .pushsection __btb_flush_fixup,"a"; \
40+ .align 2; \
41+957: \
42+ FTR_ENTRY_OFFSET 955b-957b; \
43+ FTR_ENTRY_OFFSET 956b-957b; \
44+ .popsection;
45
46 #ifndef __ASSEMBLY__
47
48@@ -229,6 +240,7 @@ extern long __start___stf_entry_barrier_fixup, __stop___stf_entry_barrier_fixup;
49 extern long __start___stf_exit_barrier_fixup, __stop___stf_exit_barrier_fixup;
50 extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
51 extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
52+extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;
53
54 #endif
55
56diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
57index d3e9da62d029..23ee67e279ae 100644
58--- a/arch/powerpc/include/asm/setup.h
59+++ b/arch/powerpc/include/asm/setup.h
60@@ -65,6 +65,8 @@ void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
61 static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { };
62 #endif
63
64+void do_btb_flush_fixups(void);
65+
66 #endif /* !__ASSEMBLY__ */
67
68 #endif /* _ASM_POWERPC_SETUP_H */
69diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
70index 5c6cf58943b9..50d365060855 100644
71--- a/arch/powerpc/kernel/vmlinux.lds.S
72+++ b/arch/powerpc/kernel/vmlinux.lds.S
73@@ -164,6 +164,14 @@ SECTIONS
74 }
75 #endif /* CONFIG_PPC_BARRIER_NOSPEC */
76
77+#ifdef CONFIG_PPC_FSL_BOOK3E
78+ . = ALIGN(8);
79+ __spec_btb_flush_fixup : AT(ADDR(__spec_btb_flush_fixup) - LOAD_OFFSET) {
80+ __start__btb_flush_fixup = .;
81+ *(__btb_flush_fixup)
82+ __stop__btb_flush_fixup = .;
83+ }
84+#endif
85 EXCEPTION_TABLE(0)
86
87 NOTES :kernel :notes
88diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
89index b3e362437ec4..e6ed0ec94bc8 100644
90--- a/arch/powerpc/lib/feature-fixups.c
91+++ b/arch/powerpc/lib/feature-fixups.c
92@@ -347,6 +347,29 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_
93
94 printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
95 }
96+
97+static void patch_btb_flush_section(long *curr)
98+{
99+ unsigned int *start, *end;
100+
101+ start = (void *)curr + *curr;
102+ end = (void *)curr + *(curr + 1);
103+ for (; start < end; start++) {
104+ pr_devel("patching dest %lx\n", (unsigned long)start);
105+ patch_instruction(start, PPC_INST_NOP);
106+ }
107+}
108+
109+void do_btb_flush_fixups(void)
110+{
111+ long *start, *end;
112+
113+ start = PTRRELOC(&__start__btb_flush_fixup);
114+ end = PTRRELOC(&__stop__btb_flush_fixup);
115+
116+ for (; start < end; start += 2)
117+ patch_btb_flush_section(start);
118+}
119 #endif /* CONFIG_PPC_FSL_BOOK3E */
120
121 void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
122--
1232.19.1
124