diff options
-rw-r--r-- | include/linux/ftrace_event.h | 1 | ||||
-rw-r--r-- | kernel/trace/trace_events_filter.c | 26 |
2 files changed, 24 insertions, 3 deletions
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index 0440bea8f6bb..ace2da9e0a0d 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -144,6 +144,7 @@ enum { | |||
144 | FILTER_OTHER = 0, | 144 | FILTER_OTHER = 0, |
145 | FILTER_STATIC_STRING, | 145 | FILTER_STATIC_STRING, |
146 | FILTER_DYN_STRING, | 146 | FILTER_DYN_STRING, |
147 | FILTER_PTR_STRING, | ||
147 | }; | 148 | }; |
148 | 149 | ||
149 | extern int trace_define_field(struct ftrace_event_call *call, | 150 | extern int trace_define_field(struct ftrace_event_call *call, |
diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 8a8e576733fc..9f03082c81d8 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c | |||
@@ -163,6 +163,20 @@ static int filter_pred_string(struct filter_pred *pred, void *event, | |||
163 | return match; | 163 | return match; |
164 | } | 164 | } |
165 | 165 | ||
166 | /* Filter predicate for char * pointers */ | ||
167 | static int filter_pred_pchar(struct filter_pred *pred, void *event, | ||
168 | int val1, int val2) | ||
169 | { | ||
170 | char **addr = (char **)(event + pred->offset); | ||
171 | int cmp, match; | ||
172 | |||
173 | cmp = strncmp(*addr, pred->str_val, pred->str_len); | ||
174 | |||
175 | match = (!cmp) ^ pred->not; | ||
176 | |||
177 | return match; | ||
178 | } | ||
179 | |||
166 | /* | 180 | /* |
167 | * Filter predicate for dynamic sized arrays of characters. | 181 | * Filter predicate for dynamic sized arrays of characters. |
168 | * These are implemented through a list of strings at the end | 182 | * These are implemented through a list of strings at the end |
@@ -489,7 +503,8 @@ int filter_assign_type(const char *type) | |||
489 | static bool is_string_field(struct ftrace_event_field *field) | 503 | static bool is_string_field(struct ftrace_event_field *field) |
490 | { | 504 | { |
491 | return field->filter_type == FILTER_DYN_STRING || | 505 | return field->filter_type == FILTER_DYN_STRING || |
492 | field->filter_type == FILTER_STATIC_STRING; | 506 | field->filter_type == FILTER_STATIC_STRING || |
507 | field->filter_type == FILTER_PTR_STRING; | ||
493 | } | 508 | } |
494 | 509 | ||
495 | static int is_legal_op(struct ftrace_event_field *field, int op) | 510 | static int is_legal_op(struct ftrace_event_field *field, int op) |
@@ -579,11 +594,16 @@ static int filter_add_pred(struct filter_parse_state *ps, | |||
579 | } | 594 | } |
580 | 595 | ||
581 | if (is_string_field(field)) { | 596 | if (is_string_field(field)) { |
597 | pred->str_len = field->size; | ||
598 | |||
582 | if (field->filter_type == FILTER_STATIC_STRING) | 599 | if (field->filter_type == FILTER_STATIC_STRING) |
583 | fn = filter_pred_string; | 600 | fn = filter_pred_string; |
584 | else | 601 | else if (field->filter_type == FILTER_DYN_STRING) |
585 | fn = filter_pred_strloc; | 602 | fn = filter_pred_strloc; |
586 | pred->str_len = field->size; | 603 | else { |
604 | fn = filter_pred_pchar; | ||
605 | pred->str_len = strlen(pred->str_val); | ||
606 | } | ||
587 | } else { | 607 | } else { |
588 | if (field->is_signed) | 608 | if (field->is_signed) |
589 | ret = strict_strtoll(pred->str_val, 0, &val); | 609 | ret = strict_strtoll(pred->str_val, 0, &val); |