From: Jason Baron <jbaron@redhat.com>
To: linux-kernel@vger.kernel.org, laijs@cn.fujitsu.com,
lizf@cn.fujitsu.com, rostedt@goodmis.org, fweisbec@gmail.com,
mingo@elte.hu, hpa@zytor.com, tglx@linutronix.de,
mhiramat@redhat.com
Subject: [PATCH 4/6] tracing: add tracing support for compat syscalls
Date: Tue, 2 Feb 2010 16:21:51 -0500 [thread overview]
Message-ID: <bec426992cb9ab8f8abe07efb2baa785577a3855.1265142153.git.jbaron@redhat.com> (raw)
In-Reply-To: <cover.1265142153.git.jbaron@redhat.com>
Add core support to event tracing for compat syscalls. The basic idea is that we
check if we have a compat task via 'is_compat_task()'. If so, we lookup in the
new compat_syscalls_metadata table, the corresponding struct syscall_metadata, to
check syscall arguments and whether or not we are enabled.
Signed-off-by: Jason Baron <jbaron@redhat.com>
---
include/linux/compat.h | 8 +++++
include/trace/syscall.h | 4 ++
kernel/trace/trace.h | 2 +
kernel/trace/trace_syscalls.c | 63 +++++++++++++++++++++++++++++++++++-----
4 files changed, 69 insertions(+), 8 deletions(-)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index ef68119..ab2cda2 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -353,5 +353,13 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
int flags, int mode);
+#else /* CONFIG_COMPAT */
+
+#define NR_syscalls_compat 0
+static inline int is_compat_task(void)
+{
+ return 0;
+}
+
#endif /* CONFIG_COMPAT */
#endif /* _LINUX_COMPAT_H */
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 8f5ac38..1cc1d1e 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -22,6 +22,7 @@
struct syscall_metadata {
const char *name;
int syscall_nr;
+ int compat_syscall_nr;
int nb_args;
const char **types;
const char **args;
@@ -36,6 +37,9 @@ struct syscall_metadata {
#ifdef CONFIG_FTRACE_SYSCALLS
extern unsigned long arch_syscall_addr(int nr);
+#ifdef CONFIG_COMPAT
+extern unsigned long arch_compat_syscall_addr(int nr);
+#endif
extern int init_syscall_trace(struct ftrace_event_call *call);
extern int syscall_enter_define_fields(struct ftrace_event_call *call);
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index ce077fb..0ed0d2e 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -94,12 +94,14 @@ extern struct tracer boot_tracer;
struct syscall_trace_enter {
struct trace_entry ent;
int nr;
+ int compat;
unsigned long args[];
};
struct syscall_trace_exit {
struct trace_entry ent;
int nr;
+ int compat;
long ret;
};
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index 8411d6c..6f721be 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -3,6 +3,7 @@
#include <linux/kernel.h>
#include <linux/ftrace.h>
#include <linux/perf_event.h>
+#include <linux/compat.h>
#include <asm/syscall.h>
#include "trace_output.h"
@@ -16,6 +17,7 @@ extern unsigned long __start_syscalls_metadata[];
extern unsigned long __stop_syscalls_metadata[];
static struct syscall_metadata **syscalls_metadata;
+static struct syscall_metadata **compat_syscalls_metadata;
static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
{
@@ -41,8 +43,14 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
return NULL;
}
-static struct syscall_metadata *syscall_nr_to_meta(int nr)
+static struct syscall_metadata *syscall_nr_to_meta(int nr, int compat)
{
+ if (compat) {
+ if (!compat_syscalls_metadata || nr >= NR_syscalls_compat ||
+ nr < 0)
+ return NULL;
+ return compat_syscalls_metadata[nr];
+ }
if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
return NULL;
@@ -60,7 +68,7 @@ print_syscall_enter(struct trace_iterator *iter, int flags)
trace = (typeof(trace))ent;
syscall = trace->nr;
- entry = syscall_nr_to_meta(syscall);
+ entry = syscall_nr_to_meta(syscall, trace->compat);
if (!entry)
goto end;
@@ -113,7 +121,7 @@ print_syscall_exit(struct trace_iterator *iter, int flags)
trace = (typeof(trace))ent;
syscall = trace->nr;
- entry = syscall_nr_to_meta(syscall);
+ entry = syscall_nr_to_meta(syscall, trace->compat);
if (!entry) {
trace_seq_printf(s, "\n");
@@ -248,12 +256,16 @@ void ftrace_syscall_enter(struct pt_regs *regs, long id)
struct ring_buffer *buffer;
int size;
int syscall_nr;
+ int compat = 0;
syscall_nr = syscall_get_nr(current, regs);
if (syscall_nr < 0)
return;
- sys_data = syscall_nr_to_meta(syscall_nr);
+ if (is_compat_task())
+ compat = 1;
+
+ sys_data = syscall_nr_to_meta(syscall_nr, compat);
if (!sys_data)
return;
@@ -269,6 +281,7 @@ void ftrace_syscall_enter(struct pt_regs *regs, long id)
entry = ring_buffer_event_data(event);
entry->nr = syscall_nr;
+ entry->compat = compat;
syscall_get_arguments(current, regs, 0, sys_data->nb_args, entry->args);
if (!filter_current_check_discard(buffer, sys_data->enter_event,
@@ -283,12 +296,16 @@ void ftrace_syscall_exit(struct pt_regs *regs, long ret)
struct ring_buffer_event *event;
struct ring_buffer *buffer;
int syscall_nr;
+ int compat = 0;
syscall_nr = syscall_get_nr(current, regs);
if (syscall_nr < 0)
return;
- sys_data = syscall_nr_to_meta(syscall_nr);
+ if (is_compat_task())
+ compat = 1;
+
+ sys_data = syscall_nr_to_meta(syscall_nr, compat);
if (!sys_data)
return;
@@ -302,6 +319,7 @@ void ftrace_syscall_exit(struct pt_regs *regs, long ret)
entry = ring_buffer_event_data(event);
entry->nr = syscall_nr;
+ entry->compat = compat;
entry->ret = syscall_get_return_value(current, regs);
if (!filter_current_check_discard(buffer, sys_data->exit_event,
@@ -416,7 +434,26 @@ int __init init_ftrace_syscalls(void)
meta->syscall_nr = i;
syscalls_metadata[i] = meta;
}
-
+#ifdef CONFIG_COMPAT
+ if (NR_syscalls_compat) {
+ compat_syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
+ NR_syscalls_compat, GFP_KERNEL);
+ if (!compat_syscalls_metadata) {
+ WARN_ON(1);
+ kfree(syscalls_metadata);
+ return -ENOMEM;
+ }
+ for (i = 0; i < NR_syscalls_compat; i++) {
+ addr = arch_compat_syscall_addr(i);
+ meta = find_syscall_meta(addr);
+ if (!meta)
+ continue;
+
+ meta->compat_syscall_nr = i;
+ compat_syscalls_metadata[i] = meta;
+ }
+ }
+#endif
return 0;
}
core_initcall(init_ftrace_syscalls);
@@ -434,9 +471,13 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
int syscall_nr;
int rctx;
int size;
+ int compat = 0;
syscall_nr = syscall_get_nr(current, regs);
- sys_data = syscall_nr_to_meta(syscall_nr);
+ if (is_compat_task())
+ compat = 1;
+
+ sys_data = syscall_nr_to_meta(syscall_nr, compat);
if (!sys_data)
return;
@@ -458,6 +499,7 @@ static void prof_syscall_enter(struct pt_regs *regs, long id)
return;
rec->nr = syscall_nr;
+ rec->compat = compat;
syscall_get_arguments(current, regs, 0, sys_data->nb_args,
(unsigned long *)&rec->args);
ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags);
@@ -506,9 +548,13 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
int syscall_nr;
int rctx;
int size;
+ int compat = 0;
syscall_nr = syscall_get_nr(current, regs);
- sys_data = syscall_nr_to_meta(syscall_nr);
+ if (is_compat_task())
+ compat = 1;
+
+ sys_data = syscall_nr_to_meta(syscall_nr, compat);
if (!sys_data)
return;
@@ -533,6 +579,7 @@ static void prof_syscall_exit(struct pt_regs *regs, long ret)
return;
rec->nr = syscall_nr;
+ rec->compat = compat;
rec->ret = syscall_get_return_value(current, regs);
ftrace_perf_buf_submit(rec, size, rctx, 0, 1, flags);
--
1.6.5.1
next prev parent reply other threads:[~2010-02-02 21:22 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-02 21:21 [PATCH 0/6] tracing: add compat syscall support Jason Baron
2010-02-02 21:21 ` [PATCH 1/6] x86: add NR_syscalls_compat, make ia32 syscall table visible Jason Baron
2010-02-02 21:21 ` [PATCH 2/6] x86: add arch_compat_syscall_addr() Jason Baron
2010-02-02 21:21 ` [PATCH 3/6] tracing: remove syscall bitmaps in preparation for compat support Jason Baron
2010-02-02 21:21 ` Jason Baron [this message]
2010-02-03 12:52 ` [PATCH 4/6] tracing: add tracing support for compat syscalls Heiko Carstens
2010-02-08 15:43 ` Jason Baron
2010-02-08 16:34 ` Heiko Carstens
2010-02-09 10:21 ` Heiko Carstens
2010-02-09 14:54 ` Jason Baron
2010-02-02 21:21 ` [PATCH 5/6] syscalls: add define syscall prefix macro Jason Baron
2010-02-03 13:01 ` Heiko Carstens
2010-02-08 15:48 ` Jason Baron
2010-02-08 16:12 ` Arnd Bergmann
2010-02-08 17:54 ` Christoph Hellwig
2010-02-08 20:48 ` Arnd Bergmann
2010-02-08 16:53 ` Randy Dunlap
2010-02-08 17:11 ` Jason Baron
2010-02-10 3:00 ` Steven Rostedt
2010-02-02 21:22 ` [PATCH 6/6] x86: convert compat syscalls to use 'DEFINE_SYSCALL()' macros Jason Baron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bec426992cb9ab8f8abe07efb2baa785577a3855.1265142153.git.jbaron@redhat.com \
--to=jbaron@redhat.com \
--cc=fweisbec@gmail.com \
--cc=hpa@zytor.com \
--cc=laijs@cn.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lizf@cn.fujitsu.com \
--cc=mhiramat@redhat.com \
--cc=mingo@elte.hu \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®