x86/alternative: Add text_opcode_size()
Introduce a common helper to map *_INSN_OPCODE to *_INSN_SIZE. Tested-by: Alexei Starovoitov <ast@kernel.org> Tested-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Alexei 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: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
c12af4407f
commit
254d2c0451
|
@ -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)
|
||||
{
|
||||
/*
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue