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

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.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent c12af440
...@@ -49,18 +49,6 @@ extern void text_poke_bp(void *addr, const void *opcode, size_t len, const void ...@@ -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_queue(void *addr, const void *opcode, size_t len, const void *emulate);
extern void text_poke_finish(void); 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_SIZE 1
#define INT3_INSN_OPCODE 0xCC #define INT3_INSN_OPCODE 0xCC
...@@ -73,6 +61,37 @@ static inline void int3_emulate_jmp(struct pt_regs *regs, unsigned long ip) ...@@ -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_SIZE 2
#define JMP8_INSN_OPCODE 0xEB #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) static inline void int3_emulate_push(struct pt_regs *regs, unsigned long val)
{ {
/* /*
......
...@@ -1259,22 +1259,12 @@ union text_poke_insn { ...@@ -1259,22 +1259,12 @@ union text_poke_insn {
void *text_gen_insn(u8 opcode, const void *addr, const void *dest) void *text_gen_insn(u8 opcode, const void *addr, const void *dest)
{ {
static union text_poke_insn insn; /* text_mutex */ static union text_poke_insn insn; /* text_mutex */
int size = 0; int size = text_opcode_size(opcode);
lockdep_assert_held(&text_mutex); lockdep_assert_held(&text_mutex);
insn.opcode = opcode; 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) { if (size > 1) {
insn.disp = (long)dest - (long)(addr + size); insn.disp = (long)dest - (long)(addr + size);
if (size == 2) if (size == 2)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment