|
From: Masami H. <mas...@hi...> - 2010-12-16 13:27:54
|
Hi,
Here is a combined patch of kprobes jump optimization (a.k.a. Djprobe)
for RHEL6.0 kernel 2.6.32-71.el6. With this patch, some kprobes can
be optimized by a jump and it reduces the probing overhead drastically.
This patch includes following commits:
b46b3d70c9c017d7c4ec49f7f3ffd0af5a622277
89ae465b0ee470f7d3f8a1c61353445c3acbbe2a
24851d2447830e6cba4c4b641cb73e713f312373
e9afe9e1b3fdbd56cca53959a2519e70db9c8095
f5ad31158d60946b9fd18c8a79c283a6bc432430
65e234ec2c4a0659ca22531dc1372a185f088517
a00e817f42663941ea0aa5f85a9d1c4f8b212839
1f0ab40976460bc4673fa204ce917a725185d8f2
98272ed0d2e6509fe7dc571e77956c99bf653bb6
4dae560f97fa438f373b53e14b30149c9e44a600
c2ef6661ce62e26a8c0978e521fab646128a144b
615d0ebbc782b67296e3226c293f520f93f93515
2cfa19780d61740f65790c5bae363b759d7c96fa
076dc4a65a6d99a16979e2c7917e669fb8c91ee5
4554dbcb85a4ed2abaa2b6fa15649b796699ec89
5ecaafdbf44b1ba400b746c60c401d54c7ee0863
d498f763950703c724c650db1d34a1c8679f9ca8
4610ee1d3638fa05ba8e87ccfa971db8e4033ae7
afd66255b9a48f5851326ddae50e2203fbf71dc9
b2be84df99ebc93599c69e931a3c4a5105abfabc
0f94eb634ef7af736dee5639aac1c2fe9635d089
f007ea2685692bafb386820144cf73a14016fc7c
3d55cc8a058ee96291d6d45b1e35121b9920eca3
c0f7ac3a9edde786bc129d37627953a8b8abefdf
e5a11016643d1ab7172193591506d33a844734cc
83ff56f46a8532488ee364bb93a9cb2a59490d33
c0614829c16ab9d31f1b7d40516decfbf3d32102
a197479848a2f1a2a5c07cffa6c31ab5e8c82797
737480a0d525dae13306296da08029dff545bc72
edbaadbe42b0b790618ec49d29626223529d8195
05662bdb64c746079de7ac4dc4fb4caa5e8e119f
6376b2297502e72255b7eb2893c6044ad5a7b5f4
6abded71d730322df96c5b7f4ab952ffd5a0080d
635c17c2b2b4e5cd34f5dcba19d751b4e58533c2
43948f50276eca010a22726860dfe9a4e8130136
404ba5d7bb958d3d788bdaa0debc0bdf60f13ffe
Below commits has been changed. Here I added some comments
about those changes.
[89ae465b0ee470f7d3f8a1c61353445c3acbbe2a]
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
@@ -94,32 +95,11 @@
- s64 disp;
- int need_modrm;
-
-- /* Skip legacy instruction prefixes. */
-- while (1) {
-- switch (*insn) {
-- case 0x66:
-- case 0x67:
-- case 0x2e:
-- case 0x3e:
-- case 0x26:
-- case 0x64:
-- case 0x65:
-- case 0x36:
-- case 0xf0:
-- case 0xf3:
-- case 0xf2:
-- ++insn;
-- continue;
-- }
-- break;
-- }
+- /* Skip prefixes */
+- insn = skip_prefixes(insn);
+ struct insn insn;
+ kernel_insn_init(&insn, p->ainsn.insn);
-- /* Skip REX instruction prefix. */
-- if (is_REX_prefix(insn))
-- ++insn;
--
- if (*insn == 0x0f) {
- /* Two-byte opcode. */
- ++insn;
RHEL6 already includes "skip_prefixes" bugfix patch which fixes
BZ#607215. Since it changes this part of kprobes code, this
commit should be modified.
[4554dbcb85a4ed2abaa2b6fa15649b796699ec89]
@@ -36,18 +38,20 @@
return -EILSEQ;
/* insn: must be on special executable page on x86. */
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
-index 9907a03..c3340e8 100644
+index 9907a03..95d5787 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
-@@ -44,6 +44,7 @@
- #include <linux/debugfs.h>
- #include <linux/kdebug.h>
- #include <linux/memory.h>
-+#include <linux/ftrace.h>
+@@ -685,6 +685,9 @@ static inline int check_kprobe_rereg(struct kprobe *p)
+ return ret;
+ }
- #include <asm-generic/sections.h>
- #include <asm/cacheflush.h>
-@@ -703,7 +704,8 @@ int __kprobes register_kprobe(struct kprobe *p)
++/* Don't include ftrace.h since kabi will be broken. */
++extern int ftrace_text_reserved(void *start, void *end);
++
+ int __kprobes register_kprobe(struct kprobe *p)
+ {
+ int ret = 0;
+@@ -703,7 +706,8 @@ int __kprobes register_kprobe(struct kprobe *p)
preempt_disable();
if (!kernel_text_address((unsigned long) p->addr) ||
I'm not sure why but including ftrace.h broke kABI compatibility,
so I removed "#include <linux/ftrace.h>" line.
[d498f763950703c724c650db1d34a1c8679f9ca8]
-@@ -32,7 +32,7 @@ struct kprobe;
+@@ -33,7 +33,7 @@ struct kprobe;
typedef u8 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0xcc
-#define RELATIVEJUMP_INSTRUCTION 0xe9
+#define RELATIVEJUMP_OPCODE 0xe9
- #define MAX_INSN_SIZE 16
#define MAX_STACK_SIZE 64
#define MIN_STACK_SIZE(ADDR) \
+ (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
A patch which moves MAX_INSN_SIZE definition from asm/kprobes.h has
been applied in RHEL6.0 kernel. Thus this commit should be modified.
[b2be84df99ebc93599c69e931a3c4a5105abfabc]
@@ -200,12 +203,13 @@
#include <asm/uaccess.h>
#include <asm/processor.h>
-@@ -1450,6 +1451,17 @@ static struct ctl_table debug_table[] = {
- .proc_handler = proc_dointvec
+@@ -1691,6 +1692,18 @@ static struct ctl_table debug_table[] = {
+ .extra1 = &zero,
},
#endif
+#if defined(CONFIG_OPTPROBES)
+ {
++ .ctl_name = CTL_UNNUMBERED,
+ .procname = "kprobes-optimization",
+ .data = &sysctl_kprobes_optimization,
+ .maxlen = sizeof(int),
@@ -215,6 +219,6 @@
+ .extra2 = &one,
+ },
+#endif
- { }
+ { .ctl_name = 0 }
};
On RHEL6.0 and recent kernel changed sysctl format. This patch
also should be modified according that change.
[0f94eb634ef7af736dee5639aac1c2fe9635d089]
@@ -113,6 +114,8 @@
+ setup_singlestep(p, regs, kcb, 0);
return 1;
}
+ } else if (*addr != BREAKPOINT_INSTRUCTION) {
+@@ -549,7 +553,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
} else if (kprobe_running()) {
p = __get_cpu_var(current_kprobe);
if (p->break_handler && p->break_handler(p, regs)) {
RHEL6.0 includes BZ#585400 bugfix (829e92458532b1dbfeb972435d45bb060cdbf5a3
in upstream) patch, and it changes arch/x86/kernel/kprobes.c. This patch
has been affected by that change.
That's all.
Thank you,
--
Masami HIRAMATSU
2nd Dept. Linux Technology Center
Hitachi, Ltd., Systems Development Laboratory
E-mail: mas...@hi...
|