diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2009-01-06 17:41:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-06 18:59:20 -0500 |
commit | 8e1144050e49dd4ef19c117dc5626f212cfe73cf (patch) | |
tree | b7feb97dc6f341999fbcaf8b4964e7e660cf0317 | |
parent | bc2f70151fe7a117dbe8347edc5a877e749572a3 (diff) |
kprobes: indirectly call kprobe_target
Call kprobe_target indirectly. This prevents gcc to unroll a noinline
function in caller function.
I ported patches which had been discussed on
http://sources.redhat.com/bugzilla/show_bug.cgi?id=3542
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Acked-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: David Miller <davem@davemloft.net>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/test_kprobes.c | 21 |
1 files changed, 6 insertions, 15 deletions
diff --git a/kernel/test_kprobes.c b/kernel/test_kprobes.c index 06b6395b45b2..9c0127ead6ab 100644 --- a/kernel/test_kprobes.c +++ b/kernel/test_kprobes.c | |||
@@ -22,21 +22,10 @@ | |||
22 | 22 | ||
23 | static u32 rand1, preh_val, posth_val, jph_val; | 23 | static u32 rand1, preh_val, posth_val, jph_val; |
24 | static int errors, handler_errors, num_tests; | 24 | static int errors, handler_errors, num_tests; |
25 | static u32 (*target)(u32 value); | ||
25 | 26 | ||
26 | static noinline u32 kprobe_target(u32 value) | 27 | static noinline u32 kprobe_target(u32 value) |
27 | { | 28 | { |
28 | /* | ||
29 | * gcc ignores noinline on some architectures unless we stuff | ||
30 | * sufficient lard into the function. The get_kprobe() here is | ||
31 | * just for that. | ||
32 | * | ||
33 | * NOTE: We aren't concerned about the correctness of get_kprobe() | ||
34 | * here; hence, this call is neither under !preempt nor with the | ||
35 | * kprobe_mutex held. This is fine(tm) | ||
36 | */ | ||
37 | if (get_kprobe((void *)0xdeadbeef)) | ||
38 | printk(KERN_INFO "Kprobe smoke test: probe on 0xdeadbeef!\n"); | ||
39 | |||
40 | return (value / div_factor); | 29 | return (value / div_factor); |
41 | } | 30 | } |
42 | 31 | ||
@@ -74,7 +63,7 @@ static int test_kprobe(void) | |||
74 | return ret; | 63 | return ret; |
75 | } | 64 | } |
76 | 65 | ||
77 | ret = kprobe_target(rand1); | 66 | ret = target(rand1); |
78 | unregister_kprobe(&kp); | 67 | unregister_kprobe(&kp); |
79 | 68 | ||
80 | if (preh_val == 0) { | 69 | if (preh_val == 0) { |
@@ -121,7 +110,7 @@ static int test_jprobe(void) | |||
121 | return ret; | 110 | return ret; |
122 | } | 111 | } |
123 | 112 | ||
124 | ret = kprobe_target(rand1); | 113 | ret = target(rand1); |
125 | unregister_jprobe(&jp); | 114 | unregister_jprobe(&jp); |
126 | if (jph_val == 0) { | 115 | if (jph_val == 0) { |
127 | printk(KERN_ERR "Kprobe smoke test failed: " | 116 | printk(KERN_ERR "Kprobe smoke test failed: " |
@@ -177,7 +166,7 @@ static int test_kretprobe(void) | |||
177 | return ret; | 166 | return ret; |
178 | } | 167 | } |
179 | 168 | ||
180 | ret = kprobe_target(rand1); | 169 | ret = target(rand1); |
181 | unregister_kretprobe(&rp); | 170 | unregister_kretprobe(&rp); |
182 | if (krph_val != rand1) { | 171 | if (krph_val != rand1) { |
183 | printk(KERN_ERR "Kprobe smoke test failed: " | 172 | printk(KERN_ERR "Kprobe smoke test failed: " |
@@ -193,6 +182,8 @@ int init_test_probes(void) | |||
193 | { | 182 | { |
194 | int ret; | 183 | int ret; |
195 | 184 | ||
185 | target = kprobe_target; | ||
186 | |||
196 | do { | 187 | do { |
197 | rand1 = random32(); | 188 | rand1 = random32(); |
198 | } while (rand1 <= div_factor); | 189 | } while (rand1 <= div_factor); |