]>
Commit | Line | Data |
---|---|---|
45d80ddf SL |
1 | From 6b1e590ea5b5811ba5bc4ff745f5bd7f75b0aa70 Mon Sep 17 00:00:00 2001 |
2 | From: Diana Craciun <diana.craciun@nxp.com> | |
3 | Date: Thu, 11 Apr 2019 21:46:11 +1000 | |
4 | Subject: powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E | |
5 | ||
6 | commit ebcd1bfc33c7a90df941df68a6e5d4018c022fba upstream. | |
7 | ||
8 | Implement the barrier_nospec as a isync;sync instruction sequence. | |
9 | The implementation uses the infrastructure built for BOOK3S 64. | |
10 | ||
11 | Signed-off-by: Diana Craciun <diana.craciun@nxp.com> | |
12 | [mpe: Split out of larger patch] | |
13 | Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> | |
14 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
15 | --- | |
16 | arch/powerpc/Kconfig | 2 +- | |
17 | arch/powerpc/include/asm/barrier.h | 8 +++++++- | |
18 | arch/powerpc/lib/feature-fixups.c | 31 ++++++++++++++++++++++++++++++ | |
19 | 3 files changed, 39 insertions(+), 2 deletions(-) | |
20 | ||
21 | diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig | |
22 | index a238698178fc..fa8f2aa88189 100644 | |
23 | --- a/arch/powerpc/Kconfig | |
24 | +++ b/arch/powerpc/Kconfig | |
25 | @@ -167,7 +167,7 @@ config PPC | |
26 | config PPC_BARRIER_NOSPEC | |
27 | bool | |
28 | default y | |
29 | - depends on PPC_BOOK3S_64 | |
30 | + depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E | |
31 | ||
32 | config GENERIC_CSUM | |
33 | def_bool CPU_LITTLE_ENDIAN | |
34 | diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h | |
35 | index 465a64316897..80024c4f2093 100644 | |
36 | --- a/arch/powerpc/include/asm/barrier.h | |
37 | +++ b/arch/powerpc/include/asm/barrier.h | |
38 | @@ -77,12 +77,18 @@ do { \ | |
39 | ||
40 | #define smp_mb__before_spinlock() smp_mb() | |
41 | ||
42 | +#ifdef CONFIG_PPC_BOOK3S_64 | |
43 | +#define NOSPEC_BARRIER_SLOT nop | |
44 | +#elif defined(CONFIG_PPC_FSL_BOOK3E) | |
45 | +#define NOSPEC_BARRIER_SLOT nop; nop | |
46 | +#endif | |
47 | + | |
48 | #ifdef CONFIG_PPC_BARRIER_NOSPEC | |
49 | /* | |
50 | * Prevent execution of subsequent instructions until preceding branches have | |
51 | * been fully resolved and are no longer executing speculatively. | |
52 | */ | |
53 | -#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; nop | |
54 | +#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; NOSPEC_BARRIER_SLOT | |
55 | ||
56 | // This also acts as a compiler barrier due to the memory clobber. | |
57 | #define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory") | |
58 | diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c | |
59 | index 5df57f7bae0a..b3e362437ec4 100644 | |
60 | --- a/arch/powerpc/lib/feature-fixups.c | |
61 | +++ b/arch/powerpc/lib/feature-fixups.c | |
62 | @@ -318,6 +318,37 @@ void do_barrier_nospec_fixups(bool enable) | |
63 | } | |
64 | #endif /* CONFIG_PPC_BARRIER_NOSPEC */ | |
65 | ||
66 | +#ifdef CONFIG_PPC_FSL_BOOK3E | |
67 | +void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end) | |
68 | +{ | |
69 | + unsigned int instr[2], *dest; | |
70 | + long *start, *end; | |
71 | + int i; | |
72 | + | |
73 | + start = fixup_start; | |
74 | + end = fixup_end; | |
75 | + | |
76 | + instr[0] = PPC_INST_NOP; | |
77 | + instr[1] = PPC_INST_NOP; | |
78 | + | |
79 | + if (enable) { | |
80 | + pr_info("barrier-nospec: using isync; sync as speculation barrier\n"); | |
81 | + instr[0] = PPC_INST_ISYNC; | |
82 | + instr[1] = PPC_INST_SYNC; | |
83 | + } | |
84 | + | |
85 | + for (i = 0; start < end; start++, i++) { | |
86 | + dest = (void *)start + *start; | |
87 | + | |
88 | + pr_devel("patching dest %lx\n", (unsigned long)dest); | |
89 | + patch_instruction(dest, instr[0]); | |
90 | + patch_instruction(dest + 1, instr[1]); | |
91 | + } | |
92 | + | |
93 | + printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); | |
94 | +} | |
95 | +#endif /* CONFIG_PPC_FSL_BOOK3E */ | |
96 | + | |
97 | void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) | |
98 | { | |
99 | long *start, *end; | |
100 | -- | |
101 | 2.19.1 | |
102 |