|
@@ -42,55 +42,40 @@ static void __ref __jump_label_transform(struct jump_entry *entry,
|
|
|
void *(*poker)(void *, const void *, size_t),
|
|
|
int init)
|
|
|
{
|
|
|
- union jump_code_union code;
|
|
|
+ union jump_code_union jmp;
|
|
|
const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
|
|
|
const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
|
|
|
+ const void *expect, *code;
|
|
|
+ int line;
|
|
|
+
|
|
|
+ jmp.jump = 0xe9;
|
|
|
+ jmp.offset = jump_entry_target(entry) -
|
|
|
+ (jump_entry_code(entry) + JUMP_LABEL_NOP_SIZE);
|
|
|
|
|
|
if (early_boot_irqs_disabled)
|
|
|
poker = text_poke_early;
|
|
|
|
|
|
if (type == JUMP_LABEL_JMP) {
|
|
|
if (init) {
|
|
|
- /*
|
|
|
- * Jump label is enabled for the first time.
|
|
|
- * So we expect a default_nop...
|
|
|
- */
|
|
|
- if (unlikely(memcmp((void *)entry->code, default_nop, 5)
|
|
|
- != 0))
|
|
|
- bug_at((void *)entry->code, __LINE__);
|
|
|
+ expect = default_nop; line = __LINE__;
|
|
|
} else {
|
|
|
- /*
|
|
|
- * ...otherwise expect an ideal_nop. Otherwise
|
|
|
- * something went horribly wrong.
|
|
|
- */
|
|
|
- if (unlikely(memcmp((void *)entry->code, ideal_nop, 5)
|
|
|
- != 0))
|
|
|
- bug_at((void *)entry->code, __LINE__);
|
|
|
+ expect = ideal_nop; line = __LINE__;
|
|
|
}
|
|
|
|
|
|
- code.jump = 0xe9;
|
|
|
- code.offset = entry->target -
|
|
|
- (entry->code + JUMP_LABEL_NOP_SIZE);
|
|
|
+ code = &jmp.code;
|
|
|
} 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) {
|
|
|
- if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0))
|
|
|
- bug_at((void *)entry->code, __LINE__);
|
|
|
+ expect = default_nop; line = __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__);
|
|
|
+ expect = &jmp.code; line = __LINE__;
|
|
|
}
|
|
|
- memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
|
|
|
+
|
|
|
+ code = ideal_nop;
|
|
|
}
|
|
|
|
|
|
+ if (memcmp((void *)jump_entry_code(entry), expect, JUMP_LABEL_NOP_SIZE))
|
|
|
+ bug_at((void *)jump_entry_code(entry), line);
|
|
|
+
|
|
|
/*
|
|
|
* Make text_poke_bp() a default fallback poker.
|
|
|
*
|
|
@@ -99,11 +84,14 @@ static void __ref __jump_label_transform(struct jump_entry *entry,
|
|
|
* 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);
|
|
|
+ if (poker) {
|
|
|
+ (*poker)((void *)jump_entry_code(entry), code,
|
|
|
+ JUMP_LABEL_NOP_SIZE);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ text_poke_bp((void *)jump_entry_code(entry), code, JUMP_LABEL_NOP_SIZE,
|
|
|
+ (void *)jump_entry_code(entry) + JUMP_LABEL_NOP_SIZE);
|
|
|
}
|
|
|
|
|
|
void arch_jump_label_transform(struct jump_entry *entry,
|