diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2008-10-01 10:52:51 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-14 04:39:07 -0400 |
commit | 7104f300c5a69b46dda00d898034dd05c9f21739 (patch) | |
tree | a8c885bd61fb1e269f277837b2e521179faf8739 /kernel/trace/trace_mmiotrace.c | |
parent | 797d3712a9dd75c720558612be05f42c031a7bb5 (diff) |
ftrace: type cast filter+verifier
The mmiotrace map had a bug that would typecast the entry from
the trace to the wrong type. That is a known danger of C typecasts,
there's absolutely zero checking done on them.
Help that problem a bit by using a GCC extension to implement a
type filter that restricts the types that a trace record can be
cast into, and by adding a dynamic check (in debug mode) to verify
the type of the entry.
This patch adds a macro to assign all entries of ftrace using the type
of the variable and checking the entry id. The typecasts are now done
in the macro for only those types that it knows about, which should
be all the types that are allowed to be read from the tracer.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/trace/trace_mmiotrace.c')
-rw-r--r-- | kernel/trace/trace_mmiotrace.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 1a266aa08e1a..0e819f47bb7a 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c | |||
@@ -178,15 +178,17 @@ print_out: | |||
178 | static enum print_line_t mmio_print_rw(struct trace_iterator *iter) | 178 | static enum print_line_t mmio_print_rw(struct trace_iterator *iter) |
179 | { | 179 | { |
180 | struct trace_entry *entry = iter->ent; | 180 | struct trace_entry *entry = iter->ent; |
181 | struct trace_mmiotrace_rw *field = | 181 | struct trace_mmiotrace_rw *field; |
182 | (struct trace_mmiotrace_rw *)entry; | 182 | struct mmiotrace_rw *rw; |
183 | struct mmiotrace_rw *rw = &field->rw; | ||
184 | struct trace_seq *s = &iter->seq; | 183 | struct trace_seq *s = &iter->seq; |
185 | unsigned long long t = ns2usecs(iter->ts); | 184 | unsigned long long t = ns2usecs(iter->ts); |
186 | unsigned long usec_rem = do_div(t, 1000000ULL); | 185 | unsigned long usec_rem = do_div(t, 1000000ULL); |
187 | unsigned secs = (unsigned long)t; | 186 | unsigned secs = (unsigned long)t; |
188 | int ret = 1; | 187 | int ret = 1; |
189 | 188 | ||
189 | trace_assign_type(field, entry); | ||
190 | rw = &field->rw; | ||
191 | |||
190 | switch (rw->opcode) { | 192 | switch (rw->opcode) { |
191 | case MMIO_READ: | 193 | case MMIO_READ: |
192 | ret = trace_seq_printf(s, | 194 | ret = trace_seq_printf(s, |
@@ -222,13 +224,17 @@ static enum print_line_t mmio_print_rw(struct trace_iterator *iter) | |||
222 | static enum print_line_t mmio_print_map(struct trace_iterator *iter) | 224 | static enum print_line_t mmio_print_map(struct trace_iterator *iter) |
223 | { | 225 | { |
224 | struct trace_entry *entry = iter->ent; | 226 | struct trace_entry *entry = iter->ent; |
225 | struct mmiotrace_map *m = (struct mmiotrace_map *)entry; | 227 | struct trace_mmiotrace_map *field; |
228 | struct mmiotrace_map *m; | ||
226 | struct trace_seq *s = &iter->seq; | 229 | struct trace_seq *s = &iter->seq; |
227 | unsigned long long t = ns2usecs(iter->ts); | 230 | unsigned long long t = ns2usecs(iter->ts); |
228 | unsigned long usec_rem = do_div(t, 1000000ULL); | 231 | unsigned long usec_rem = do_div(t, 1000000ULL); |
229 | unsigned secs = (unsigned long)t; | 232 | unsigned secs = (unsigned long)t; |
230 | int ret; | 233 | int ret; |
231 | 234 | ||
235 | trace_assign_type(field, entry); | ||
236 | m = &field->map; | ||
237 | |||
232 | switch (m->opcode) { | 238 | switch (m->opcode) { |
233 | case MMIO_PROBE: | 239 | case MMIO_PROBE: |
234 | ret = trace_seq_printf(s, | 240 | ret = trace_seq_printf(s, |