diff options
author | Diana Craciun <diana.craciun@nxp.com> | 2018-07-28 02:06:37 +0300 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2018-08-07 17:32:24 +0300 |
commit | ebcd1bfc33c7a90df941df68a6e5d4018c022fba (patch) | |
tree | 55128a08e7c84290d2e187f7c79d66743c7cc5ea /arch/powerpc/lib/feature-fixups.c | |
parent | 406d2b6ae3420f5bb2b3db6986dc6f0b6dbb637b (diff) | |
download | linux-ebcd1bfc33c7a90df941df68a6e5d4018c022fba.tar.xz |
powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E
Implement the barrier_nospec as a isync;sync instruction sequence.
The implementation uses the infrastructure built for BOOK3S 64.
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
[mpe: Split out of larger patch]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/lib/feature-fixups.c')
-rw-r--r-- | arch/powerpc/lib/feature-fixups.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 0e604b41b5d1..e613b02bb2f0 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -318,6 +318,37 @@ void do_barrier_nospec_fixups(bool enable) } #endif /* CONFIG_PPC_BARRIER_NOSPEC */ +#ifdef CONFIG_PPC_FSL_BOOK3E +void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end) +{ + unsigned int instr[2], *dest; + long *start, *end; + int i; + + start = fixup_start; + end = fixup_end; + + instr[0] = PPC_INST_NOP; + instr[1] = PPC_INST_NOP; + + if (enable) { + pr_info("barrier-nospec: using isync; sync as speculation barrier\n"); + instr[0] = PPC_INST_ISYNC; + instr[1] = PPC_INST_SYNC; + } + + for (i = 0; start < end; start++, i++) { + dest = (void *)start + *start; + + pr_devel("patching dest %lx\n", (unsigned long)dest); + patch_instruction(dest, instr[0]); + patch_instruction(dest + 1, instr[1]); + } + + printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); +} +#endif /* CONFIG_PPC_FSL_BOOK3E */ + void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) { long *start, *end; |