KVM: Fix order passed to iommu_unmap
[safe/jmp/linux-2.6] / kernel / trace / trace_events_filter.c
index 50504cb..57bb1bb 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ctype.h>
 #include <linux/mutex.h>
 #include <linux/perf_event.h>
+#include <linux/slab.h>
 
 #include "trace.h"
 #include "trace_output.h"
@@ -211,8 +212,9 @@ static int filter_pred_pchar(struct filter_pred *pred, void *event,
 {
        char **addr = (char **)(event + pred->offset);
        int cmp, match;
+       int len = strlen(*addr) + 1;    /* including tailing '\0' */
 
-       cmp = pred->regex.match(*addr, &pred->regex, pred->regex.field_len);
+       cmp = pred->regex.match(*addr, &pred->regex, len);
 
        match = cmp ^ pred->not;
 
@@ -251,7 +253,18 @@ static int filter_pred_none(struct filter_pred *pred, void *event,
        return 0;
 }
 
-/* Basic regex callbacks */
+/*
+ * regex_match_foo - Basic regex callbacks
+ *
+ * @str: the string to be searched
+ * @r:   the regex structure containing the pattern string
+ * @len: the length of the string to be searched (including '\0')
+ *
+ * Note:
+ * - @str might not be NULL-terminated if it's of type DYN_STRING
+ *   or STATIC_STRING
+ */
+
 static int regex_match_full(char *str, struct regex *r, int len)
 {
        if (strncmp(str, r->pattern, len) == 0)
@@ -261,23 +274,24 @@ static int regex_match_full(char *str, struct regex *r, int len)
 
 static int regex_match_front(char *str, struct regex *r, int len)
 {
-       if (strncmp(str, r->pattern, len) == 0)
+       if (strncmp(str, r->pattern, r->len) == 0)
                return 1;
        return 0;
 }
 
 static int regex_match_middle(char *str, struct regex *r, int len)
 {
-       if (strstr(str, r->pattern))
+       if (strnstr(str, r->pattern, len))
                return 1;
        return 0;
 }
 
 static int regex_match_end(char *str, struct regex *r, int len)
 {
-       char *ptr = strstr(str, r->pattern);
+       int strlen = len - 1;
 
-       if (ptr && (ptr[r->len] == 0))
+       if (strlen >= r->len &&
+           memcmp(str + strlen - r->len, r->pattern, r->len) == 0)
                return 1;
        return 0;
 }
@@ -486,8 +500,10 @@ static struct ftrace_event_field *
 find_event_field(struct ftrace_event_call *call, char *name)
 {
        struct ftrace_event_field *field;
+       struct list_head *head;
 
-       list_for_each_entry(field, &call->fields, link) {
+       head = trace_get_fields(call);
+       list_for_each_entry(field, head, link) {
                if (!strcmp(field->name, name))
                        return field;
        }
@@ -531,7 +547,7 @@ static void filter_disable_preds(struct ftrace_event_call *call)
        struct event_filter *filter = call->filter;
        int i;
 
-       call->filter_active = 0;
+       call->flags &= ~TRACE_EVENT_FL_FILTERED;
        filter->n_preds = 0;
 
        for (i = 0; i < MAX_FILTER_PRED; i++)
@@ -558,7 +574,7 @@ void destroy_preds(struct ftrace_event_call *call)
 {
        __free_preds(call->filter);
        call->filter = NULL;
-       call->filter_active = 0;
+       call->flags &= ~TRACE_EVENT_FL_FILTERED;
 }
 
 static struct event_filter *__alloc_preds(void)
@@ -597,7 +613,7 @@ static int init_preds(struct ftrace_event_call *call)
        if (call->filter)
                return 0;
 
-       call->filter_active = 0;
+       call->flags &= ~TRACE_EVENT_FL_FILTERED;
        call->filter = __alloc_preds();
        if (IS_ERR(call->filter))
                return PTR_ERR(call->filter);
@@ -611,10 +627,10 @@ static int init_subsystem_preds(struct event_subsystem *system)
        int err;
 
        list_for_each_entry(call, &ftrace_events, list) {
-               if (!call->define_fields)
+               if (!call->class || !call->class->define_fields)
                        continue;
 
-               if (strcmp(call->system, system->name) != 0)
+               if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
                err = init_preds(call);
@@ -630,10 +646,10 @@ static void filter_free_subsystem_preds(struct event_subsystem *system)
        struct ftrace_event_call *call;
 
        list_for_each_entry(call, &ftrace_events, list) {
-               if (!call->define_fields)
+               if (!call->class || !call->class->define_fields)
                        continue;
 
-               if (strcmp(call->system, system->name) != 0)
+               if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
                filter_disable_preds(call);
@@ -781,10 +797,8 @@ static int filter_add_pred(struct filter_parse_state *ps,
                        pred->regex.field_len = field->size;
                } else if (field->filter_type == FILTER_DYN_STRING)
                        fn = filter_pred_strloc;
-               else {
+               else
                        fn = filter_pred_pchar;
-                       pred->regex.field_len = strlen(pred->regex.pattern);
-               }
        } else {
                if (field->is_signed)
                        ret = strict_strtoll(pred->regex.pattern, 0, &val);
@@ -1237,10 +1251,10 @@ static int replace_system_preds(struct event_subsystem *system,
        list_for_each_entry(call, &ftrace_events, list) {
                struct event_filter *filter = call->filter;
 
-               if (!call->define_fields)
+               if (!call->class || !call->class->define_fields)
                        continue;
 
-               if (strcmp(call->system, system->name) != 0)
+               if (strcmp(call->class->system, system->name) != 0)
                        continue;
 
                /* try to see if the filter can be applied */
@@ -1254,7 +1268,7 @@ static int replace_system_preds(struct event_subsystem *system,
                if (err)
                        filter_disable_preds(call);
                else {
-                       call->filter_active = 1;
+                       call->flags |= TRACE_EVENT_FL_FILTERED;
                        replace_filter_string(filter, filter_string);
                }
                fail = false;
@@ -1303,7 +1317,7 @@ int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
        if (err)
                append_filter_err(ps, call->filter);
        else
-               call->filter_active = 1;
+               call->flags |= TRACE_EVENT_FL_FILTERED;
 out:
        filter_opstack_clear(ps);
        postfix_clear(ps);
@@ -1360,7 +1374,7 @@ out_unlock:
        return err;
 }
 
-#ifdef CONFIG_EVENT_PROFILE
+#ifdef CONFIG_PERF_EVENTS
 
 void ftrace_profile_free_filter(struct perf_event *event)
 {
@@ -1381,12 +1395,12 @@ int ftrace_profile_set_filter(struct perf_event *event, int event_id,
        mutex_lock(&event_mutex);
 
        list_for_each_entry(call, &ftrace_events, list) {
-               if (call->id == event_id)
+               if (call->event.type == event_id)
                        break;
        }
 
        err = -EINVAL;
-       if (!call)
+       if (&call->list == &ftrace_events)
                goto out_unlock;
 
        err = -EEXIST;
@@ -1428,5 +1442,5 @@ out_unlock:
        return err;
 }
 
-#endif /* CONFIG_EVENT_PROFILE */
+#endif /* CONFIG_PERF_EVENTS */