]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - kernel/trace/trace_events_filter.c
tracing/filter: Optimize short ciruit check
[mirror_ubuntu-hirsute-kernel.git] / kernel / trace / trace_events_filter.c
CommitLineData
7ce7e424
TZ
1/*
2 * trace_events_filter - generic event filtering
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) 2009 Tom Zanussi <tzanussi@gmail.com>
19 */
20
7ce7e424
TZ
21#include <linux/module.h>
22#include <linux/ctype.h>
ac1adc55 23#include <linux/mutex.h>
6fb2915d 24#include <linux/perf_event.h>
5a0e3ad6 25#include <linux/slab.h>
7ce7e424
TZ
26
27#include "trace.h"
4bda2d51 28#include "trace_output.h"
7ce7e424 29
8b372562 30enum filter_op_ids
7ce7e424 31{
8b372562
TZ
32 OP_OR,
33 OP_AND,
b0f1a59a 34 OP_GLOB,
8b372562
TZ
35 OP_NE,
36 OP_EQ,
37 OP_LT,
38 OP_LE,
39 OP_GT,
40 OP_GE,
41 OP_NONE,
42 OP_OPEN_PAREN,
43};
44
45struct filter_op {
46 int id;
47 char *string;
48 int precedence;
49};
50
51static struct filter_op filter_ops[] = {
b0f1a59a
LZ
52 { OP_OR, "||", 1 },
53 { OP_AND, "&&", 2 },
54 { OP_GLOB, "~", 4 },
55 { OP_NE, "!=", 4 },
56 { OP_EQ, "==", 4 },
57 { OP_LT, "<", 5 },
58 { OP_LE, "<=", 5 },
59 { OP_GT, ">", 5 },
60 { OP_GE, ">=", 5 },
61 { OP_NONE, "OP_NONE", 0 },
62 { OP_OPEN_PAREN, "(", 0 },
8b372562
TZ
63};
64
65enum {
66 FILT_ERR_NONE,
67 FILT_ERR_INVALID_OP,
68 FILT_ERR_UNBALANCED_PAREN,
69 FILT_ERR_TOO_MANY_OPERANDS,
70 FILT_ERR_OPERAND_TOO_LONG,
71 FILT_ERR_FIELD_NOT_FOUND,
72 FILT_ERR_ILLEGAL_FIELD_OP,
73 FILT_ERR_ILLEGAL_INTVAL,
74 FILT_ERR_BAD_SUBSYS_FILTER,
75 FILT_ERR_TOO_MANY_PREDS,
76 FILT_ERR_MISSING_FIELD,
77 FILT_ERR_INVALID_FILTER,
78};
79
80static char *err_text[] = {
81 "No error",
82 "Invalid operator",
83 "Unbalanced parens",
84 "Too many operands",
85 "Operand too long",
86 "Field not found",
87 "Illegal operation for field type",
88 "Illegal integer value",
89 "Couldn't find or set field in one of a subsystem's events",
90 "Too many terms in predicate expression",
91 "Missing field name and/or value",
92 "Meaningless filter expression",
93};
94
95struct opstack_op {
96 int op;
97 struct list_head list;
98};
99
100struct postfix_elt {
101 int op;
102 char *operand;
103 struct list_head list;
104};
105
106struct filter_parse_state {
107 struct filter_op *ops;
108 struct list_head opstack;
109 struct list_head postfix;
110 int lasterr;
111 int lasterr_pos;
112
113 struct {
114 char *string;
115 unsigned int cnt;
116 unsigned int tail;
117 } infix;
118
119 struct {
120 char string[MAX_FILTER_STR_VAL];
121 int pos;
122 unsigned int tail;
123 } operand;
124};
125
61e9dea2
SR
126struct pred_stack {
127 struct filter_pred **preds;
128 int index;
129};
130
197e2eab 131#define DEFINE_COMPARISON_PRED(type) \
58d9a597 132static int filter_pred_##type(struct filter_pred *pred, void *event) \
197e2eab
LZ
133{ \
134 type *addr = (type *)(event + pred->offset); \
135 type val = (type)pred->val; \
136 int match = 0; \
137 \
138 switch (pred->op) { \
139 case OP_LT: \
140 match = (*addr < val); \
141 break; \
142 case OP_LE: \
143 match = (*addr <= val); \
144 break; \
145 case OP_GT: \
146 match = (*addr > val); \
147 break; \
148 case OP_GE: \
149 match = (*addr >= val); \
150 break; \
151 default: \
152 break; \
153 } \
154 \
155 return match; \
156}
157
158#define DEFINE_EQUALITY_PRED(size) \
58d9a597 159static int filter_pred_##size(struct filter_pred *pred, void *event) \
197e2eab
LZ
160{ \
161 u##size *addr = (u##size *)(event + pred->offset); \
162 u##size val = (u##size)pred->val; \
163 int match; \
164 \
165 match = (val == *addr) ^ pred->not; \
166 \
167 return match; \
168}
169
8b372562
TZ
170DEFINE_COMPARISON_PRED(s64);
171DEFINE_COMPARISON_PRED(u64);
172DEFINE_COMPARISON_PRED(s32);
173DEFINE_COMPARISON_PRED(u32);
174DEFINE_COMPARISON_PRED(s16);
175DEFINE_COMPARISON_PRED(u16);
176DEFINE_COMPARISON_PRED(s8);
177DEFINE_COMPARISON_PRED(u8);
178
179DEFINE_EQUALITY_PRED(64);
180DEFINE_EQUALITY_PRED(32);
181DEFINE_EQUALITY_PRED(16);
182DEFINE_EQUALITY_PRED(8);
183
e8808c10 184/* Filter predicate for fixed sized arrays of characters */
58d9a597 185static int filter_pred_string(struct filter_pred *pred, void *event)
7ce7e424
TZ
186{
187 char *addr = (char *)(event + pred->offset);
188 int cmp, match;
189
1889d209 190 cmp = pred->regex.match(addr, &pred->regex, pred->regex.field_len);
7ce7e424 191
1889d209 192 match = cmp ^ pred->not;
7ce7e424
TZ
193
194 return match;
195}
196
87a342f5 197/* Filter predicate for char * pointers */
58d9a597 198static int filter_pred_pchar(struct filter_pred *pred, void *event)
87a342f5
LZ
199{
200 char **addr = (char **)(event + pred->offset);
201 int cmp, match;
16da27a8 202 int len = strlen(*addr) + 1; /* including tailing '\0' */
87a342f5 203
16da27a8 204 cmp = pred->regex.match(*addr, &pred->regex, len);
87a342f5 205
1889d209 206 match = cmp ^ pred->not;
87a342f5
LZ
207
208 return match;
209}
210
e8808c10
FW
211/*
212 * Filter predicate for dynamic sized arrays of characters.
213 * These are implemented through a list of strings at the end
214 * of the entry.
215 * Also each of these strings have a field in the entry which
216 * contains its offset from the beginning of the entry.
217 * We have then first to get this field, dereference it
218 * and add it to the address of the entry, and at last we have
219 * the address of the string.
220 */
58d9a597 221static int filter_pred_strloc(struct filter_pred *pred, void *event)
e8808c10 222{
7d536cb3
LZ
223 u32 str_item = *(u32 *)(event + pred->offset);
224 int str_loc = str_item & 0xffff;
225 int str_len = str_item >> 16;
e8808c10
FW
226 char *addr = (char *)(event + str_loc);
227 int cmp, match;
228
1889d209 229 cmp = pred->regex.match(addr, &pred->regex, str_len);
e8808c10 230
1889d209 231 match = cmp ^ pred->not;
e8808c10
FW
232
233 return match;
234}
235
58d9a597 236static int filter_pred_none(struct filter_pred *pred, void *event)
0a19e53c
TZ
237{
238 return 0;
239}
240
d1303dd1
LZ
241/*
242 * regex_match_foo - Basic regex callbacks
243 *
244 * @str: the string to be searched
245 * @r: the regex structure containing the pattern string
246 * @len: the length of the string to be searched (including '\0')
247 *
248 * Note:
249 * - @str might not be NULL-terminated if it's of type DYN_STRING
250 * or STATIC_STRING
251 */
252
1889d209
FW
253static int regex_match_full(char *str, struct regex *r, int len)
254{
255 if (strncmp(str, r->pattern, len) == 0)
256 return 1;
257 return 0;
258}
259
260static int regex_match_front(char *str, struct regex *r, int len)
261{
285caad4 262 if (strncmp(str, r->pattern, r->len) == 0)
1889d209
FW
263 return 1;
264 return 0;
265}
266
267static int regex_match_middle(char *str, struct regex *r, int len)
268{
b2af211f 269 if (strnstr(str, r->pattern, len))
1889d209
FW
270 return 1;
271 return 0;
272}
273
274static int regex_match_end(char *str, struct regex *r, int len)
275{
a3291c14 276 int strlen = len - 1;
1889d209 277
a3291c14
LZ
278 if (strlen >= r->len &&
279 memcmp(str + strlen - r->len, r->pattern, r->len) == 0)
1889d209
FW
280 return 1;
281 return 0;
282}
283
3f6fe06d
FW
284/**
285 * filter_parse_regex - parse a basic regex
286 * @buff: the raw regex
287 * @len: length of the regex
288 * @search: will point to the beginning of the string to compare
289 * @not: tell whether the match will have to be inverted
290 *
291 * This passes in a buffer containing a regex and this function will
1889d209
FW
292 * set search to point to the search part of the buffer and
293 * return the type of search it is (see enum above).
294 * This does modify buff.
295 *
296 * Returns enum type.
297 * search returns the pointer to use for comparison.
298 * not returns 1 if buff started with a '!'
299 * 0 otherwise.
300 */
3f6fe06d 301enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
1889d209
FW
302{
303 int type = MATCH_FULL;
304 int i;
305
306 if (buff[0] == '!') {
307 *not = 1;
308 buff++;
309 len--;
310 } else
311 *not = 0;
312
313 *search = buff;
314
315 for (i = 0; i < len; i++) {
316 if (buff[i] == '*') {
317 if (!i) {
318 *search = buff + 1;
319 type = MATCH_END_ONLY;
320 } else {
321 if (type == MATCH_END_ONLY)
322 type = MATCH_MIDDLE_ONLY;
323 else
324 type = MATCH_FRONT_ONLY;
325 buff[i] = 0;
326 break;
327 }
328 }
329 }
330
331 return type;
332}
333
b0f1a59a 334static void filter_build_regex(struct filter_pred *pred)
1889d209
FW
335{
336 struct regex *r = &pred->regex;
b0f1a59a
LZ
337 char *search;
338 enum regex_type type = MATCH_FULL;
339 int not = 0;
340
341 if (pred->op == OP_GLOB) {
342 type = filter_parse_regex(r->pattern, r->len, &search, &not);
343 r->len = strlen(search);
344 memmove(r->pattern, search, r->len+1);
345 }
1889d209
FW
346
347 switch (type) {
348 case MATCH_FULL:
349 r->match = regex_match_full;
350 break;
351 case MATCH_FRONT_ONLY:
352 r->match = regex_match_front;
353 break;
354 case MATCH_MIDDLE_ONLY:
355 r->match = regex_match_middle;
356 break;
357 case MATCH_END_ONLY:
358 r->match = regex_match_end;
359 break;
360 }
361
362 pred->not ^= not;
1889d209
FW
363}
364
61e9dea2
SR
365enum move_type {
366 MOVE_DOWN,
367 MOVE_UP_FROM_LEFT,
368 MOVE_UP_FROM_RIGHT
369};
370
371static struct filter_pred *
372get_pred_parent(struct filter_pred *pred, struct filter_pred *preds,
373 int index, enum move_type *move)
374{
375 if (pred->parent & FILTER_PRED_IS_RIGHT)
376 *move = MOVE_UP_FROM_RIGHT;
377 else
378 *move = MOVE_UP_FROM_LEFT;
379 pred = &preds[pred->parent & ~FILTER_PRED_IS_RIGHT];
380
381 return pred;
382}
383
7ce7e424 384/* return 1 if event matches, 0 otherwise (discard) */
6fb2915d 385int filter_match_preds(struct event_filter *filter, void *rec)
7ce7e424 386{
61e9dea2
SR
387 int match = -1;
388 enum move_type move = MOVE_DOWN;
74e9e58c 389 struct filter_pred *preds;
7ce7e424 390 struct filter_pred *pred;
61e9dea2 391 struct filter_pred *root;
6d54057d 392 int n_preds = ACCESS_ONCE(filter->n_preds);
61e9dea2 393 int done = 0;
7ce7e424 394
6d54057d
SR
395 /* no filter is considered a match */
396 if (!n_preds)
397 return 1;
398
c9c53ca0 399 /*
61e9dea2 400 * n_preds, root and filter->preds are protect with preemption disabled.
c9c53ca0
SR
401 */
402 preds = rcu_dereference_sched(filter->preds);
61e9dea2
SR
403 root = rcu_dereference_sched(filter->root);
404 if (!root)
405 return 1;
c9c53ca0 406
61e9dea2
SR
407 pred = root;
408
409 /* match is currently meaningless */
410 match = -1;
411
412 do {
413 switch (move) {
414 case MOVE_DOWN:
415 /* only AND and OR have children */
416 if (pred->left != FILTER_PRED_INVALID) {
417 /* keep going to leaf node */
418 pred = &preds[pred->left];
419 continue;
420 }
58d9a597 421 match = pred->fn(pred, rec);
61e9dea2
SR
422 /* If this pred is the only pred */
423 if (pred == root)
424 break;
425 pred = get_pred_parent(pred, preds,
426 pred->parent, &move);
427 continue;
428 case MOVE_UP_FROM_LEFT:
55719274
SR
429 /*
430 * Check for short circuits.
431 *
432 * Optimization: !!match == (pred->op == OP_OR)
433 * is the same as:
434 * if ((match && pred->op == OP_OR) ||
435 * (!match && pred->op == OP_AND))
436 */
437 if (!!match == (pred->op == OP_OR)) {
61e9dea2
SR
438 if (pred == root)
439 break;
440 pred = get_pred_parent(pred, preds,
441 pred->parent, &move);
442 continue;
443 }
444 /* now go down the right side of the tree. */
445 pred = &preds[pred->right];
446 move = MOVE_DOWN;
447 continue;
448 case MOVE_UP_FROM_RIGHT:
449 /* We finished this equation. */
450 if (pred == root)
451 break;
452 pred = get_pred_parent(pred, preds,
453 pred->parent, &move);
0a19e53c 454 continue;
8b372562 455 }
61e9dea2
SR
456 done = 1;
457 } while (!done);
7ce7e424 458
61e9dea2 459 return match;
7ce7e424 460}
17c873ec 461EXPORT_SYMBOL_GPL(filter_match_preds);
7ce7e424 462
8b372562 463static void parse_error(struct filter_parse_state *ps, int err, int pos)
7ce7e424 464{
8b372562
TZ
465 ps->lasterr = err;
466 ps->lasterr_pos = pos;
467}
7ce7e424 468
8b372562
TZ
469static void remove_filter_string(struct event_filter *filter)
470{
471 kfree(filter->filter_string);
472 filter->filter_string = NULL;
473}
474
475static int replace_filter_string(struct event_filter *filter,
476 char *filter_string)
477{
478 kfree(filter->filter_string);
479 filter->filter_string = kstrdup(filter_string, GFP_KERNEL);
480 if (!filter->filter_string)
481 return -ENOMEM;
482
483 return 0;
484}
485
486static int append_filter_string(struct event_filter *filter,
487 char *string)
488{
489 int newlen;
490 char *new_filter_string;
491
492 BUG_ON(!filter->filter_string);
493 newlen = strlen(filter->filter_string) + strlen(string) + 1;
494 new_filter_string = kmalloc(newlen, GFP_KERNEL);
495 if (!new_filter_string)
496 return -ENOMEM;
497
498 strcpy(new_filter_string, filter->filter_string);
499 strcat(new_filter_string, string);
500 kfree(filter->filter_string);
501 filter->filter_string = new_filter_string;
502
503 return 0;
504}
505
506static void append_filter_err(struct filter_parse_state *ps,
507 struct event_filter *filter)
508{
509 int pos = ps->lasterr_pos;
510 char *buf, *pbuf;
511
512 buf = (char *)__get_free_page(GFP_TEMPORARY);
513 if (!buf)
4bda2d51 514 return;
7ce7e424 515
8b372562
TZ
516 append_filter_string(filter, "\n");
517 memset(buf, ' ', PAGE_SIZE);
518 if (pos > PAGE_SIZE - 128)
519 pos = 0;
520 buf[pos] = '^';
521 pbuf = &buf[pos] + 1;
522
523 sprintf(pbuf, "\nparse_error: %s\n", err_text[ps->lasterr]);
524 append_filter_string(filter, buf);
525 free_page((unsigned long) buf);
7ce7e424
TZ
526}
527
8b372562 528void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
ac1adc55 529{
8b372562
TZ
530 struct event_filter *filter = call->filter;
531
00e95830 532 mutex_lock(&event_mutex);
8e254c1d 533 if (filter && filter->filter_string)
8b372562
TZ
534 trace_seq_printf(s, "%s\n", filter->filter_string);
535 else
536 trace_seq_printf(s, "none\n");
00e95830 537 mutex_unlock(&event_mutex);
ac1adc55
TZ
538}
539
8b372562 540void print_subsystem_event_filter(struct event_subsystem *system,
ac1adc55
TZ
541 struct trace_seq *s)
542{
8b372562
TZ
543 struct event_filter *filter = system->filter;
544
00e95830 545 mutex_lock(&event_mutex);
8e254c1d 546 if (filter && filter->filter_string)
8b372562
TZ
547 trace_seq_printf(s, "%s\n", filter->filter_string);
548 else
549 trace_seq_printf(s, "none\n");
00e95830 550 mutex_unlock(&event_mutex);
ac1adc55
TZ
551}
552
7ce7e424 553static struct ftrace_event_field *
8728fe50 554__find_event_field(struct list_head *head, char *name)
7ce7e424 555{
1fc2d5c1 556 struct ftrace_event_field *field;
7ce7e424 557
2e33af02 558 list_for_each_entry(field, head, link) {
7ce7e424
TZ
559 if (!strcmp(field->name, name))
560 return field;
561 }
562
563 return NULL;
564}
565
8728fe50
LZ
566static struct ftrace_event_field *
567find_event_field(struct ftrace_event_call *call, char *name)
568{
569 struct ftrace_event_field *field;
570 struct list_head *head;
571
572 field = __find_event_field(&ftrace_common_fields, name);
573 if (field)
574 return field;
575
576 head = trace_get_fields(call);
577 return __find_event_field(head, name);
578}
579
8b372562 580static void filter_free_pred(struct filter_pred *pred)
7ce7e424
TZ
581{
582 if (!pred)
583 return;
584
585 kfree(pred->field_name);
7ce7e424
TZ
586 kfree(pred);
587}
588
0a19e53c
TZ
589static void filter_clear_pred(struct filter_pred *pred)
590{
591 kfree(pred->field_name);
592 pred->field_name = NULL;
1889d209 593 pred->regex.len = 0;
0a19e53c
TZ
594}
595
61e9dea2
SR
596static int __alloc_pred_stack(struct pred_stack *stack, int n_preds)
597{
598 stack->preds = kzalloc(sizeof(*stack->preds)*(n_preds + 1), GFP_KERNEL);
599 if (!stack->preds)
600 return -ENOMEM;
601 stack->index = n_preds;
602 return 0;
603}
604
605static void __free_pred_stack(struct pred_stack *stack)
606{
607 kfree(stack->preds);
608 stack->index = 0;
609}
610
611static int __push_pred_stack(struct pred_stack *stack,
612 struct filter_pred *pred)
613{
614 int index = stack->index;
615
616 if (WARN_ON(index == 0))
617 return -ENOSPC;
618
619 stack->preds[--index] = pred;
620 stack->index = index;
621 return 0;
622}
623
624static struct filter_pred *
625__pop_pred_stack(struct pred_stack *stack)
626{
627 struct filter_pred *pred;
628 int index = stack->index;
629
630 pred = stack->preds[index++];
631 if (!pred)
632 return NULL;
633
634 stack->index = index;
635 return pred;
636}
637
638static int filter_set_pred(struct event_filter *filter,
639 int idx,
640 struct pred_stack *stack,
0a19e53c
TZ
641 struct filter_pred *src,
642 filter_pred_fn_t fn)
643{
61e9dea2
SR
644 struct filter_pred *dest = &filter->preds[idx];
645 struct filter_pred *left;
646 struct filter_pred *right;
647
0a19e53c 648 *dest = *src;
8b372562
TZ
649 if (src->field_name) {
650 dest->field_name = kstrdup(src->field_name, GFP_KERNEL);
651 if (!dest->field_name)
652 return -ENOMEM;
653 }
0a19e53c 654 dest->fn = fn;
61e9dea2 655 dest->index = idx;
0a19e53c 656
61e9dea2
SR
657 if (dest->op == OP_OR || dest->op == OP_AND) {
658 right = __pop_pred_stack(stack);
659 left = __pop_pred_stack(stack);
660 if (!left || !right)
661 return -EINVAL;
662 dest->left = left->index;
663 dest->right = right->index;
664 left->parent = dest->index;
665 right->parent = dest->index | FILTER_PRED_IS_RIGHT;
666 } else
667 /*
668 * Make dest->left invalid to be used as a quick
669 * way to know this is a leaf node.
670 */
671 dest->left = FILTER_PRED_INVALID;
672
673 return __push_pred_stack(stack, dest);
0a19e53c
TZ
674}
675
c9c53ca0
SR
676static void __free_preds(struct event_filter *filter)
677{
678 int i;
679
680 if (filter->preds) {
74e9e58c
SR
681 for (i = 0; i < filter->a_preds; i++)
682 kfree(filter->preds[i].field_name);
c9c53ca0
SR
683 kfree(filter->preds);
684 filter->preds = NULL;
685 }
686 filter->a_preds = 0;
687 filter->n_preds = 0;
688}
689
0fc3ca9a
SR
690static void reset_preds(struct event_filter *filter)
691{
0fc3ca9a
SR
692 int n_preds = filter->n_preds;
693 int i;
694
695 filter->n_preds = 0;
61e9dea2 696 filter->root = NULL;
0fc3ca9a
SR
697 if (!filter->preds)
698 return;
699
74e9e58c
SR
700 for (i = 0; i < n_preds; i++)
701 filter->preds[i].fn = filter_pred_none;
0fc3ca9a
SR
702}
703
8b372562 704static void filter_disable_preds(struct ftrace_event_call *call)
7ce7e424 705{
30e673b2 706 struct event_filter *filter = call->filter;
7ce7e424 707
553552ce 708 call->flags &= ~TRACE_EVENT_FL_FILTERED;
0fc3ca9a 709 reset_preds(filter);
0a19e53c
TZ
710}
711
c9c53ca0 712static void __free_filter(struct event_filter *filter)
2df75e41 713{
8e254c1d
LZ
714 if (!filter)
715 return;
716
c9c53ca0 717 __free_preds(filter);
57be8887 718 kfree(filter->filter_string);
2df75e41 719 kfree(filter);
6fb2915d
LZ
720}
721
722void destroy_preds(struct ftrace_event_call *call)
723{
c9c53ca0 724 __free_filter(call->filter);
2df75e41 725 call->filter = NULL;
553552ce 726 call->flags &= ~TRACE_EVENT_FL_FILTERED;
2df75e41
LZ
727}
728
c9c53ca0 729static struct event_filter *__alloc_filter(void)
0a19e53c 730{
30e673b2 731 struct event_filter *filter;
0a19e53c 732
6fb2915d
LZ
733 filter = kzalloc(sizeof(*filter), GFP_KERNEL);
734 if (!filter)
735 return ERR_PTR(-ENOMEM);
0a19e53c 736
30e673b2
TZ
737 filter->n_preds = 0;
738
c9c53ca0
SR
739 return filter;
740}
741
742static int __alloc_preds(struct event_filter *filter, int n_preds)
743{
744 struct filter_pred *pred;
745 int i;
746
747 if (filter->preds) {
748 if (filter->a_preds < n_preds) {
c9c53ca0 749 /*
0fc3ca9a
SR
750 * We need to reallocate.
751 * We should have already have zeroed out
752 * the pred count and called synchronized_sched()
753 * to make sure no one is using the preds.
c9c53ca0 754 */
0fc3ca9a
SR
755 if (WARN_ON_ONCE(filter->n_preds)) {
756 /* We need to reset it now */
757 filter->n_preds = 0;
758 synchronize_sched();
759 }
c9c53ca0
SR
760 __free_preds(filter);
761 }
762 }
763
764 if (!filter->preds) {
765 filter->preds =
766 kzalloc(sizeof(*filter->preds) * n_preds, GFP_KERNEL);
767 filter->a_preds = n_preds;
768 }
30e673b2 769 if (!filter->preds)
c9c53ca0
SR
770 return -ENOMEM;
771
772 if (WARN_ON(filter->a_preds < n_preds))
773 return -EINVAL;
30e673b2 774
c9c53ca0 775 for (i = 0; i < n_preds; i++) {
74e9e58c 776 pred = &filter->preds[i];
0a19e53c 777 pred->fn = filter_pred_none;
0a19e53c
TZ
778 }
779
c9c53ca0 780 return 0;
6fb2915d
LZ
781}
782
c9c53ca0 783static int init_filter(struct ftrace_event_call *call)
6fb2915d
LZ
784{
785 if (call->filter)
786 return 0;
787
553552ce 788 call->flags &= ~TRACE_EVENT_FL_FILTERED;
c9c53ca0 789 call->filter = __alloc_filter();
6fb2915d
LZ
790 if (IS_ERR(call->filter))
791 return PTR_ERR(call->filter);
0a19e53c 792
6fb2915d 793 return 0;
7ce7e424 794}
8e254c1d
LZ
795
796static int init_subsystem_preds(struct event_subsystem *system)
797{
798 struct ftrace_event_call *call;
799 int err;
800
801 list_for_each_entry(call, &ftrace_events, list) {
8f082018 802 if (strcmp(call->class->system, system->name) != 0)
8e254c1d
LZ
803 continue;
804
c9c53ca0 805 err = init_filter(call);
c58b4321
LZ
806 if (err)
807 return err;
8e254c1d
LZ
808 }
809
810 return 0;
811}
7ce7e424 812
fce29d15 813static void filter_free_subsystem_preds(struct event_subsystem *system)
cfb180f3 814{
a59fd602 815 struct ftrace_event_call *call;
cfb180f3 816
a59fd602 817 list_for_each_entry(call, &ftrace_events, list) {
8f082018 818 if (strcmp(call->class->system, system->name) != 0)
8e254c1d
LZ
819 continue;
820
8e254c1d
LZ
821 filter_disable_preds(call);
822 remove_filter_string(call->filter);
cfb180f3
TZ
823 }
824}
825
8b372562
TZ
826static int filter_add_pred_fn(struct filter_parse_state *ps,
827 struct ftrace_event_call *call,
6fb2915d 828 struct event_filter *filter,
ac1adc55 829 struct filter_pred *pred,
61e9dea2 830 struct pred_stack *stack,
ac1adc55 831 filter_pred_fn_t fn)
7ce7e424 832{
0a19e53c 833 int idx, err;
7ce7e424 834
c9c53ca0 835 if (WARN_ON(filter->n_preds == filter->a_preds)) {
8b372562 836 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
0a19e53c 837 return -ENOSPC;
8b372562 838 }
7ce7e424 839
30e673b2 840 idx = filter->n_preds;
74e9e58c 841 filter_clear_pred(&filter->preds[idx]);
61e9dea2 842 err = filter_set_pred(filter, idx, stack, pred, fn);
0a19e53c
TZ
843 if (err)
844 return err;
845
30e673b2 846 filter->n_preds++;
7ce7e424 847
0a19e53c 848 return 0;
7ce7e424
TZ
849}
850
aa38e9fc 851int filter_assign_type(const char *type)
7ce7e424 852{
7fcb7c47
LZ
853 if (strstr(type, "__data_loc") && strstr(type, "char"))
854 return FILTER_DYN_STRING;
855
7ce7e424 856 if (strchr(type, '[') && strstr(type, "char"))
e8808c10
FW
857 return FILTER_STATIC_STRING;
858
aa38e9fc
LZ
859 return FILTER_OTHER;
860}
861
862static bool is_string_field(struct ftrace_event_field *field)
863{
864 return field->filter_type == FILTER_DYN_STRING ||
87a342f5
LZ
865 field->filter_type == FILTER_STATIC_STRING ||
866 field->filter_type == FILTER_PTR_STRING;
7ce7e424
TZ
867}
868
8b372562
TZ
869static int is_legal_op(struct ftrace_event_field *field, int op)
870{
b0f1a59a
LZ
871 if (is_string_field(field) &&
872 (op != OP_EQ && op != OP_NE && op != OP_GLOB))
873 return 0;
874 if (!is_string_field(field) && op == OP_GLOB)
8b372562
TZ
875 return 0;
876
877 return 1;
878}
879
880static filter_pred_fn_t select_comparison_fn(int op, int field_size,
881 int field_is_signed)
882{
883 filter_pred_fn_t fn = NULL;
884
885 switch (field_size) {
886 case 8:
887 if (op == OP_EQ || op == OP_NE)
888 fn = filter_pred_64;
889 else if (field_is_signed)
890 fn = filter_pred_s64;
891 else
892 fn = filter_pred_u64;
893 break;
894 case 4:
895 if (op == OP_EQ || op == OP_NE)
896 fn = filter_pred_32;
897 else if (field_is_signed)
898 fn = filter_pred_s32;
899 else
900 fn = filter_pred_u32;
901 break;
902 case 2:
903 if (op == OP_EQ || op == OP_NE)
904 fn = filter_pred_16;
905 else if (field_is_signed)
906 fn = filter_pred_s16;
907 else
908 fn = filter_pred_u16;
909 break;
910 case 1:
911 if (op == OP_EQ || op == OP_NE)
912 fn = filter_pred_8;
913 else if (field_is_signed)
914 fn = filter_pred_s8;
915 else
916 fn = filter_pred_u8;
917 break;
918 }
919
920 return fn;
921}
922
923static int filter_add_pred(struct filter_parse_state *ps,
924 struct ftrace_event_call *call,
6fb2915d 925 struct event_filter *filter,
1f9963cb 926 struct filter_pred *pred,
61e9dea2 927 struct pred_stack *stack,
1f9963cb 928 bool dry_run)
7ce7e424
TZ
929{
930 struct ftrace_event_field *field;
0a19e53c 931 filter_pred_fn_t fn;
f66578a7 932 unsigned long long val;
5e4904cb 933 int ret;
7ce7e424 934
58d9a597 935 fn = pred->fn = filter_pred_none;
8b372562 936
61e9dea2 937 if (pred->op == OP_AND)
1f9963cb 938 goto add_pred_fn;
61e9dea2 939 else if (pred->op == OP_OR)
1f9963cb 940 goto add_pred_fn;
8b372562 941
7ce7e424 942 field = find_event_field(call, pred->field_name);
8b372562
TZ
943 if (!field) {
944 parse_error(ps, FILT_ERR_FIELD_NOT_FOUND, 0);
7ce7e424 945 return -EINVAL;
8b372562 946 }
7ce7e424
TZ
947
948 pred->offset = field->offset;
949
8b372562
TZ
950 if (!is_legal_op(field, pred->op)) {
951 parse_error(ps, FILT_ERR_ILLEGAL_FIELD_OP, 0);
952 return -EINVAL;
953 }
954
aa38e9fc 955 if (is_string_field(field)) {
b0f1a59a 956 filter_build_regex(pred);
87a342f5 957
1889d209 958 if (field->filter_type == FILTER_STATIC_STRING) {
e8808c10 959 fn = filter_pred_string;
1889d209
FW
960 pred->regex.field_len = field->size;
961 } else if (field->filter_type == FILTER_DYN_STRING)
b0f1a59a 962 fn = filter_pred_strloc;
16da27a8 963 else
87a342f5 964 fn = filter_pred_pchar;
9f58a159 965 } else {
5e4904cb 966 if (field->is_signed)
1889d209 967 ret = strict_strtoll(pred->regex.pattern, 0, &val);
5e4904cb 968 else
1889d209 969 ret = strict_strtoull(pred->regex.pattern, 0, &val);
5e4904cb 970 if (ret) {
8b372562 971 parse_error(ps, FILT_ERR_ILLEGAL_INTVAL, 0);
9f58a159 972 return -EINVAL;
8b372562 973 }
f66578a7 974 pred->val = val;
7ce7e424 975
1f9963cb
LZ
976 fn = select_comparison_fn(pred->op, field->size,
977 field->is_signed);
978 if (!fn) {
979 parse_error(ps, FILT_ERR_INVALID_OP, 0);
980 return -EINVAL;
981 }
7ce7e424
TZ
982 }
983
8b372562
TZ
984 if (pred->op == OP_NE)
985 pred->not = 1;
ac1adc55 986
1f9963cb
LZ
987add_pred_fn:
988 if (!dry_run)
61e9dea2 989 return filter_add_pred_fn(ps, call, filter, pred, stack, fn);
1f9963cb 990 return 0;
cfb180f3
TZ
991}
992
8b372562
TZ
993static void parse_init(struct filter_parse_state *ps,
994 struct filter_op *ops,
995 char *infix_string)
996{
997 memset(ps, '\0', sizeof(*ps));
998
999 ps->infix.string = infix_string;
1000 ps->infix.cnt = strlen(infix_string);
1001 ps->ops = ops;
1002
1003 INIT_LIST_HEAD(&ps->opstack);
1004 INIT_LIST_HEAD(&ps->postfix);
1005}
1006
1007static char infix_next(struct filter_parse_state *ps)
1008{
1009 ps->infix.cnt--;
1010
1011 return ps->infix.string[ps->infix.tail++];
1012}
1013
1014static char infix_peek(struct filter_parse_state *ps)
1015{
1016 if (ps->infix.tail == strlen(ps->infix.string))
1017 return 0;
1018
1019 return ps->infix.string[ps->infix.tail];
1020}
1021
1022static void infix_advance(struct filter_parse_state *ps)
1023{
1024 ps->infix.cnt--;
1025 ps->infix.tail++;
1026}
1027
1028static inline int is_precedence_lower(struct filter_parse_state *ps,
1029 int a, int b)
1030{
1031 return ps->ops[a].precedence < ps->ops[b].precedence;
1032}
1033
1034static inline int is_op_char(struct filter_parse_state *ps, char c)
1035{
1036 int i;
1037
1038 for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
1039 if (ps->ops[i].string[0] == c)
1040 return 1;
1041 }
c4cff064 1042
0a19e53c 1043 return 0;
cfb180f3
TZ
1044}
1045
8b372562
TZ
1046static int infix_get_op(struct filter_parse_state *ps, char firstc)
1047{
1048 char nextc = infix_peek(ps);
1049 char opstr[3];
1050 int i;
1051
1052 opstr[0] = firstc;
1053 opstr[1] = nextc;
1054 opstr[2] = '\0';
1055
1056 for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
1057 if (!strcmp(opstr, ps->ops[i].string)) {
1058 infix_advance(ps);
1059 return ps->ops[i].id;
7ce7e424 1060 }
8b372562
TZ
1061 }
1062
1063 opstr[1] = '\0';
1064
1065 for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
1066 if (!strcmp(opstr, ps->ops[i].string))
1067 return ps->ops[i].id;
1068 }
1069
1070 return OP_NONE;
1071}
1072
1073static inline void clear_operand_string(struct filter_parse_state *ps)
1074{
1075 memset(ps->operand.string, '\0', MAX_FILTER_STR_VAL);
1076 ps->operand.tail = 0;
1077}
1078
1079static inline int append_operand_char(struct filter_parse_state *ps, char c)
1080{
5872144f 1081 if (ps->operand.tail == MAX_FILTER_STR_VAL - 1)
8b372562
TZ
1082 return -EINVAL;
1083
1084 ps->operand.string[ps->operand.tail++] = c;
1085
1086 return 0;
1087}
1088
1089static int filter_opstack_push(struct filter_parse_state *ps, int op)
1090{
1091 struct opstack_op *opstack_op;
1092
1093 opstack_op = kmalloc(sizeof(*opstack_op), GFP_KERNEL);
1094 if (!opstack_op)
1095 return -ENOMEM;
1096
1097 opstack_op->op = op;
1098 list_add(&opstack_op->list, &ps->opstack);
1099
1100 return 0;
1101}
1102
1103static int filter_opstack_empty(struct filter_parse_state *ps)
1104{
1105 return list_empty(&ps->opstack);
1106}
1107
1108static int filter_opstack_top(struct filter_parse_state *ps)
1109{
1110 struct opstack_op *opstack_op;
1111
1112 if (filter_opstack_empty(ps))
1113 return OP_NONE;
1114
1115 opstack_op = list_first_entry(&ps->opstack, struct opstack_op, list);
1116
1117 return opstack_op->op;
1118}
1119
1120static int filter_opstack_pop(struct filter_parse_state *ps)
1121{
1122 struct opstack_op *opstack_op;
1123 int op;
1124
1125 if (filter_opstack_empty(ps))
1126 return OP_NONE;
1127
1128 opstack_op = list_first_entry(&ps->opstack, struct opstack_op, list);
1129 op = opstack_op->op;
1130 list_del(&opstack_op->list);
1131
1132 kfree(opstack_op);
1133
1134 return op;
1135}
1136
1137static void filter_opstack_clear(struct filter_parse_state *ps)
1138{
1139 while (!filter_opstack_empty(ps))
1140 filter_opstack_pop(ps);
1141}
1142
1143static char *curr_operand(struct filter_parse_state *ps)
1144{
1145 return ps->operand.string;
1146}
1147
1148static int postfix_append_operand(struct filter_parse_state *ps, char *operand)
1149{
1150 struct postfix_elt *elt;
1151
1152 elt = kmalloc(sizeof(*elt), GFP_KERNEL);
1153 if (!elt)
1154 return -ENOMEM;
1155
1156 elt->op = OP_NONE;
1157 elt->operand = kstrdup(operand, GFP_KERNEL);
1158 if (!elt->operand) {
1159 kfree(elt);
1160 return -ENOMEM;
1161 }
1162
1163 list_add_tail(&elt->list, &ps->postfix);
1164
1165 return 0;
1166}
1167
1168static int postfix_append_op(struct filter_parse_state *ps, int op)
1169{
1170 struct postfix_elt *elt;
1171
1172 elt = kmalloc(sizeof(*elt), GFP_KERNEL);
1173 if (!elt)
1174 return -ENOMEM;
1175
1176 elt->op = op;
1177 elt->operand = NULL;
1178
1179 list_add_tail(&elt->list, &ps->postfix);
1180
1181 return 0;
1182}
1183
1184static void postfix_clear(struct filter_parse_state *ps)
1185{
1186 struct postfix_elt *elt;
1187
1188 while (!list_empty(&ps->postfix)) {
1189 elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
8b372562 1190 list_del(&elt->list);
8ad80731
LZ
1191 kfree(elt->operand);
1192 kfree(elt);
8b372562
TZ
1193 }
1194}
1195
1196static int filter_parse(struct filter_parse_state *ps)
1197{
5928c3cc 1198 int in_string = 0;
8b372562
TZ
1199 int op, top_op;
1200 char ch;
1201
1202 while ((ch = infix_next(ps))) {
5928c3cc
FW
1203 if (ch == '"') {
1204 in_string ^= 1;
1205 continue;
1206 }
1207
1208 if (in_string)
1209 goto parse_operand;
1210
8b372562
TZ
1211 if (isspace(ch))
1212 continue;
1213
1214 if (is_op_char(ps, ch)) {
1215 op = infix_get_op(ps, ch);
1216 if (op == OP_NONE) {
1217 parse_error(ps, FILT_ERR_INVALID_OP, 0);
7ce7e424
TZ
1218 return -EINVAL;
1219 }
8b372562
TZ
1220
1221 if (strlen(curr_operand(ps))) {
1222 postfix_append_operand(ps, curr_operand(ps));
1223 clear_operand_string(ps);
1224 }
1225
1226 while (!filter_opstack_empty(ps)) {
1227 top_op = filter_opstack_top(ps);
1228 if (!is_precedence_lower(ps, top_op, op)) {
1229 top_op = filter_opstack_pop(ps);
1230 postfix_append_op(ps, top_op);
1231 continue;
1232 }
1233 break;
1234 }
1235
1236 filter_opstack_push(ps, op);
7ce7e424
TZ
1237 continue;
1238 }
8b372562
TZ
1239
1240 if (ch == '(') {
1241 filter_opstack_push(ps, OP_OPEN_PAREN);
1242 continue;
1243 }
1244
1245 if (ch == ')') {
1246 if (strlen(curr_operand(ps))) {
1247 postfix_append_operand(ps, curr_operand(ps));
1248 clear_operand_string(ps);
1249 }
1250
1251 top_op = filter_opstack_pop(ps);
1252 while (top_op != OP_NONE) {
1253 if (top_op == OP_OPEN_PAREN)
1254 break;
1255 postfix_append_op(ps, top_op);
1256 top_op = filter_opstack_pop(ps);
1257 }
1258 if (top_op == OP_NONE) {
1259 parse_error(ps, FILT_ERR_UNBALANCED_PAREN, 0);
1260 return -EINVAL;
7ce7e424 1261 }
7ce7e424
TZ
1262 continue;
1263 }
5928c3cc 1264parse_operand:
8b372562
TZ
1265 if (append_operand_char(ps, ch)) {
1266 parse_error(ps, FILT_ERR_OPERAND_TOO_LONG, 0);
1267 return -EINVAL;
1268 }
1269 }
1270
1271 if (strlen(curr_operand(ps)))
1272 postfix_append_operand(ps, curr_operand(ps));
1273
1274 while (!filter_opstack_empty(ps)) {
1275 top_op = filter_opstack_pop(ps);
1276 if (top_op == OP_NONE)
1277 break;
1278 if (top_op == OP_OPEN_PAREN) {
1279 parse_error(ps, FILT_ERR_UNBALANCED_PAREN, 0);
1280 return -EINVAL;
1281 }
1282 postfix_append_op(ps, top_op);
1283 }
1284
1285 return 0;
1286}
1287
1288static struct filter_pred *create_pred(int op, char *operand1, char *operand2)
1289{
1290 struct filter_pred *pred;
1291
1292 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
1293 if (!pred)
1294 return NULL;
1295
1296 pred->field_name = kstrdup(operand1, GFP_KERNEL);
1297 if (!pred->field_name) {
1298 kfree(pred);
1299 return NULL;
1300 }
1301
1889d209
FW
1302 strcpy(pred->regex.pattern, operand2);
1303 pred->regex.len = strlen(pred->regex.pattern);
8b372562
TZ
1304
1305 pred->op = op;
1306
1307 return pred;
1308}
1309
1310static struct filter_pred *create_logical_pred(int op)
1311{
1312 struct filter_pred *pred;
1313
1314 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
1315 if (!pred)
1316 return NULL;
1317
1318 pred->op = op;
1319
1320 return pred;
1321}
1322
1323static int check_preds(struct filter_parse_state *ps)
1324{
1325 int n_normal_preds = 0, n_logical_preds = 0;
1326 struct postfix_elt *elt;
1327
1328 list_for_each_entry(elt, &ps->postfix, list) {
1329 if (elt->op == OP_NONE)
1330 continue;
1331
1332 if (elt->op == OP_AND || elt->op == OP_OR) {
1333 n_logical_preds++;
1334 continue;
7ce7e424 1335 }
8b372562 1336 n_normal_preds++;
7ce7e424
TZ
1337 }
1338
8b372562
TZ
1339 if (!n_normal_preds || n_logical_preds >= n_normal_preds) {
1340 parse_error(ps, FILT_ERR_INVALID_FILTER, 0);
bcabd91c
LZ
1341 return -EINVAL;
1342 }
1343
8b372562
TZ
1344 return 0;
1345}
f66578a7 1346
c9c53ca0
SR
1347static int count_preds(struct filter_parse_state *ps)
1348{
1349 struct postfix_elt *elt;
1350 int n_preds = 0;
1351
1352 list_for_each_entry(elt, &ps->postfix, list) {
1353 if (elt->op == OP_NONE)
1354 continue;
1355 n_preds++;
1356 }
1357
1358 return n_preds;
1359}
1360
fce29d15 1361static int replace_preds(struct ftrace_event_call *call,
6fb2915d 1362 struct event_filter *filter,
8b372562 1363 struct filter_parse_state *ps,
1f9963cb
LZ
1364 char *filter_string,
1365 bool dry_run)
8b372562
TZ
1366{
1367 char *operand1 = NULL, *operand2 = NULL;
1368 struct filter_pred *pred;
1369 struct postfix_elt *elt;
61e9dea2 1370 struct pred_stack stack = { }; /* init to NULL */
8b372562 1371 int err;
1f9963cb 1372 int n_preds = 0;
8b372562 1373
c9c53ca0
SR
1374 n_preds = count_preds(ps);
1375 if (n_preds >= MAX_FILTER_PRED) {
1376 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
1377 return -ENOSPC;
1378 }
1379
8b372562
TZ
1380 err = check_preds(ps);
1381 if (err)
1382 return err;
1383
c9c53ca0 1384 if (!dry_run) {
61e9dea2 1385 err = __alloc_pred_stack(&stack, n_preds);
c9c53ca0
SR
1386 if (err)
1387 return err;
61e9dea2
SR
1388 err = __alloc_preds(filter, n_preds);
1389 if (err)
1390 goto fail;
c9c53ca0
SR
1391 }
1392
1393 n_preds = 0;
8b372562
TZ
1394 list_for_each_entry(elt, &ps->postfix, list) {
1395 if (elt->op == OP_NONE) {
1396 if (!operand1)
1397 operand1 = elt->operand;
1398 else if (!operand2)
1399 operand2 = elt->operand;
1400 else {
1401 parse_error(ps, FILT_ERR_TOO_MANY_OPERANDS, 0);
61e9dea2
SR
1402 err = -EINVAL;
1403 goto fail;
8b372562
TZ
1404 }
1405 continue;
1406 }
1407
c9c53ca0 1408 if (WARN_ON(n_preds++ == MAX_FILTER_PRED)) {
1f9963cb 1409 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
61e9dea2
SR
1410 err = -ENOSPC;
1411 goto fail;
1f9963cb
LZ
1412 }
1413
8b372562
TZ
1414 if (elt->op == OP_AND || elt->op == OP_OR) {
1415 pred = create_logical_pred(elt->op);
1f9963cb 1416 goto add_pred;
8b372562
TZ
1417 }
1418
1419 if (!operand1 || !operand2) {
1420 parse_error(ps, FILT_ERR_MISSING_FIELD, 0);
61e9dea2
SR
1421 err = -EINVAL;
1422 goto fail;
8b372562
TZ
1423 }
1424
1425 pred = create_pred(elt->op, operand1, operand2);
1f9963cb 1426add_pred:
61e9dea2
SR
1427 if (!pred) {
1428 err = -ENOMEM;
1429 goto fail;
1430 }
1431 err = filter_add_pred(ps, call, filter, pred, &stack, dry_run);
c5cb1836 1432 filter_free_pred(pred);
8b372562 1433 if (err)
61e9dea2 1434 goto fail;
8b372562
TZ
1435
1436 operand1 = operand2 = NULL;
1437 }
7ce7e424 1438
61e9dea2
SR
1439 if (!dry_run) {
1440 /* We should have one item left on the stack */
1441 pred = __pop_pred_stack(&stack);
1442 if (!pred)
1443 return -EINVAL;
1444 /* This item is where we start from in matching */
1445 filter->root = pred;
1446 /* Make sure the stack is empty */
1447 pred = __pop_pred_stack(&stack);
1448 if (WARN_ON(pred)) {
1449 err = -EINVAL;
1450 filter->root = NULL;
1451 goto fail;
1452 }
1453 }
1454
1455 err = 0;
1456fail:
1457 __free_pred_stack(&stack);
1458 return err;
7ce7e424
TZ
1459}
1460
fce29d15
LZ
1461static int replace_system_preds(struct event_subsystem *system,
1462 struct filter_parse_state *ps,
1463 char *filter_string)
1464{
1465 struct ftrace_event_call *call;
fce29d15 1466 bool fail = true;
a66abe7f 1467 int err;
fce29d15
LZ
1468
1469 list_for_each_entry(call, &ftrace_events, list) {
3ed67776 1470 struct event_filter *filter = call->filter;
fce29d15 1471
8f082018 1472 if (strcmp(call->class->system, system->name) != 0)
fce29d15
LZ
1473 continue;
1474
1475 /* try to see if the filter can be applied */
6fb2915d 1476 err = replace_preds(call, filter, ps, filter_string, true);
fce29d15 1477 if (err)
0fc3ca9a
SR
1478 goto fail;
1479 }
1480
1481 /* set all filter pred counts to zero */
1482 list_for_each_entry(call, &ftrace_events, list) {
1483 struct event_filter *filter = call->filter;
1484
1485 if (strcmp(call->class->system, system->name) != 0)
1486 continue;
1487
1488 reset_preds(filter);
1489 }
1490
1491 /*
1492 * Since some of the preds may be used under preemption
1493 * we need to wait for them to finish before we may
1494 * reallocate them.
1495 */
1496 synchronize_sched();
1497
1498 list_for_each_entry(call, &ftrace_events, list) {
1499 struct event_filter *filter = call->filter;
1500
1501 if (strcmp(call->class->system, system->name) != 0)
fce29d15
LZ
1502 continue;
1503
1504 /* really apply the filter */
1505 filter_disable_preds(call);
6fb2915d 1506 err = replace_preds(call, filter, ps, filter_string, false);
fce29d15
LZ
1507 if (err)
1508 filter_disable_preds(call);
6fb2915d 1509 else {
553552ce 1510 call->flags |= TRACE_EVENT_FL_FILTERED;
6fb2915d
LZ
1511 replace_filter_string(filter, filter_string);
1512 }
fce29d15
LZ
1513 fail = false;
1514 }
1515
0fc3ca9a
SR
1516 if (fail)
1517 goto fail;
1518
fce29d15 1519 return 0;
0fc3ca9a
SR
1520 fail:
1521 parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0);
1522 return -EINVAL;
fce29d15
LZ
1523}
1524
8b372562
TZ
1525int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
1526{
1527 int err;
8b372562
TZ
1528 struct filter_parse_state *ps;
1529
00e95830 1530 mutex_lock(&event_mutex);
8b372562 1531
c9c53ca0 1532 err = init_filter(call);
8e254c1d
LZ
1533 if (err)
1534 goto out_unlock;
1535
8b372562
TZ
1536 if (!strcmp(strstrip(filter_string), "0")) {
1537 filter_disable_preds(call);
f76690af
SR
1538 reset_preds(call->filter);
1539 /* Make sure the filter is not being used */
1540 synchronize_sched();
1541 __free_preds(call->filter);
8b372562 1542 remove_filter_string(call->filter);
a66abe7f 1543 goto out_unlock;
8b372562
TZ
1544 }
1545
8cd995b6 1546 err = -ENOMEM;
8b372562
TZ
1547 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1548 if (!ps)
8cd995b6 1549 goto out_unlock;
8b372562
TZ
1550
1551 filter_disable_preds(call);
1552 replace_filter_string(call->filter, filter_string);
1553
1554 parse_init(ps, filter_ops, filter_string);
1555 err = filter_parse(ps);
1556 if (err) {
1557 append_filter_err(ps, call->filter);
1558 goto out;
1559 }
1560
0fc3ca9a
SR
1561 /*
1562 * Make sure all the pred counts are zero so that
1563 * no task is using it when we reallocate the preds array.
1564 */
1565 reset_preds(call->filter);
1566 synchronize_sched();
1567
6fb2915d 1568 err = replace_preds(call, call->filter, ps, filter_string, false);
8b372562
TZ
1569 if (err)
1570 append_filter_err(ps, call->filter);
6fb2915d 1571 else
553552ce 1572 call->flags |= TRACE_EVENT_FL_FILTERED;
8b372562
TZ
1573out:
1574 filter_opstack_clear(ps);
1575 postfix_clear(ps);
1576 kfree(ps);
8cd995b6 1577out_unlock:
00e95830 1578 mutex_unlock(&event_mutex);
8b372562
TZ
1579
1580 return err;
1581}
1582
1583int apply_subsystem_event_filter(struct event_subsystem *system,
1584 char *filter_string)
1585{
1586 int err;
8b372562
TZ
1587 struct filter_parse_state *ps;
1588
00e95830 1589 mutex_lock(&event_mutex);
8b372562 1590
8e254c1d
LZ
1591 err = init_subsystem_preds(system);
1592 if (err)
1593 goto out_unlock;
1594
8b372562 1595 if (!strcmp(strstrip(filter_string), "0")) {
fce29d15 1596 filter_free_subsystem_preds(system);
8b372562 1597 remove_filter_string(system->filter);
a66abe7f 1598 goto out_unlock;
8b372562
TZ
1599 }
1600
8cd995b6 1601 err = -ENOMEM;
8b372562
TZ
1602 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1603 if (!ps)
8cd995b6 1604 goto out_unlock;
8b372562 1605
8b372562
TZ
1606 replace_filter_string(system->filter, filter_string);
1607
1608 parse_init(ps, filter_ops, filter_string);
1609 err = filter_parse(ps);
1610 if (err) {
1611 append_filter_err(ps, system->filter);
1612 goto out;
1613 }
1614
fce29d15
LZ
1615 err = replace_system_preds(system, ps, filter_string);
1616 if (err)
8b372562
TZ
1617 append_filter_err(ps, system->filter);
1618
1619out:
1620 filter_opstack_clear(ps);
1621 postfix_clear(ps);
1622 kfree(ps);
8cd995b6 1623out_unlock:
00e95830 1624 mutex_unlock(&event_mutex);
8b372562
TZ
1625
1626 return err;
1627}
7ce7e424 1628
07b139c8 1629#ifdef CONFIG_PERF_EVENTS
6fb2915d
LZ
1630
1631void ftrace_profile_free_filter(struct perf_event *event)
1632{
1633 struct event_filter *filter = event->filter;
1634
1635 event->filter = NULL;
c9c53ca0 1636 __free_filter(filter);
6fb2915d
LZ
1637}
1638
1639int ftrace_profile_set_filter(struct perf_event *event, int event_id,
1640 char *filter_str)
1641{
1642 int err;
1643 struct event_filter *filter;
1644 struct filter_parse_state *ps;
1645 struct ftrace_event_call *call = NULL;
1646
1647 mutex_lock(&event_mutex);
1648
1649 list_for_each_entry(call, &ftrace_events, list) {
32c0edae 1650 if (call->event.type == event_id)
6fb2915d
LZ
1651 break;
1652 }
a66abe7f
IM
1653
1654 err = -EINVAL;
d9f599e1 1655 if (&call->list == &ftrace_events)
a66abe7f 1656 goto out_unlock;
6fb2915d 1657
a66abe7f 1658 err = -EEXIST;
6fb2915d 1659 if (event->filter)
a66abe7f 1660 goto out_unlock;
6fb2915d 1661
c9c53ca0 1662 filter = __alloc_filter();
a66abe7f
IM
1663 if (IS_ERR(filter)) {
1664 err = PTR_ERR(filter);
1665 goto out_unlock;
1666 }
6fb2915d
LZ
1667
1668 err = -ENOMEM;
1669 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1670 if (!ps)
c9c53ca0 1671 goto free_filter;
6fb2915d
LZ
1672
1673 parse_init(ps, filter_ops, filter_str);
1674 err = filter_parse(ps);
1675 if (err)
1676 goto free_ps;
1677
1678 err = replace_preds(call, filter, ps, filter_str, false);
1679 if (!err)
1680 event->filter = filter;
1681
1682free_ps:
1683 filter_opstack_clear(ps);
1684 postfix_clear(ps);
1685 kfree(ps);
1686
c9c53ca0 1687free_filter:
6fb2915d 1688 if (err)
c9c53ca0 1689 __free_filter(filter);
6fb2915d 1690
a66abe7f 1691out_unlock:
6fb2915d
LZ
1692 mutex_unlock(&event_mutex);
1693
1694 return err;
1695}
1696
07b139c8 1697#endif /* CONFIG_PERF_EVENTS */
6fb2915d 1698