diff options
author | Peter Zijlstra <[email protected]> | 2019-10-09 12:44:17 +0200 |
---|---|---|
committer | Ingo Molnar <[email protected]> | 2019-11-27 07:44:24 +0100 |
commit | 254d2c04515ea4532a503cc5d8649e1513042e56 (patch) | |
tree | db80da541648e4e40fe11f4b066425c4e2b51d62 | |
parent | c12af4407fa5a3fc6396bde379e0882a132df49b (diff) |
x86/alternative: Add text_opcode_size()
Introduce a common helper to map *_INSN_OPCODE to *_INSN_SIZE.
Tested-by: Alexei Starovoitov <[email protected]>
Tested-by: Steven Rostedt (VMware) <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Acked-by: Alexei Starovoitov <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Josh Poimboeuf <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
-rw-r--r-- | arch/x86/include/asm/text-patching.h | 43 | ||||
-rw-r--r-- | arch/x86/kernel/alternative.c | 12 |
2 files changed, 32 insertions, 23 deletions
diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h index 95beb85aef65..93e4266cd5a3 100644 --- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -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) { /* diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index ce737f1da834..f8f34f94d13d 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -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) |