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