tracing/filters: Refactor subsystem filter code
[GitHub/mt8127/android_kernel_alcatel_ttab.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>
7ce7e424
TZ
24
25#include "trace.h"
4bda2d51 26#include "trace_output.h"
7ce7e424 27
8b372562 28enum filter_op_ids
7ce7e424 29{
8b372562
TZ
30 OP_OR,
31 OP_AND,
32 OP_NE,
33 OP_EQ,
34 OP_LT,
35 OP_LE,
36 OP_GT,
37 OP_GE,
38 OP_NONE,
39 OP_OPEN_PAREN,
40};
41
42struct filter_op {
43 int id;
44 char *string;
45 int precedence;
46};
47
48static struct filter_op filter_ops[] = {
49 { OP_OR, "||", 1 },
50 { OP_AND, "&&", 2 },
51 { OP_NE, "!=", 4 },
52 { OP_EQ, "==", 4 },
53 { OP_LT, "<", 5 },
54 { OP_LE, "<=", 5 },
55 { OP_GT, ">", 5 },
56 { OP_GE, ">=", 5 },
57 { OP_NONE, "OP_NONE", 0 },
58 { OP_OPEN_PAREN, "(", 0 },
59};
60
61enum {
62 FILT_ERR_NONE,
63 FILT_ERR_INVALID_OP,
64 FILT_ERR_UNBALANCED_PAREN,
65 FILT_ERR_TOO_MANY_OPERANDS,
66 FILT_ERR_OPERAND_TOO_LONG,
67 FILT_ERR_FIELD_NOT_FOUND,
68 FILT_ERR_ILLEGAL_FIELD_OP,
69 FILT_ERR_ILLEGAL_INTVAL,
70 FILT_ERR_BAD_SUBSYS_FILTER,
71 FILT_ERR_TOO_MANY_PREDS,
72 FILT_ERR_MISSING_FIELD,
73 FILT_ERR_INVALID_FILTER,
74};
75
76static char *err_text[] = {
77 "No error",
78 "Invalid operator",
79 "Unbalanced parens",
80 "Too many operands",
81 "Operand too long",
82 "Field not found",
83 "Illegal operation for field type",
84 "Illegal integer value",
85 "Couldn't find or set field in one of a subsystem's events",
86 "Too many terms in predicate expression",
87 "Missing field name and/or value",
88 "Meaningless filter expression",
89};
90
91struct opstack_op {
92 int op;
93 struct list_head list;
94};
95
96struct postfix_elt {
97 int op;
98 char *operand;
99 struct list_head list;
100};
101
102struct filter_parse_state {
103 struct filter_op *ops;
104 struct list_head opstack;
105 struct list_head postfix;
106 int lasterr;
107 int lasterr_pos;
108
109 struct {
110 char *string;
111 unsigned int cnt;
112 unsigned int tail;
113 } infix;
114
115 struct {
116 char string[MAX_FILTER_STR_VAL];
117 int pos;
118 unsigned int tail;
119 } operand;
120};
121
197e2eab
LZ
122#define DEFINE_COMPARISON_PRED(type) \
123static int filter_pred_##type(struct filter_pred *pred, void *event, \
124 int val1, int val2) \
125{ \
126 type *addr = (type *)(event + pred->offset); \
127 type val = (type)pred->val; \
128 int match = 0; \
129 \
130 switch (pred->op) { \
131 case OP_LT: \
132 match = (*addr < val); \
133 break; \
134 case OP_LE: \
135 match = (*addr <= val); \
136 break; \
137 case OP_GT: \
138 match = (*addr > val); \
139 break; \
140 case OP_GE: \
141 match = (*addr >= val); \
142 break; \
143 default: \
144 break; \
145 } \
146 \
147 return match; \
148}
149
150#define DEFINE_EQUALITY_PRED(size) \
151static int filter_pred_##size(struct filter_pred *pred, void *event, \
152 int val1, int val2) \
153{ \
154 u##size *addr = (u##size *)(event + pred->offset); \
155 u##size val = (u##size)pred->val; \
156 int match; \
157 \
158 match = (val == *addr) ^ pred->not; \
159 \
160 return match; \
161}
162
8b372562
TZ
163DEFINE_COMPARISON_PRED(s64);
164DEFINE_COMPARISON_PRED(u64);
165DEFINE_COMPARISON_PRED(s32);
166DEFINE_COMPARISON_PRED(u32);
167DEFINE_COMPARISON_PRED(s16);
168DEFINE_COMPARISON_PRED(u16);
169DEFINE_COMPARISON_PRED(s8);
170DEFINE_COMPARISON_PRED(u8);
171
172DEFINE_EQUALITY_PRED(64);
173DEFINE_EQUALITY_PRED(32);
174DEFINE_EQUALITY_PRED(16);
175DEFINE_EQUALITY_PRED(8);
176
177static int filter_pred_and(struct filter_pred *pred __attribute((unused)),
178 void *event __attribute((unused)),
179 int val1, int val2)
7ce7e424 180{
8b372562 181 return val1 && val2;
7ce7e424
TZ
182}
183
8b372562
TZ
184static int filter_pred_or(struct filter_pred *pred __attribute((unused)),
185 void *event __attribute((unused)),
186 int val1, int val2)
7ce7e424 187{
8b372562 188 return val1 || val2;
7ce7e424
TZ
189}
190
e8808c10 191/* Filter predicate for fixed sized arrays of characters */
8b372562
TZ
192static int filter_pred_string(struct filter_pred *pred, void *event,
193 int val1, int val2)
7ce7e424
TZ
194{
195 char *addr = (char *)(event + pred->offset);
196 int cmp, match;
197
1889d209 198 cmp = pred->regex.match(addr, &pred->regex, pred->regex.field_len);
7ce7e424 199
1889d209 200 match = cmp ^ pred->not;
7ce7e424
TZ
201
202 return match;
203}
204
87a342f5
LZ
205/* Filter predicate for char * pointers */
206static int filter_pred_pchar(struct filter_pred *pred, void *event,
207 int val1, int val2)
208{
209 char **addr = (char **)(event + pred->offset);
210 int cmp, match;
211
1889d209 212 cmp = pred->regex.match(*addr, &pred->regex, pred->regex.field_len);
87a342f5 213
1889d209 214 match = cmp ^ pred->not;
87a342f5
LZ
215
216 return match;
217}
218
e8808c10
FW
219/*
220 * Filter predicate for dynamic sized arrays of characters.
221 * These are implemented through a list of strings at the end
222 * of the entry.
223 * Also each of these strings have a field in the entry which
224 * contains its offset from the beginning of the entry.
225 * We have then first to get this field, dereference it
226 * and add it to the address of the entry, and at last we have
227 * the address of the string.
228 */
229static int filter_pred_strloc(struct filter_pred *pred, void *event,
230 int val1, int val2)
231{
7d536cb3
LZ
232 u32 str_item = *(u32 *)(event + pred->offset);
233 int str_loc = str_item & 0xffff;
234 int str_len = str_item >> 16;
e8808c10
FW
235 char *addr = (char *)(event + str_loc);
236 int cmp, match;
237
1889d209 238 cmp = pred->regex.match(addr, &pred->regex, str_len);
e8808c10 239
1889d209 240 match = cmp ^ pred->not;
e8808c10
FW
241
242 return match;
243}
244
8b372562
TZ
245static int filter_pred_none(struct filter_pred *pred, void *event,
246 int val1, int val2)
0a19e53c
TZ
247{
248 return 0;
249}
250
1889d209
FW
251/* Basic regex callbacks */
252static int regex_match_full(char *str, struct regex *r, int len)
253{
254 if (strncmp(str, r->pattern, len) == 0)
255 return 1;
256 return 0;
257}
258
259static int regex_match_front(char *str, struct regex *r, int len)
260{
261 if (strncmp(str, r->pattern, len) == 0)
262 return 1;
263 return 0;
264}
265
266static int regex_match_middle(char *str, struct regex *r, int len)
267{
268 if (strstr(str, r->pattern))
269 return 1;
270 return 0;
271}
272
273static int regex_match_end(char *str, struct regex *r, int len)
274{
275 char *ptr = strstr(str, r->pattern);
276
277 if (ptr && (ptr[r->len] == 0))
278 return 1;
279 return 0;
280}
281
3f6fe06d
FW
282/**
283 * filter_parse_regex - parse a basic regex
284 * @buff: the raw regex
285 * @len: length of the regex
286 * @search: will point to the beginning of the string to compare
287 * @not: tell whether the match will have to be inverted
288 *
289 * This passes in a buffer containing a regex and this function will
1889d209
FW
290 * set search to point to the search part of the buffer and
291 * return the type of search it is (see enum above).
292 * This does modify buff.
293 *
294 * Returns enum type.
295 * search returns the pointer to use for comparison.
296 * not returns 1 if buff started with a '!'
297 * 0 otherwise.
298 */
3f6fe06d 299enum regex_type filter_parse_regex(char *buff, int len, char **search, int *not)
1889d209
FW
300{
301 int type = MATCH_FULL;
302 int i;
303
304 if (buff[0] == '!') {
305 *not = 1;
306 buff++;
307 len--;
308 } else
309 *not = 0;
310
311 *search = buff;
312
313 for (i = 0; i < len; i++) {
314 if (buff[i] == '*') {
315 if (!i) {
316 *search = buff + 1;
317 type = MATCH_END_ONLY;
318 } else {
319 if (type == MATCH_END_ONLY)
320 type = MATCH_MIDDLE_ONLY;
321 else
322 type = MATCH_FRONT_ONLY;
323 buff[i] = 0;
324 break;
325 }
326 }
327 }
328
329 return type;
330}
331
332static int filter_build_regex(struct filter_pred *pred)
333{
334 struct regex *r = &pred->regex;
335 char *search, *dup;
336 enum regex_type type;
337 int not;
338
339 type = filter_parse_regex(r->pattern, r->len, &search, &not);
340 dup = kstrdup(search, GFP_KERNEL);
341 if (!dup)
342 return -ENOMEM;
343
344 strcpy(r->pattern, dup);
345 kfree(dup);
346
347 r->len = strlen(r->pattern);
348
349 switch (type) {
350 case MATCH_FULL:
351 r->match = regex_match_full;
352 break;
353 case MATCH_FRONT_ONLY:
354 r->match = regex_match_front;
355 break;
356 case MATCH_MIDDLE_ONLY:
357 r->match = regex_match_middle;
358 break;
359 case MATCH_END_ONLY:
360 r->match = regex_match_end;
361 break;
362 }
363
364 pred->not ^= not;
365
366 return 0;
367}
368
7ce7e424
TZ
369/* return 1 if event matches, 0 otherwise (discard) */
370int filter_match_preds(struct ftrace_event_call *call, void *rec)
371{
30e673b2 372 struct event_filter *filter = call->filter;
8b372562
TZ
373 int match, top = 0, val1 = 0, val2 = 0;
374 int stack[MAX_FILTER_PRED];
7ce7e424 375 struct filter_pred *pred;
8b372562 376 int i;
7ce7e424 377
30e673b2
TZ
378 for (i = 0; i < filter->n_preds; i++) {
379 pred = filter->preds[i];
8b372562
TZ
380 if (!pred->pop_n) {
381 match = pred->fn(pred, rec, val1, val2);
382 stack[top++] = match;
0a19e53c 383 continue;
8b372562
TZ
384 }
385 if (pred->pop_n > top) {
386 WARN_ON_ONCE(1);
387 return 0;
388 }
389 val1 = stack[--top];
390 val2 = stack[--top];
391 match = pred->fn(pred, rec, val1, val2);
392 stack[top++] = match;
7ce7e424
TZ
393 }
394
8b372562 395 return stack[--top];
7ce7e424 396}
17c873ec 397EXPORT_SYMBOL_GPL(filter_match_preds);
7ce7e424 398
8b372562 399static void parse_error(struct filter_parse_state *ps, int err, int pos)
7ce7e424 400{
8b372562
TZ
401 ps->lasterr = err;
402 ps->lasterr_pos = pos;
403}
7ce7e424 404
8b372562
TZ
405static void remove_filter_string(struct event_filter *filter)
406{
407 kfree(filter->filter_string);
408 filter->filter_string = NULL;
409}
410
411static int replace_filter_string(struct event_filter *filter,
412 char *filter_string)
413{
414 kfree(filter->filter_string);
415 filter->filter_string = kstrdup(filter_string, GFP_KERNEL);
416 if (!filter->filter_string)
417 return -ENOMEM;
418
419 return 0;
420}
421
422static int append_filter_string(struct event_filter *filter,
423 char *string)
424{
425 int newlen;
426 char *new_filter_string;
427
428 BUG_ON(!filter->filter_string);
429 newlen = strlen(filter->filter_string) + strlen(string) + 1;
430 new_filter_string = kmalloc(newlen, GFP_KERNEL);
431 if (!new_filter_string)
432 return -ENOMEM;
433
434 strcpy(new_filter_string, filter->filter_string);
435 strcat(new_filter_string, string);
436 kfree(filter->filter_string);
437 filter->filter_string = new_filter_string;
438
439 return 0;
440}
441
442static void append_filter_err(struct filter_parse_state *ps,
443 struct event_filter *filter)
444{
445 int pos = ps->lasterr_pos;
446 char *buf, *pbuf;
447
448 buf = (char *)__get_free_page(GFP_TEMPORARY);
449 if (!buf)
4bda2d51 450 return;
7ce7e424 451
8b372562
TZ
452 append_filter_string(filter, "\n");
453 memset(buf, ' ', PAGE_SIZE);
454 if (pos > PAGE_SIZE - 128)
455 pos = 0;
456 buf[pos] = '^';
457 pbuf = &buf[pos] + 1;
458
459 sprintf(pbuf, "\nparse_error: %s\n", err_text[ps->lasterr]);
460 append_filter_string(filter, buf);
461 free_page((unsigned long) buf);
7ce7e424
TZ
462}
463
8b372562 464void print_event_filter(struct ftrace_event_call *call, struct trace_seq *s)
ac1adc55 465{
8b372562
TZ
466 struct event_filter *filter = call->filter;
467
00e95830 468 mutex_lock(&event_mutex);
8e254c1d 469 if (filter && filter->filter_string)
8b372562
TZ
470 trace_seq_printf(s, "%s\n", filter->filter_string);
471 else
472 trace_seq_printf(s, "none\n");
00e95830 473 mutex_unlock(&event_mutex);
ac1adc55
TZ
474}
475
8b372562 476void print_subsystem_event_filter(struct event_subsystem *system,
ac1adc55
TZ
477 struct trace_seq *s)
478{
8b372562
TZ
479 struct event_filter *filter = system->filter;
480
00e95830 481 mutex_lock(&event_mutex);
8e254c1d 482 if (filter && filter->filter_string)
8b372562
TZ
483 trace_seq_printf(s, "%s\n", filter->filter_string);
484 else
485 trace_seq_printf(s, "none\n");
00e95830 486 mutex_unlock(&event_mutex);
ac1adc55
TZ
487}
488
7ce7e424
TZ
489static struct ftrace_event_field *
490find_event_field(struct ftrace_event_call *call, char *name)
491{
1fc2d5c1 492 struct ftrace_event_field *field;
7ce7e424 493
1fc2d5c1 494 list_for_each_entry(field, &call->fields, link) {
7ce7e424
TZ
495 if (!strcmp(field->name, name))
496 return field;
497 }
498
499 return NULL;
500}
501
8b372562 502static void filter_free_pred(struct filter_pred *pred)
7ce7e424
TZ
503{
504 if (!pred)
505 return;
506
507 kfree(pred->field_name);
7ce7e424
TZ
508 kfree(pred);
509}
510
0a19e53c
TZ
511static void filter_clear_pred(struct filter_pred *pred)
512{
513 kfree(pred->field_name);
514 pred->field_name = NULL;
1889d209 515 pred->regex.len = 0;
0a19e53c
TZ
516}
517
518static int filter_set_pred(struct filter_pred *dest,
519 struct filter_pred *src,
520 filter_pred_fn_t fn)
521{
522 *dest = *src;
8b372562
TZ
523 if (src->field_name) {
524 dest->field_name = kstrdup(src->field_name, GFP_KERNEL);
525 if (!dest->field_name)
526 return -ENOMEM;
527 }
0a19e53c
TZ
528 dest->fn = fn;
529
530 return 0;
531}
532
8b372562 533static void filter_disable_preds(struct ftrace_event_call *call)
7ce7e424 534{
30e673b2 535 struct event_filter *filter = call->filter;
7ce7e424
TZ
536 int i;
537
30e673b2
TZ
538 call->filter_active = 0;
539 filter->n_preds = 0;
0a19e53c
TZ
540
541 for (i = 0; i < MAX_FILTER_PRED; i++)
30e673b2 542 filter->preds[i]->fn = filter_pred_none;
0a19e53c
TZ
543}
544
2df75e41
LZ
545void destroy_preds(struct ftrace_event_call *call)
546{
547 struct event_filter *filter = call->filter;
548 int i;
549
8e254c1d
LZ
550 if (!filter)
551 return;
552
2df75e41
LZ
553 for (i = 0; i < MAX_FILTER_PRED; i++) {
554 if (filter->preds[i])
555 filter_free_pred(filter->preds[i]);
556 }
557 kfree(filter->preds);
57be8887 558 kfree(filter->filter_string);
2df75e41
LZ
559 kfree(filter);
560 call->filter = NULL;
561}
562
8e254c1d 563static int init_preds(struct ftrace_event_call *call)
0a19e53c 564{
30e673b2 565 struct event_filter *filter;
0a19e53c
TZ
566 struct filter_pred *pred;
567 int i;
568
c58b4321
LZ
569 if (call->filter)
570 return 0;
571
30e673b2
TZ
572 filter = call->filter = kzalloc(sizeof(*filter), GFP_KERNEL);
573 if (!call->filter)
0a19e53c
TZ
574 return -ENOMEM;
575
30e673b2
TZ
576 filter->n_preds = 0;
577
578 filter->preds = kzalloc(MAX_FILTER_PRED * sizeof(pred), GFP_KERNEL);
579 if (!filter->preds)
580 goto oom;
581
0a19e53c
TZ
582 for (i = 0; i < MAX_FILTER_PRED; i++) {
583 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
584 if (!pred)
585 goto oom;
586 pred->fn = filter_pred_none;
30e673b2 587 filter->preds[i] = pred;
0a19e53c
TZ
588 }
589
590 return 0;
591
592oom:
2df75e41 593 destroy_preds(call);
0a19e53c
TZ
594
595 return -ENOMEM;
7ce7e424 596}
8e254c1d
LZ
597
598static int init_subsystem_preds(struct event_subsystem *system)
599{
600 struct ftrace_event_call *call;
601 int err;
602
603 list_for_each_entry(call, &ftrace_events, list) {
604 if (!call->define_fields)
605 continue;
606
607 if (strcmp(call->system, system->name) != 0)
608 continue;
609
c58b4321
LZ
610 err = init_preds(call);
611 if (err)
612 return err;
8e254c1d
LZ
613 }
614
615 return 0;
616}
7ce7e424 617
fce29d15 618static void filter_free_subsystem_preds(struct event_subsystem *system)
cfb180f3 619{
a59fd602 620 struct ftrace_event_call *call;
cfb180f3 621
a59fd602 622 list_for_each_entry(call, &ftrace_events, list) {
e1112b4d 623 if (!call->define_fields)
cfb180f3
TZ
624 continue;
625
8e254c1d
LZ
626 if (strcmp(call->system, system->name) != 0)
627 continue;
628
8e254c1d
LZ
629 filter_disable_preds(call);
630 remove_filter_string(call->filter);
cfb180f3
TZ
631 }
632}
633
8b372562
TZ
634static int filter_add_pred_fn(struct filter_parse_state *ps,
635 struct ftrace_event_call *call,
ac1adc55
TZ
636 struct filter_pred *pred,
637 filter_pred_fn_t fn)
7ce7e424 638{
30e673b2 639 struct event_filter *filter = call->filter;
0a19e53c 640 int idx, err;
7ce7e424 641
8b372562
TZ
642 if (filter->n_preds == MAX_FILTER_PRED) {
643 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
0a19e53c 644 return -ENOSPC;
8b372562 645 }
7ce7e424 646
30e673b2
TZ
647 idx = filter->n_preds;
648 filter_clear_pred(filter->preds[idx]);
649 err = filter_set_pred(filter->preds[idx], pred, fn);
0a19e53c
TZ
650 if (err)
651 return err;
652
30e673b2
TZ
653 filter->n_preds++;
654 call->filter_active = 1;
7ce7e424 655
0a19e53c 656 return 0;
7ce7e424
TZ
657}
658
aa38e9fc 659int filter_assign_type(const char *type)
7ce7e424 660{
7fcb7c47
LZ
661 if (strstr(type, "__data_loc") && strstr(type, "char"))
662 return FILTER_DYN_STRING;
663
7ce7e424 664 if (strchr(type, '[') && strstr(type, "char"))
e8808c10
FW
665 return FILTER_STATIC_STRING;
666
aa38e9fc
LZ
667 return FILTER_OTHER;
668}
669
670static bool is_string_field(struct ftrace_event_field *field)
671{
672 return field->filter_type == FILTER_DYN_STRING ||
87a342f5
LZ
673 field->filter_type == FILTER_STATIC_STRING ||
674 field->filter_type == FILTER_PTR_STRING;
7ce7e424
TZ
675}
676
8b372562
TZ
677static int is_legal_op(struct ftrace_event_field *field, int op)
678{
aa38e9fc 679 if (is_string_field(field) && (op != OP_EQ && op != OP_NE))
8b372562
TZ
680 return 0;
681
682 return 1;
683}
684
685static filter_pred_fn_t select_comparison_fn(int op, int field_size,
686 int field_is_signed)
687{
688 filter_pred_fn_t fn = NULL;
689
690 switch (field_size) {
691 case 8:
692 if (op == OP_EQ || op == OP_NE)
693 fn = filter_pred_64;
694 else if (field_is_signed)
695 fn = filter_pred_s64;
696 else
697 fn = filter_pred_u64;
698 break;
699 case 4:
700 if (op == OP_EQ || op == OP_NE)
701 fn = filter_pred_32;
702 else if (field_is_signed)
703 fn = filter_pred_s32;
704 else
705 fn = filter_pred_u32;
706 break;
707 case 2:
708 if (op == OP_EQ || op == OP_NE)
709 fn = filter_pred_16;
710 else if (field_is_signed)
711 fn = filter_pred_s16;
712 else
713 fn = filter_pred_u16;
714 break;
715 case 1:
716 if (op == OP_EQ || op == OP_NE)
717 fn = filter_pred_8;
718 else if (field_is_signed)
719 fn = filter_pred_s8;
720 else
721 fn = filter_pred_u8;
722 break;
723 }
724
725 return fn;
726}
727
728static int filter_add_pred(struct filter_parse_state *ps,
729 struct ftrace_event_call *call,
1f9963cb
LZ
730 struct filter_pred *pred,
731 bool dry_run)
7ce7e424
TZ
732{
733 struct ftrace_event_field *field;
0a19e53c 734 filter_pred_fn_t fn;
f66578a7 735 unsigned long long val;
5e4904cb 736 int ret;
7ce7e424 737
8b372562
TZ
738 pred->fn = filter_pred_none;
739
740 if (pred->op == OP_AND) {
741 pred->pop_n = 2;
1f9963cb
LZ
742 fn = filter_pred_and;
743 goto add_pred_fn;
8b372562
TZ
744 } else if (pred->op == OP_OR) {
745 pred->pop_n = 2;
1f9963cb
LZ
746 fn = filter_pred_or;
747 goto add_pred_fn;
8b372562
TZ
748 }
749
7ce7e424 750 field = find_event_field(call, pred->field_name);
8b372562
TZ
751 if (!field) {
752 parse_error(ps, FILT_ERR_FIELD_NOT_FOUND, 0);
7ce7e424 753 return -EINVAL;
8b372562 754 }
7ce7e424
TZ
755
756 pred->offset = field->offset;
757
8b372562
TZ
758 if (!is_legal_op(field, pred->op)) {
759 parse_error(ps, FILT_ERR_ILLEGAL_FIELD_OP, 0);
760 return -EINVAL;
761 }
762
aa38e9fc 763 if (is_string_field(field)) {
1889d209
FW
764 ret = filter_build_regex(pred);
765 if (ret)
766 return ret;
87a342f5 767
1889d209 768 if (field->filter_type == FILTER_STATIC_STRING) {
e8808c10 769 fn = filter_pred_string;
1889d209
FW
770 pred->regex.field_len = field->size;
771 } else if (field->filter_type == FILTER_DYN_STRING)
772 fn = filter_pred_strloc;
87a342f5
LZ
773 else {
774 fn = filter_pred_pchar;
1889d209 775 pred->regex.field_len = strlen(pred->regex.pattern);
87a342f5 776 }
9f58a159 777 } else {
5e4904cb 778 if (field->is_signed)
1889d209 779 ret = strict_strtoll(pred->regex.pattern, 0, &val);
5e4904cb 780 else
1889d209 781 ret = strict_strtoull(pred->regex.pattern, 0, &val);
5e4904cb 782 if (ret) {
8b372562 783 parse_error(ps, FILT_ERR_ILLEGAL_INTVAL, 0);
9f58a159 784 return -EINVAL;
8b372562 785 }
f66578a7 786 pred->val = val;
7ce7e424 787
1f9963cb
LZ
788 fn = select_comparison_fn(pred->op, field->size,
789 field->is_signed);
790 if (!fn) {
791 parse_error(ps, FILT_ERR_INVALID_OP, 0);
792 return -EINVAL;
793 }
7ce7e424
TZ
794 }
795
8b372562
TZ
796 if (pred->op == OP_NE)
797 pred->not = 1;
ac1adc55 798
1f9963cb
LZ
799add_pred_fn:
800 if (!dry_run)
801 return filter_add_pred_fn(ps, call, pred, fn);
802 return 0;
cfb180f3
TZ
803}
804
8b372562
TZ
805static void parse_init(struct filter_parse_state *ps,
806 struct filter_op *ops,
807 char *infix_string)
808{
809 memset(ps, '\0', sizeof(*ps));
810
811 ps->infix.string = infix_string;
812 ps->infix.cnt = strlen(infix_string);
813 ps->ops = ops;
814
815 INIT_LIST_HEAD(&ps->opstack);
816 INIT_LIST_HEAD(&ps->postfix);
817}
818
819static char infix_next(struct filter_parse_state *ps)
820{
821 ps->infix.cnt--;
822
823 return ps->infix.string[ps->infix.tail++];
824}
825
826static char infix_peek(struct filter_parse_state *ps)
827{
828 if (ps->infix.tail == strlen(ps->infix.string))
829 return 0;
830
831 return ps->infix.string[ps->infix.tail];
832}
833
834static void infix_advance(struct filter_parse_state *ps)
835{
836 ps->infix.cnt--;
837 ps->infix.tail++;
838}
839
840static inline int is_precedence_lower(struct filter_parse_state *ps,
841 int a, int b)
842{
843 return ps->ops[a].precedence < ps->ops[b].precedence;
844}
845
846static inline int is_op_char(struct filter_parse_state *ps, char c)
847{
848 int i;
849
850 for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
851 if (ps->ops[i].string[0] == c)
852 return 1;
853 }
c4cff064 854
0a19e53c 855 return 0;
cfb180f3
TZ
856}
857
8b372562
TZ
858static int infix_get_op(struct filter_parse_state *ps, char firstc)
859{
860 char nextc = infix_peek(ps);
861 char opstr[3];
862 int i;
863
864 opstr[0] = firstc;
865 opstr[1] = nextc;
866 opstr[2] = '\0';
867
868 for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
869 if (!strcmp(opstr, ps->ops[i].string)) {
870 infix_advance(ps);
871 return ps->ops[i].id;
7ce7e424 872 }
8b372562
TZ
873 }
874
875 opstr[1] = '\0';
876
877 for (i = 0; strcmp(ps->ops[i].string, "OP_NONE"); i++) {
878 if (!strcmp(opstr, ps->ops[i].string))
879 return ps->ops[i].id;
880 }
881
882 return OP_NONE;
883}
884
885static inline void clear_operand_string(struct filter_parse_state *ps)
886{
887 memset(ps->operand.string, '\0', MAX_FILTER_STR_VAL);
888 ps->operand.tail = 0;
889}
890
891static inline int append_operand_char(struct filter_parse_state *ps, char c)
892{
5872144f 893 if (ps->operand.tail == MAX_FILTER_STR_VAL - 1)
8b372562
TZ
894 return -EINVAL;
895
896 ps->operand.string[ps->operand.tail++] = c;
897
898 return 0;
899}
900
901static int filter_opstack_push(struct filter_parse_state *ps, int op)
902{
903 struct opstack_op *opstack_op;
904
905 opstack_op = kmalloc(sizeof(*opstack_op), GFP_KERNEL);
906 if (!opstack_op)
907 return -ENOMEM;
908
909 opstack_op->op = op;
910 list_add(&opstack_op->list, &ps->opstack);
911
912 return 0;
913}
914
915static int filter_opstack_empty(struct filter_parse_state *ps)
916{
917 return list_empty(&ps->opstack);
918}
919
920static int filter_opstack_top(struct filter_parse_state *ps)
921{
922 struct opstack_op *opstack_op;
923
924 if (filter_opstack_empty(ps))
925 return OP_NONE;
926
927 opstack_op = list_first_entry(&ps->opstack, struct opstack_op, list);
928
929 return opstack_op->op;
930}
931
932static int filter_opstack_pop(struct filter_parse_state *ps)
933{
934 struct opstack_op *opstack_op;
935 int op;
936
937 if (filter_opstack_empty(ps))
938 return OP_NONE;
939
940 opstack_op = list_first_entry(&ps->opstack, struct opstack_op, list);
941 op = opstack_op->op;
942 list_del(&opstack_op->list);
943
944 kfree(opstack_op);
945
946 return op;
947}
948
949static void filter_opstack_clear(struct filter_parse_state *ps)
950{
951 while (!filter_opstack_empty(ps))
952 filter_opstack_pop(ps);
953}
954
955static char *curr_operand(struct filter_parse_state *ps)
956{
957 return ps->operand.string;
958}
959
960static int postfix_append_operand(struct filter_parse_state *ps, char *operand)
961{
962 struct postfix_elt *elt;
963
964 elt = kmalloc(sizeof(*elt), GFP_KERNEL);
965 if (!elt)
966 return -ENOMEM;
967
968 elt->op = OP_NONE;
969 elt->operand = kstrdup(operand, GFP_KERNEL);
970 if (!elt->operand) {
971 kfree(elt);
972 return -ENOMEM;
973 }
974
975 list_add_tail(&elt->list, &ps->postfix);
976
977 return 0;
978}
979
980static int postfix_append_op(struct filter_parse_state *ps, int op)
981{
982 struct postfix_elt *elt;
983
984 elt = kmalloc(sizeof(*elt), GFP_KERNEL);
985 if (!elt)
986 return -ENOMEM;
987
988 elt->op = op;
989 elt->operand = NULL;
990
991 list_add_tail(&elt->list, &ps->postfix);
992
993 return 0;
994}
995
996static void postfix_clear(struct filter_parse_state *ps)
997{
998 struct postfix_elt *elt;
999
1000 while (!list_empty(&ps->postfix)) {
1001 elt = list_first_entry(&ps->postfix, struct postfix_elt, list);
8b372562 1002 list_del(&elt->list);
8ad80731
LZ
1003 kfree(elt->operand);
1004 kfree(elt);
8b372562
TZ
1005 }
1006}
1007
1008static int filter_parse(struct filter_parse_state *ps)
1009{
5928c3cc 1010 int in_string = 0;
8b372562
TZ
1011 int op, top_op;
1012 char ch;
1013
1014 while ((ch = infix_next(ps))) {
5928c3cc
FW
1015 if (ch == '"') {
1016 in_string ^= 1;
1017 continue;
1018 }
1019
1020 if (in_string)
1021 goto parse_operand;
1022
8b372562
TZ
1023 if (isspace(ch))
1024 continue;
1025
1026 if (is_op_char(ps, ch)) {
1027 op = infix_get_op(ps, ch);
1028 if (op == OP_NONE) {
1029 parse_error(ps, FILT_ERR_INVALID_OP, 0);
7ce7e424
TZ
1030 return -EINVAL;
1031 }
8b372562
TZ
1032
1033 if (strlen(curr_operand(ps))) {
1034 postfix_append_operand(ps, curr_operand(ps));
1035 clear_operand_string(ps);
1036 }
1037
1038 while (!filter_opstack_empty(ps)) {
1039 top_op = filter_opstack_top(ps);
1040 if (!is_precedence_lower(ps, top_op, op)) {
1041 top_op = filter_opstack_pop(ps);
1042 postfix_append_op(ps, top_op);
1043 continue;
1044 }
1045 break;
1046 }
1047
1048 filter_opstack_push(ps, op);
7ce7e424
TZ
1049 continue;
1050 }
8b372562
TZ
1051
1052 if (ch == '(') {
1053 filter_opstack_push(ps, OP_OPEN_PAREN);
1054 continue;
1055 }
1056
1057 if (ch == ')') {
1058 if (strlen(curr_operand(ps))) {
1059 postfix_append_operand(ps, curr_operand(ps));
1060 clear_operand_string(ps);
1061 }
1062
1063 top_op = filter_opstack_pop(ps);
1064 while (top_op != OP_NONE) {
1065 if (top_op == OP_OPEN_PAREN)
1066 break;
1067 postfix_append_op(ps, top_op);
1068 top_op = filter_opstack_pop(ps);
1069 }
1070 if (top_op == OP_NONE) {
1071 parse_error(ps, FILT_ERR_UNBALANCED_PAREN, 0);
1072 return -EINVAL;
7ce7e424 1073 }
7ce7e424
TZ
1074 continue;
1075 }
5928c3cc 1076parse_operand:
8b372562
TZ
1077 if (append_operand_char(ps, ch)) {
1078 parse_error(ps, FILT_ERR_OPERAND_TOO_LONG, 0);
1079 return -EINVAL;
1080 }
1081 }
1082
1083 if (strlen(curr_operand(ps)))
1084 postfix_append_operand(ps, curr_operand(ps));
1085
1086 while (!filter_opstack_empty(ps)) {
1087 top_op = filter_opstack_pop(ps);
1088 if (top_op == OP_NONE)
1089 break;
1090 if (top_op == OP_OPEN_PAREN) {
1091 parse_error(ps, FILT_ERR_UNBALANCED_PAREN, 0);
1092 return -EINVAL;
1093 }
1094 postfix_append_op(ps, top_op);
1095 }
1096
1097 return 0;
1098}
1099
1100static struct filter_pred *create_pred(int op, char *operand1, char *operand2)
1101{
1102 struct filter_pred *pred;
1103
1104 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
1105 if (!pred)
1106 return NULL;
1107
1108 pred->field_name = kstrdup(operand1, GFP_KERNEL);
1109 if (!pred->field_name) {
1110 kfree(pred);
1111 return NULL;
1112 }
1113
1889d209
FW
1114 strcpy(pred->regex.pattern, operand2);
1115 pred->regex.len = strlen(pred->regex.pattern);
8b372562
TZ
1116
1117 pred->op = op;
1118
1119 return pred;
1120}
1121
1122static struct filter_pred *create_logical_pred(int op)
1123{
1124 struct filter_pred *pred;
1125
1126 pred = kzalloc(sizeof(*pred), GFP_KERNEL);
1127 if (!pred)
1128 return NULL;
1129
1130 pred->op = op;
1131
1132 return pred;
1133}
1134
1135static int check_preds(struct filter_parse_state *ps)
1136{
1137 int n_normal_preds = 0, n_logical_preds = 0;
1138 struct postfix_elt *elt;
1139
1140 list_for_each_entry(elt, &ps->postfix, list) {
1141 if (elt->op == OP_NONE)
1142 continue;
1143
1144 if (elt->op == OP_AND || elt->op == OP_OR) {
1145 n_logical_preds++;
1146 continue;
7ce7e424 1147 }
8b372562 1148 n_normal_preds++;
7ce7e424
TZ
1149 }
1150
8b372562
TZ
1151 if (!n_normal_preds || n_logical_preds >= n_normal_preds) {
1152 parse_error(ps, FILT_ERR_INVALID_FILTER, 0);
bcabd91c
LZ
1153 return -EINVAL;
1154 }
1155
8b372562
TZ
1156 return 0;
1157}
f66578a7 1158
fce29d15 1159static int replace_preds(struct ftrace_event_call *call,
8b372562 1160 struct filter_parse_state *ps,
1f9963cb
LZ
1161 char *filter_string,
1162 bool dry_run)
8b372562
TZ
1163{
1164 char *operand1 = NULL, *operand2 = NULL;
1165 struct filter_pred *pred;
1166 struct postfix_elt *elt;
1167 int err;
1f9963cb 1168 int n_preds = 0;
8b372562
TZ
1169
1170 err = check_preds(ps);
1171 if (err)
1172 return err;
1173
1174 list_for_each_entry(elt, &ps->postfix, list) {
1175 if (elt->op == OP_NONE) {
1176 if (!operand1)
1177 operand1 = elt->operand;
1178 else if (!operand2)
1179 operand2 = elt->operand;
1180 else {
1181 parse_error(ps, FILT_ERR_TOO_MANY_OPERANDS, 0);
1182 return -EINVAL;
1183 }
1184 continue;
1185 }
1186
1f9963cb
LZ
1187 if (n_preds++ == MAX_FILTER_PRED) {
1188 parse_error(ps, FILT_ERR_TOO_MANY_PREDS, 0);
1189 return -ENOSPC;
1190 }
1191
8b372562
TZ
1192 if (elt->op == OP_AND || elt->op == OP_OR) {
1193 pred = create_logical_pred(elt->op);
1f9963cb 1194 goto add_pred;
8b372562
TZ
1195 }
1196
1197 if (!operand1 || !operand2) {
1198 parse_error(ps, FILT_ERR_MISSING_FIELD, 0);
1199 return -EINVAL;
1200 }
1201
1202 pred = create_pred(elt->op, operand1, operand2);
1f9963cb 1203add_pred:
fb82ad71
TZ
1204 if (!pred)
1205 return -ENOMEM;
fce29d15 1206 err = filter_add_pred(ps, call, pred, dry_run);
c5cb1836 1207 filter_free_pred(pred);
8b372562
TZ
1208 if (err)
1209 return err;
1210
1211 operand1 = operand2 = NULL;
1212 }
7ce7e424 1213
7ce7e424
TZ
1214 return 0;
1215}
1216
fce29d15
LZ
1217static int replace_system_preds(struct event_subsystem *system,
1218 struct filter_parse_state *ps,
1219 char *filter_string)
1220{
1221 struct ftrace_event_call *call;
1222 int err;
1223 bool fail = true;
1224
1225 list_for_each_entry(call, &ftrace_events, list) {
1226
1227 if (!call->define_fields)
1228 continue;
1229
1230 if (strcmp(call->system, system->name) != 0)
1231 continue;
1232
1233 /* try to see if the filter can be applied */
1234 err = replace_preds(call, ps, filter_string, true);
1235 if (err)
1236 continue;
1237
1238 /* really apply the filter */
1239 filter_disable_preds(call);
1240 err = replace_preds(call, ps, filter_string, false);
1241 if (err)
1242 filter_disable_preds(call);
1243 else
1244 replace_filter_string(call->filter, filter_string);
1245 fail = false;
1246 }
1247
1248 if (fail) {
1249 parse_error(ps, FILT_ERR_BAD_SUBSYS_FILTER, 0);
1250 return err;
1251 }
1252 return 0;
1253}
1254
8b372562
TZ
1255int apply_event_filter(struct ftrace_event_call *call, char *filter_string)
1256{
1257 int err;
1258
1259 struct filter_parse_state *ps;
1260
00e95830 1261 mutex_lock(&event_mutex);
8b372562 1262
8e254c1d
LZ
1263 err = init_preds(call);
1264 if (err)
1265 goto out_unlock;
1266
8b372562
TZ
1267 if (!strcmp(strstrip(filter_string), "0")) {
1268 filter_disable_preds(call);
1269 remove_filter_string(call->filter);
00e95830 1270 mutex_unlock(&event_mutex);
8b372562
TZ
1271 return 0;
1272 }
1273
8cd995b6 1274 err = -ENOMEM;
8b372562
TZ
1275 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1276 if (!ps)
8cd995b6 1277 goto out_unlock;
8b372562
TZ
1278
1279 filter_disable_preds(call);
1280 replace_filter_string(call->filter, filter_string);
1281
1282 parse_init(ps, filter_ops, filter_string);
1283 err = filter_parse(ps);
1284 if (err) {
1285 append_filter_err(ps, call->filter);
1286 goto out;
1287 }
1288
fce29d15 1289 err = replace_preds(call, ps, filter_string, false);
8b372562
TZ
1290 if (err)
1291 append_filter_err(ps, call->filter);
1292
1293out:
1294 filter_opstack_clear(ps);
1295 postfix_clear(ps);
1296 kfree(ps);
8cd995b6 1297out_unlock:
00e95830 1298 mutex_unlock(&event_mutex);
8b372562
TZ
1299
1300 return err;
1301}
1302
1303int apply_subsystem_event_filter(struct event_subsystem *system,
1304 char *filter_string)
1305{
1306 int err;
1307
1308 struct filter_parse_state *ps;
1309
00e95830 1310 mutex_lock(&event_mutex);
8b372562 1311
8e254c1d
LZ
1312 err = init_subsystem_preds(system);
1313 if (err)
1314 goto out_unlock;
1315
8b372562 1316 if (!strcmp(strstrip(filter_string), "0")) {
fce29d15 1317 filter_free_subsystem_preds(system);
8b372562 1318 remove_filter_string(system->filter);
00e95830 1319 mutex_unlock(&event_mutex);
8b372562
TZ
1320 return 0;
1321 }
1322
8cd995b6 1323 err = -ENOMEM;
8b372562
TZ
1324 ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1325 if (!ps)
8cd995b6 1326 goto out_unlock;
8b372562 1327
8b372562
TZ
1328 replace_filter_string(system->filter, filter_string);
1329
1330 parse_init(ps, filter_ops, filter_string);
1331 err = filter_parse(ps);
1332 if (err) {
1333 append_filter_err(ps, system->filter);
1334 goto out;
1335 }
1336
fce29d15
LZ
1337 err = replace_system_preds(system, ps, filter_string);
1338 if (err)
8b372562
TZ
1339 append_filter_err(ps, system->filter);
1340
1341out:
1342 filter_opstack_clear(ps);
1343 postfix_clear(ps);
1344 kfree(ps);
8cd995b6 1345out_unlock:
00e95830 1346 mutex_unlock(&event_mutex);
8b372562
TZ
1347
1348 return err;
1349}
7ce7e424 1350