aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_probe.c
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2013-11-26 01:21:04 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-01-02 16:17:43 -0500
commit5baaa59ef09e8729aef101f7bf7d9d0af00852e3 (patch)
treeadf05e51e33e06d0d9eb9689269364314b754c2c /kernel/trace/trace_probe.c
parent3925f4a5afa489e905a08edffc36a435a3434a63 (diff)
tracing/probes: Implement 'memory' fetch method for uprobes
Use separate method to fetch from memory. Move existing functions to trace_kprobe.c and make them static. Also add new memory fetch implementation for uprobes. Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: zhangwei(Jovi) <jovi.zhangwei@huawei.com> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'kernel/trace/trace_probe.c')
-rw-r--r--kernel/trace/trace_probe.c77
1 files changed, 0 insertions, 77 deletions
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 8d7231d436da..8f7a2b6d389d 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -103,83 +103,6 @@ DEFINE_BASIC_FETCH_FUNCS(retval)
103#define fetch_retval_string NULL 103#define fetch_retval_string NULL
104#define fetch_retval_string_size NULL 104#define fetch_retval_string_size NULL
105 105
106#define DEFINE_FETCH_memory(type) \
107__kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs, \
108 void *addr, void *dest) \
109{ \
110 type retval; \
111 if (probe_kernel_address(addr, retval)) \
112 *(type *)dest = 0; \
113 else \
114 *(type *)dest = retval; \
115}
116DEFINE_BASIC_FETCH_FUNCS(memory)
117/*
118 * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
119 * length and relative data location.
120 */
121__kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
122 void *addr, void *dest)
123{
124 long ret;
125 int maxlen = get_rloc_len(*(u32 *)dest);
126 u8 *dst = get_rloc_data(dest);
127 u8 *src = addr;
128 mm_segment_t old_fs = get_fs();
129
130 if (!maxlen)
131 return;
132
133 /*
134 * Try to get string again, since the string can be changed while
135 * probing.
136 */
137 set_fs(KERNEL_DS);
138 pagefault_disable();
139
140 do
141 ret = __copy_from_user_inatomic(dst++, src++, 1);
142 while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
143
144 dst[-1] = '\0';
145 pagefault_enable();
146 set_fs(old_fs);
147
148 if (ret < 0) { /* Failed to fetch string */
149 ((u8 *)get_rloc_data(dest))[0] = '\0';
150 *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
151 } else {
152 *(u32 *)dest = make_data_rloc(src - (u8 *)addr,
153 get_rloc_offs(*(u32 *)dest));
154 }
155}
156
157/* Return the length of string -- including null terminal byte */
158__kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
159 void *addr, void *dest)
160{
161 mm_segment_t old_fs;
162 int ret, len = 0;
163 u8 c;
164
165 old_fs = get_fs();
166 set_fs(KERNEL_DS);
167 pagefault_disable();
168
169 do {
170 ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
171 len++;
172 } while (c && ret == 0 && len < MAX_STRING_SIZE);
173
174 pagefault_enable();
175 set_fs(old_fs);
176
177 if (ret < 0) /* Failed to check the length */
178 *(u32 *)dest = 0;
179 else
180 *(u32 *)dest = len;
181}
182
183/* Dereference memory access function */ 106/* Dereference memory access function */
184struct deref_fetch_param { 107struct deref_fetch_param {
185 struct fetch_param orig; 108 struct fetch_param orig;