Commit 73175d0d authored by Oleg Nesterov's avatar Oleg Nesterov

uprobes/x86: Add uprobe_init_insn(), kill validate_insn_{32,64}bits()

validate_insn_32bits() and validate_insn_64bits() are very similar,
turn them into the single uprobe_init_insn() which has the additional
"bool x86_64" argument which can be passed to insn_init() and used to
choose between good_insns_64/good_insns_32.

Also kill UPROBE_FIX_NONE, it has no users.

Note: the current code doesn't use ifdef's consistently, good_insns_64
depends on CONFIG_X86_64 but good_insns_32 is unconditional. This patch
removes ifdef around good_insns_64, we will add it back later along with
the similar one for good_insns_32.
Signed-off-by: default avatarOleg Nesterov <oleg@redhat.com>
Reviewed-by: default avatarJim Keniston <jkenisto@us.ibm.com>
Acked-by: default avatarSrikar Dronamraju <srikar@linux.vnet.ibm.com>
parent 250bbd12
...@@ -32,9 +32,6 @@ ...@@ -32,9 +32,6 @@
/* Post-execution fixups. */ /* Post-execution fixups. */
/* No fixup needed */
#define UPROBE_FIX_NONE 0x0
/* Adjust IP back to vicinity of actual insn */ /* Adjust IP back to vicinity of actual insn */
#define UPROBE_FIX_IP 0x1 #define UPROBE_FIX_IP 0x1
...@@ -114,7 +111,6 @@ static volatile u32 good_2byte_insns[256 / 32] = { ...@@ -114,7 +111,6 @@ static volatile u32 good_2byte_insns[256 / 32] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
}; };
#ifdef CONFIG_X86_64
/* Good-instruction tables for 64-bit apps */ /* Good-instruction tables for 64-bit apps */
static volatile u32 good_insns_64[256 / 32] = { static volatile u32 good_insns_64[256 / 32] = {
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
...@@ -138,7 +134,6 @@ static volatile u32 good_insns_64[256 / 32] = { ...@@ -138,7 +134,6 @@ static volatile u32 good_insns_64[256 / 32] = {
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
}; };
#endif
#undef W #undef W
/* /*
...@@ -209,16 +204,22 @@ static bool is_prefix_bad(struct insn *insn) ...@@ -209,16 +204,22 @@ static bool is_prefix_bad(struct insn *insn)
return false; return false;
} }
static int validate_insn_32bits(struct arch_uprobe *auprobe, struct insn *insn) static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool x86_64)
{ {
insn_init(insn, auprobe->insn, false); u32 volatile *good_insns;
insn_init(insn, auprobe->insn, x86_64);
/* Skip good instruction prefixes; reject "bad" ones. */
insn_get_opcode(insn); insn_get_opcode(insn);
if (is_prefix_bad(insn)) if (is_prefix_bad(insn))
return -ENOTSUPP; return -ENOTSUPP;
if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_32)) if (x86_64)
good_insns = good_insns_64;
else
good_insns = good_insns_32;
if (test_bit(OPCODE1(insn), (unsigned long *)good_insns))
return 0; return 0;
if (insn->opcode.nbytes == 2) { if (insn->opcode.nbytes == 2) {
...@@ -355,30 +356,10 @@ handle_riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs, long * ...@@ -355,30 +356,10 @@ handle_riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs, long *
} }
} }
static int validate_insn_64bits(struct arch_uprobe *auprobe, struct insn *insn)
{
insn_init(insn, auprobe->insn, true);
/* Skip good instruction prefixes; reject "bad" ones. */
insn_get_opcode(insn);
if (is_prefix_bad(insn))
return -ENOTSUPP;
if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_64))
return 0;
if (insn->opcode.nbytes == 2) {
if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
return 0;
}
return -ENOTSUPP;
}
static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn) static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn)
{ {
if (mm->context.ia32_compat) bool x86_64 = !mm->context.ia32_compat;
return validate_insn_32bits(auprobe, insn); return uprobe_init_insn(auprobe, insn, x86_64);
return validate_insn_64bits(auprobe, insn);
} }
#else /* 32-bit: */ #else /* 32-bit: */
/* /*
...@@ -398,7 +379,7 @@ static void handle_riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs * ...@@ -398,7 +379,7 @@ static void handle_riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *
static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn) static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn)
{ {
return validate_insn_32bits(auprobe, insn); return uprobe_init_insn(auprobe, insn, false);
} }
#endif /* CONFIG_X86_64 */ #endif /* CONFIG_X86_64 */
......
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