]>
Commit | Line | Data |
---|---|---|
45d80ddf SL |
1 | From 331d7fa8c50f1a30d0a1eb925aa94396e036a0fd Mon Sep 17 00:00:00 2001 |
2 | From: Diana Craciun <diana.craciun@nxp.com> | |
3 | Date: Thu, 11 Apr 2019 21:46:18 +1000 | |
4 | Subject: powerpc/fsl: Add infrastructure to fixup branch predictor flush | |
5 | ||
6 | commit 76a5eaa38b15dda92cd6964248c39b5a6f3a4e9d upstream. | |
7 | ||
8 | In order to protect against speculation attacks (Spectre | |
9 | variant 2) on NXP PowerPC platforms, the branch predictor | |
10 | should be flushed when the privillege level is changed. | |
11 | This patch is adding the infrastructure to fixup at runtime | |
12 | the code sections that are performing the branch predictor flush | |
13 | depending on a boot arg parameter which is added later in a | |
14 | separate patch. | |
15 | ||
16 | Signed-off-by: Diana Craciun <diana.craciun@nxp.com> | |
17 | Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> | |
18 | Signed-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 | ||
26 | diff --git a/arch/powerpc/include/asm/feature-fixups.h b/arch/powerpc/include/asm/feature-fixups.h | |
27 | index 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 | ||
56 | diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h | |
57 | index 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 */ | |
69 | diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S | |
70 | index 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 | |
88 | diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c | |
89 | index 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 | -- | |
123 | 2.19.1 | |
124 |