Commit 254d2c04 authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

x86/alternative: Add text_opcode_size()



Introduce a common helper to map *_INSN_OPCODE to *_INSN_SIZE.

Tested-by: default avatarAlexei Starovoitov <ast@kernel.org>
Tested-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/20191111132457.875666061@infradead.org


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent c12af440
Loading
Loading
Loading
Loading
+31 −12
Original line number Diff line number Diff line
@@ -49,18 +49,6 @@ extern void text_poke_bp(void *addr, const void *opcode, size_t len, const void
extern void text_poke_queue(void *addr, const void *opcode, size_t len, const void *emulate);
extern void text_poke_finish(void);

extern void *text_gen_insn(u8 opcode, const void *addr, const void *dest);

extern int after_bootmem;
extern __ro_after_init struct mm_struct *poking_mm;
extern __ro_after_init unsigned long poking_addr;

#ifndef CONFIG_UML_X86
static inline void int3_emulate_jmp(struct pt_regs *regs, unsigned long ip)
{
	regs->ip = ip;
}

#define INT3_INSN_SIZE		1
#define INT3_INSN_OPCODE	0xCC

@@ -73,6 +61,37 @@ static inline void int3_emulate_jmp(struct pt_regs *regs, unsigned long ip)
#define JMP8_INSN_SIZE		2
#define JMP8_INSN_OPCODE	0xEB

static inline int text_opcode_size(u8 opcode)
{
	int size = 0;

#define __CASE(insn)	\
	case insn##_INSN_OPCODE: size = insn##_INSN_SIZE; break

	switch(opcode) {
	__CASE(INT3);
	__CASE(CALL);
	__CASE(JMP32);
	__CASE(JMP8);
	}

#undef __CASE

	return size;
}

extern void *text_gen_insn(u8 opcode, const void *addr, const void *dest);

extern int after_bootmem;
extern __ro_after_init struct mm_struct *poking_mm;
extern __ro_after_init unsigned long poking_addr;

#ifndef CONFIG_UML_X86
static inline void int3_emulate_jmp(struct pt_regs *regs, unsigned long ip)
{
	regs->ip = ip;
}

static inline void int3_emulate_push(struct pt_regs *regs, unsigned long val)
{
	/*
+1 −11
Original line number Diff line number Diff line
@@ -1259,22 +1259,12 @@ union text_poke_insn {
void *text_gen_insn(u8 opcode, const void *addr, const void *dest)
{
	static union text_poke_insn insn; /* text_mutex */
	int size = 0;
	int size = text_opcode_size(opcode);

	lockdep_assert_held(&text_mutex);

	insn.opcode = opcode;

#define __CASE(insn)	\
	case insn##_INSN_OPCODE: size = insn##_INSN_SIZE; break

	switch(opcode) {
	__CASE(INT3);
	__CASE(CALL);
	__CASE(JMP32);
	__CASE(JMP8);
	}

	if (size > 1) {
		insn.disp = (long)dest - (long)(addr + size);
		if (size == 2)