Skip to contentSkip to conversation

x86: Introduce REX prefix helper for kprobes

PATCH Applied Harvey Harrison 4 participants 8 messages Dec 24, 2007 – Dec 30, 2007 x86

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86: Introduce REX prefix helper for kprobes

Fold some small ifdefs into a helper function.

---
Masami, Ingo, I had this left in some unsent kprobes unification work. Depends on your tastes, but does reduce ifdefs and is a bit better about self-documenting the REX prefix on X86_64.

If I find places that could also use this I'll try to find a suitable header any stick a static inline there instead. Otherwise static to kprobes.c is probably more appropriate for now.

 arch/x86/kernel/kprobes.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)
arch/x86/kernel/kprobes.c +19 -8
index 4e33329..b1804e4 100644
@@ -171,6 +171,19 @@ static void __kprobes set_jmp_op(void *from, void *to)
 }
 
 /*
+ * Check for the REX prefix which can only exist on X86_64
+ * X86_32 always returns 0
+ */
+static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
+{
+#ifdef CONFIG_X86_64
+	if ((*insn & 0xf0) == 0x40)
+		return 1;
+#endif
+	return 0;
+}
+
+/*
  * Returns non-zero if opcode is boostable.
  * RIP relative instructions are adjusted at copying time in 64 bits mode
  */
@@ -239,14 +252,14 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
 	case 0x9d:		/* popf/popfd */
 		return 1;
 	}
-#ifdef CONFIG_X86_64
+
 	/*
-	 * on 64 bit x86, 0x40-0x4f are prefixes so we need to look
+	 * on X86_64, 0x40-0x4f are REX prefixes so we need to look
 	 * at the next byte instead.. but of course not recurse infinitely
 	 */
-	if (*insn  >= 0x40 && *insn <= 0x4f)
+	if (is_REX_prefix(insn))
 		return is_IF_modifier(++insn);
-#endif
+
 	return 0;
 }
 
@@ -284,7 +297,7 @@ static void __kprobes fix_riprel(struct kprobe *p)
 	}
 
 	/* Skip REX instruction prefix.  */
-	if ((*insn & 0xf0) == 0x40)
+	if (is_REX_prefix(insn))
 		++insn;
 
 	if (*insn == 0x0f) {
@@ -748,11 +761,9 @@ static void __kprobes resume_execution(struct kprobe *p,
 	unsigned long orig_ip = (unsigned long)p->addr;
 	kprobe_opcode_t *insn = p->ainsn.insn;
 
-#ifdef CONFIG_X86_64
 	/*skip the REX prefix*/
-	if (*insn >= 0x40 && *insn <= 0x4f)
+	if (is_REX_prefix(insn))
 		insn++;
-#endif
 
 	regs->flags &= ~X86_EFLAGS_TF;
 	switch (*insn) {
Signature · 1 line
1.5.4.rc0.1143.g1a8a
#1 lore raw

Hi Harvey,

Quoted 7 lines · Harvey Harrison

Fold some small ifdefs into a helper function.

---
Masami, Ingo, I had this left in some unsent kprobes unification work. Depends on your tastes, but does reduce ifdefs and is a bit better about self-documenting the REX prefix on X86_64.

Basically, I think it is good idea.
Could you use a macro same as the stack_addr() macro, like as below?

#defile is_REX_prefix(insn) ((insn & 0xf0) == 0x40))

This is just a bit checker, so I think a macro is better to do that.

Quoted 72 lines

If I find places that could also use this I'll try to find a suitable header any stick a static inline there instead. Otherwise static to kprobes.c is probably more appropriate for now.

 arch/x86/kernel/kprobes.c |   27 +++++++++++++++++++--------
 1 files changed, 19 insertions(+), 8 deletions(-)
arch/x86/kernel/kprobes.c +19 -8
index 4e33329..b1804e4 100644
@@ -171,6 +171,19 @@ static void __kprobes set_jmp_op(void *from, void *to)
 }
 
 /*
+ * Check for the REX prefix which can only exist on X86_64
+ * X86_32 always returns 0
+ */
+static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
+{
+#ifdef CONFIG_X86_64
+	if ((*insn & 0xf0) == 0x40)
+		return 1;
+#endif
+	return 0;
+}
+
+/*
  * Returns non-zero if opcode is boostable.
  * RIP relative instructions are adjusted at copying time in 64 bits mode
  */
@@ -239,14 +252,14 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
 	case 0x9d:		/* popf/popfd */
 		return 1;
 	}
-#ifdef CONFIG_X86_64
+
 	/*
-	 * on 64 bit x86, 0x40-0x4f are prefixes so we need to look
+	 * on X86_64, 0x40-0x4f are REX prefixes so we need to look
 	 * at the next byte instead.. but of course not recurse infinitely
 	 */
-	if (*insn  >= 0x40 && *insn <= 0x4f)
+	if (is_REX_prefix(insn))
 		return is_IF_modifier(++insn);
-#endif
+
 	return 0;
 }
 
