Exemplo n.º 1
0
/*
 * Replace instructions with better alternatives for this CPU type.
 * This runs before SMP is initialized to avoid SMP problems with
 * self modifying code. This implies that asymmetric systems where
 * APs have less capabilities than the boot processor are not handled.
 * Tough. Make sure you disable such features by hand.
 */
static void __init apply_alternatives(struct alt_instr *start, struct alt_instr *end)
{
    struct alt_instr *a;
    u8 *instr, *replacement;
    u8 insnbuf[MAX_PATCH_LEN];

    ASSERT(!local_irq_is_enabled());

    printk(KERN_INFO "alt table %p -> %p\n", start, end);

    /*
     * The scan order should be from start to end. A later scanned
     * alternative code can overwrite a previous scanned alternative code.
     * Some kernel functions (e.g. memcpy, memset, etc) use this order to
     * patch code.
     *
     * So be careful if you want to change the scan order to any other
     * order.
     */
    for ( a = start; a < end; a++ )
    {
        instr = (u8 *)&a->instr_offset + a->instr_offset;
        replacement = (u8 *)&a->repl_offset + a->repl_offset;
        BUG_ON(a->replacementlen > a->instrlen);
        BUG_ON(a->instrlen > sizeof(insnbuf));
        BUG_ON(a->cpuid >= NCAPINTS * 32);
        if ( !boot_cpu_has(a->cpuid) )
            continue;

        memcpy(insnbuf, replacement, a->replacementlen);

        /* 0xe8/0xe9 are relative branches; fix the offset. */
        if ( (*insnbuf & 0xfe) == 0xe8 && a->replacementlen == 5 )
            *(s32 *)(insnbuf + 1) += replacement - instr;

        add_nops(insnbuf + a->replacementlen,
                 a->instrlen - a->replacementlen);
        text_poke_early(instr, insnbuf, a->instrlen);
    }
}
Exemplo n.º 2
0
void arch_jump_label_text_poke_early(jump_label_t addr)
{
	text_poke_early((void *)addr, ideal_nops[NOP_ATOMIC5],
			JUMP_LABEL_NOP_SIZE);
}