On Sun, Mar 21, 2021 at 01:06:47PM +0100, Borislav Petkov wrote: > I think I've made this simpler; pasting the whole function and not the > diff because former is easier to read:
You've make it only replace a single stream of NOPs. Which is probably fine, but... :-) So mine, while a little more complicated, will replace any number of NOP streams in any location. Saves having to worry about if we missed some stupid corner case somewhere. Anyway, I think I got it slightly wrong.. How's this one? --- static void __init_or_module noinline optimize_nops(struct alt_instr *a, u8 *instr) { int nops = 0, i = 0; bool done = false; struct insn insn; u8 *nop = NULL; do { if (insn_decode_kernel(&insn, &instr[i])) return; if (insn.length == 1 && insn.opcode.bytes[0] == 0x90) nops++; else if (nops) nop = &instr[i - nops]; if (i + insn.length >= a->instrlen) { nop = &instr[i - nops]; done = true; } if (nop) { unsigned long flags; local_irq_save(flags); add_nops(nop, nops); local_irq_restore(flags); DUMP_BYTES(instr, a->instrlen, "%px: [%d:%d) optimized NOPs: ", instr, (int)(unsigned long)(nop-instr), nops); nops = 0; nop = NULL; } i += insn.length; } while (!done); WARN_ON_ONCE(nop); }