From: Linus Torvalds Date: Wed, 11 Sep 2013 02:43:23 +0000 (-0700) Subject: Merge branch 'x86/jumplabel' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=442e0973e9273ae8832abd70f52efde8b8326178;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git Merge branch 'x86/jumplabel' of git://git./linux/kernel/git/tip/tip Pull x86 jumplabel changes from Peter Anvin: "One more x86 tree for this merge window. This tree improves the handling of jump labels, so that most of the time we don't have to do a massive initial patching run. Furthermore, we will error out of the jump label is not what is expected, eg if it has been corrupted or tampered with" * 'x86/jumplabel' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/jump-label: Show where and what was wrong on errors x86/jump-label: Add safety checks to jump label conversions x86/jump-label: Do not bother updating nops if they are correct x86/jump-label: Use best default nops for inital jump label calls --- 442e0973e9273ae8832abd70f52efde8b8326178 diff --cc arch/x86/kernel/jump_label.c index 460f5d9ceebb,912a52812916..ee11b7dfbfbb --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c @@@ -34,22 -55,28 +55,40 @@@ static void __jump_label_transform(stru code.jump = 0xe9; code.offset = entry->target - (entry->code + JUMP_LABEL_NOP_SIZE); - } else + } else { + /* + * We are disabling this jump label. If it is not what + * we think it is, then something must have gone wrong. + * If this is the first initialization call, then we + * are converting the default nop to the ideal nop. + */ + if (init) { + const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP }; + if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0)) + bug_at((void *)entry->code, __LINE__); + } else { + code.jump = 0xe9; + code.offset = entry->target - + (entry->code + JUMP_LABEL_NOP_SIZE); + if (unlikely(memcmp((void *)entry->code, &code, 5) != 0)) + bug_at((void *)entry->code, __LINE__); + } memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE); + } - (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); + /* + * Make text_poke_bp() a default fallback poker. + * + * At the time the change is being done, just ignore whether we + * are doing nop -> jump or jump -> nop transition, and assume + * always nop being the 'currently valid' instruction + * + */ + if (poker) + (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE); + else + text_poke_bp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE, + (void *)entry->code + JUMP_LABEL_NOP_SIZE); } void arch_jump_label_transform(struct jump_entry *entry, @@@ -57,7 -84,7 +96,7 @@@ { get_online_cpus(); mutex_lock(&text_mutex); - __jump_label_transform(entry, type, NULL); - __jump_label_transform(entry, type, text_poke_smp, 0); ++ __jump_label_transform(entry, type, NULL, 0); mutex_unlock(&text_mutex); put_online_cpus(); }