On Mon, Jan 8, 2018 at 8:54 AM, Michael Ellerman <m...@ellerman.id.au> wrote: > On some CPUs we can prevent the Meltdown vulnerability by flushing the > L1-D cache on exit from kernel to user mode, and from hypervisor to > guest.
Super minor nitpicks below. Don't let this hold up your work. > --- a/arch/powerpc/kernel/exceptions-64s.S > +++ b/arch/powerpc/kernel/exceptions-64s.S > @@ -1449,6 +1449,88 @@ masked_##_H##interrupt: > \ > b .; \ > MASKED_DEC_HANDLER(_H) > > +TRAMP_REAL_BEGIN(rfi_flush_fallback) > + SET_SCRATCH0(r13); > + GET_PACA(r13); > + std r9,PACA_EXRFI+EX_R9(r13) > + std r10,PACA_EXRFI+EX_R10(r13) > + std r11,PACA_EXRFI+EX_R11(r13) > + std r12,PACA_EXRFI+EX_R12(r13) > + std r8,PACA_EXRFI+EX_R13(r13) > + mfctr r9 > + ld r10,PACA_RFI_FLUSH_FALLBACK_AREA(r13) > + ld r11,PACA_L1D_FLUSH_SETS(r13) > + ld r12,PACA_L1D_FLUSH_CONGRUENCE(r13) > + /* > + * The load adresses are at staggered offsets within cachelines, > + * which suits some pipelines better (on others it should not > + * hurt. Nit: missing ) on the last line. > + */ > + addi r12,r12,8 > + mtctr r11 > + DCBT_STOP_ALL_STREAM_IDS(r11) /* Stop prefetch streams */ > + > --- a/arch/powerpc/lib/feature-fixups.c > +++ b/arch/powerpc/lib/feature-fixups.c > @@ -116,6 +116,47 @@ void do_feature_fixups(unsigned long value, void > *fixup_start, void *fixup_end) > } > } > > +#ifdef CONFIG_PPC_BOOK3S_64 > +void do_rfi_flush_fixups(enum l1d_flush_type types) > +{ > + unsigned int instrs[3], *dest; > + long *start, *end; > + int i; > + > + start = PTRRELOC(&__start___rfi_flush_fixup), > + end = PTRRELOC(&__stop___rfi_flush_fixup); > + > + instrs[0] = 0x60000000; /* nop */ > + instrs[1] = 0x60000000; /* nop */ > + instrs[2] = 0x60000000; /* nop */ > + > + if (types & L1D_FLUSH_FALLBACK) This looked a bit confusing on first read. Do we ever get L1D_FLUSH_FALLBACK and the other types? If not, could it be made clearer? if ( types & L1D_FLUSH_FALLBACK) /* stuff */ else /* other types */ > + /* b .+16 to fallback flush */ > + instrs[0] = 0x48000010; > + > + i = 0; > + if (types & L1D_FLUSH_ORI) { > + instrs[i++] = 0x63ff0000; /* ori 31,31,0 speculation barrier > */ > + instrs[i++] = 0x63de0000; /* ori 30,30,0 L1d flush*/ > + } > + > + if (types & L1D_FLUSH_MTTRIG) > + instrs[i++] = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */ > + > + for (i = 0; start < end; start++, i++) { > + dest = (void *)start + *start; > + > + pr_devel("patching dest %lx\n", (unsigned long)dest); > + > + patch_instruction(dest, instrs[0]); > + patch_instruction(dest + 1, instrs[1]); > + patch_instruction(dest + 2, instrs[2]); > + } > + > + printk(KERN_DEBUG "rfi-flush: patched %d locations\n", i); > +} > +#endif /* CONFIG_PPC_BOOK3S_64 */ > + > void do_lwsync_fixups(unsigned long value, void *fixup_start, void > *fixup_end) > { > long *start, *end; > -- > 2.14.3 >