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);
}

Reply via email to