@@ -284,7 +297,7 @@ static void __kprobes fix_riprel(struct kprobe *p)
 	}
 
 	/* Skip REX instruction prefix.  */
-	if ((*insn & 0xf0) == 0x40)
+	if (is_REX_prefix(insn))
 		++insn;
 
 	if (*insn == 0x0f) {
@@ -748,11 +761,9 @@ static void __kprobes resume_execution(struct kprobe *p,
 	unsigned long orig_ip = (unsigned long)p->addr;
 	kprobe_opcode_t *insn = p->ainsn.insn;
 
-#ifdef CONFIG_X86_64
 	/*skip the REX prefix*/
-	if (*insn >= 0x40 && *insn <= 0x4f)
+	if (is_REX_prefix(insn))
 		insn++;
-#endif
 
 	regs->flags &= ~X86_EFLAGS_TF;
 	switch (*insn) {
Signature · 7 lines
Masami Hiramatsu

Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division

e-mail: [email protected], [email protected]
#2 lore raw
Quoted 11 lines · Masami Hiramatsu

Hi Harvey,

Quoted 7 lines · Harvey Harrison

Fold some small ifdefs into a helper function.

---
Masami, Ingo, I had this left in some unsent kprobes unification work. Depends on your tastes, but does reduce ifdefs and is a bit better about self-documenting the REX prefix on X86_64.

Quoted 7 lines

Basically, I think it is good idea.
Could you use a macro same as the stack_addr() macro, like as below?

#defile is_REX_prefix(insn) ((insn & 0xf0) == 0x40))

This is just a bit checker, so I think a macro is better to do that.

Why is a macro better than an inline, and why the odd mIXed case?

-hpa

#3 lore raw

Hi,

Quoted 8 lines · H. Peter Anvin
Quoted 6 lines

Could you use a macro same as the stack_addr() macro, like as below?

#defile is_REX_prefix(insn) ((insn & 0xf0) == 0x40))

This is just a bit checker, so I think a macro is better to do that.

Why is a macro better than an inline, and why the odd mIXed case?

I thought we can use macro because it just check a bit mask. And if we use this as a macro, it will be defined in #ifdef block at the top of kprobes.c. It is simple in this case.
I know the inline is better than the macro, it can check the type of arguments.
If you would like to use inline, how about this?

---
(in case of CONFIG_X86_64)
static inline int is_rex_prefix(int op)

{
	return ((op & 0xf0) == 0x40);
}

(in case of CONFIG_X86_32)
#define is_rex_prefix(op) (0)
---

About the name, I just used the previous inline function name.

Thank you,

Quoted 2 lines

-hpa

Signature · 7 lines
Masami Hiramatsu

Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division

e-mail: [email protected], [email protected]
#4 lore raw
Quoted 2 lines · Masami Hiramatsu

(in case of CONFIG_X86_64)
static inline int is_rex_prefix(int op)

Oops, s/int op/kprobe_opcode_t opcode/

Quoted 1 line

About the name, I just used the previous inline function name.

I re-think "is_REX_prefix" is better, because it is an architecture dependent notation(intel's software developers manual called it "REX prefixes"), and there is already is_IF_modifier() function in arch/x86/kernel/kprobes.c.

Thanks,

Best Regards,

Signature · 7 lines
Masami Hiramatsu

Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division

e-mail: [email protected], [email protected]
#5 lore raw
In reply to Masami Hiramatsu
Quoted 7 lines · Masami Hiramatsu
Quoted 1 line

Why is a macro better than an inline, and why the odd mIXed case?

I thought we can use macro because it just check a bit mask. And if we use this as a macro, it will be defined in #ifdef block at the top of kprobes.c. It is simple in this case. I know the inline is better than the macro, it can check the type of arguments. If you would like to use inline, how about this?

yes, we prefer inlines for just about everything. We have reoccuring regressions due to macro side-effects, lack of type and argument checking - and the simplest maintenance policy is to just never introduce new macros. Macros also played an active role in creating our current include file dependencies spaghetti. So unless there are very, very strong reasons in favor of adding a macro, please always use inlines.

Ingo

#6 lore raw
In reply to H. Peter Anvin
Quoted 15 lines · H. Peter Anvin
Quoted 14 lines · Masami Hiramatsu

Hi Harvey,

Quoted 7 lines · Harvey Harrison

Fold some small ifdefs into a helper function.

---
Masami, Ingo, I had this left in some unsent kprobes unification work. Depends on your tastes, but does reduce ifdefs and is a bit better about self-documenting the REX prefix on X86_64.

Basically, I think it is good idea.
Could you use a macro same as the stack_addr() macro, like as below?

Quoted 7 lines
Quoted 4 lines

#defile is_REX_prefix(insn) ((insn & 0xf0) == 0x40))

This is just a bit checker, so I think a macro is better to do that.

Why is a macro better than an inline, and why the odd mIXed case?

I was emulating existing practice I saw in kprobes, see is_IF_modifier.

Harvey