diff options
Diffstat (limited to 'arch/x86/kernel/jump_label.c')
| -rw-r--r-- | arch/x86/kernel/jump_label.c | 62 | 
1 files changed, 25 insertions, 37 deletions
| diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c index eeea935e9bb5..aac0c1f7e354 100644 --- a/arch/x86/kernel/jump_label.c +++ b/arch/x86/kernel/jump_label.c @@ -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, |