Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Diana Craciun and committed by
Michael Ellerman
ebcd1bfc 406d2b6a

+39 -2
+1 -1
arch/powerpc/Kconfig
··· 245 245 config PPC_BARRIER_NOSPEC 246 246 bool 247 247 default y 248 - depends on PPC_BOOK3S_64 248 + depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E 249 249 250 250 config GENERIC_CSUM 251 251 def_bool n
+7 -1
arch/powerpc/include/asm/barrier.h
··· 78 78 ___p1; \ 79 79 }) 80 80 81 + #ifdef CONFIG_PPC_BOOK3S_64 82 + #define NOSPEC_BARRIER_SLOT nop 83 + #elif defined(CONFIG_PPC_FSL_BOOK3E) 84 + #define NOSPEC_BARRIER_SLOT nop; nop 85 + #endif 86 + 81 87 #ifdef CONFIG_PPC_BARRIER_NOSPEC 82 88 /* 83 89 * Prevent execution of subsequent instructions until preceding branches have 84 90 * been fully resolved and are no longer executing speculatively. 85 91 */ 86 - #define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; nop 92 + #define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; NOSPEC_BARRIER_SLOT 87 93 88 94 // This also acts as a compiler barrier due to the memory clobber. 89 95 #define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory")
+31
arch/powerpc/lib/feature-fixups.c
··· 318 318 } 319 319 #endif /* CONFIG_PPC_BARRIER_NOSPEC */ 320 320 321 + #ifdef CONFIG_PPC_FSL_BOOK3E 322 + void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end) 323 + { 324 + unsigned int instr[2], *dest; 325 + long *start, *end; 326 + int i; 327 + 328 + start = fixup_start; 329 + end = fixup_end; 330 + 331 + instr[0] = PPC_INST_NOP; 332 + instr[1] = PPC_INST_NOP; 333 + 334 + if (enable) { 335 + pr_info("barrier-nospec: using isync; sync as speculation barrier\n"); 336 + instr[0] = PPC_INST_ISYNC; 337 + instr[1] = PPC_INST_SYNC; 338 + } 339 + 340 + for (i = 0; start < end; start++, i++) { 341 + dest = (void *)start + *start; 342 + 343 + pr_devel("patching dest %lx\n", (unsigned long)dest); 344 + patch_instruction(dest, instr[0]); 345 + patch_instruction(dest + 1, instr[1]); 346 + } 347 + 348 + printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); 349 + } 350 + #endif /* CONFIG_PPC_FSL_BOOK3E */ 351 + 321 352 void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) 322 353 { 323 354 long *start, *end;