فهرست منبع

tracing/probes: Add fetch{,_size} member into deref fetch method

The deref fetch methods access a memory region but it assumes that
it's a kernel memory since uprobes does not support them.

Add ->fetch and ->fetch_size member in order to provide a proper
access methods for supporting 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: Hyeoncheol Lee <cheol.lee@lge.com>
[namhyung@kernel.org: Split original patch into pieces as requested]
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Hyeoncheol Lee 12 سال پیش
والد
کامیت
3925f4a5af
1فایلهای تغییر یافته به همراه20 افزوده شده و 2 حذف شده
  1. 20 2
      kernel/trace/trace_probe.c

+ 20 - 2
kernel/trace/trace_probe.c

@@ -184,6 +184,8 @@ __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
 struct deref_fetch_param {
 struct deref_fetch_param {
 	struct fetch_param	orig;
 	struct fetch_param	orig;
 	long			offset;
 	long			offset;
+	fetch_func_t		fetch;
+	fetch_func_t		fetch_size;
 };
 };
 
 
 #define DEFINE_FETCH_deref(type)					\
 #define DEFINE_FETCH_deref(type)					\
@@ -195,13 +197,26 @@ __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,	\
 	call_fetch(&dprm->orig, regs, &addr);				\
 	call_fetch(&dprm->orig, regs, &addr);				\
 	if (addr) {							\
 	if (addr) {							\
 		addr += dprm->offset;					\
 		addr += dprm->offset;					\
-		fetch_memory_##type(regs, (void *)addr, dest);		\
+		dprm->fetch(regs, (void *)addr, dest);			\
 	} else								\
 	} else								\
 		*(type *)dest = 0;					\
 		*(type *)dest = 0;					\
 }
 }
 DEFINE_BASIC_FETCH_FUNCS(deref)
 DEFINE_BASIC_FETCH_FUNCS(deref)
 DEFINE_FETCH_deref(string)
 DEFINE_FETCH_deref(string)
-DEFINE_FETCH_deref(string_size)
+
+__kprobes void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs,
+						   void *data, void *dest)
+{
+	struct deref_fetch_param *dprm = data;
+	unsigned long addr;
+
+	call_fetch(&dprm->orig, regs, &addr);
+	if (addr && dprm->fetch_size) {
+		addr += dprm->offset;
+		dprm->fetch_size(regs, (void *)addr, dest);
+	} else
+		*(string_size *)dest = 0;
+}
 
 
 static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
 static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
 {
 {
@@ -477,6 +492,9 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
 				return -ENOMEM;
 				return -ENOMEM;
 
 
 			dprm->offset = offset;
 			dprm->offset = offset;
+			dprm->fetch = t->fetch[FETCH_MTD_memory];
+			dprm->fetch_size = get_fetch_size_function(t,
+							dprm->fetch, ftbl);
 			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return,
 			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return,
 							is_kprobe);
 							is_kprobe);
 			if (ret)
 			if (ret)