aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_mmiotrace.c
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-10-01 10:52:51 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-14 04:39:07 -0400
commit7104f300c5a69b46dda00d898034dd05c9f21739 (patch)
treea8c885bd61fb1e269f277837b2e521179faf8739 /kernel/trace/trace_mmiotrace.c
parent797d3712a9dd75c720558612be05f42c031a7bb5 (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.c14
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:
178static enum print_line_t mmio_print_rw(struct trace_iterator *iter) 178static 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)
222static enum print_line_t mmio_print_map(struct trace_iterator *iter) 224static 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,