diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
index f3c18324b07a..903caf62a407 100644
--- a/kernel/trace/trace_events_filter.c
+++ b/kernel/trace/trace_events_filter.c
@@ -537,7 +537,7 @@ predicate_parse(const char *str, int nr_parens, int nr_preds,
inverts[N] = invert; /* #4 */
prog[N].target = N-1;
- len = parse_pred(next, data, ptr - str, pe, &prog[N].pred);
+ len = parse_pred(next, data, next - str, pe, &prog[N].pred);
if (len < 0) {
ret = len;
goto out_free;@@ -1694,12 +1694,15 @@ static int parse_pred(const char *str, void *data,
int ret;
int op;
int s;
+ int field_pos = 0;
+ int op_pos = 0;
int i = 0;
/* First find the field to associate to */
while (isspace(str[i]))
i++;
s = i;
+ field_pos = i;
while (isalnum(str[i]) || str[i] == '_')
i++;
@@ -1720,7 +1723,7 @@ static int parse_pred(const char *str, void *data,
field = trace_find_event_field(call, field_name);
kfree(field_name);
if (!field) {
- parse_error(pe, FILT_ERR_FIELD_NOT_FOUND, pos + i);
+ parse_error(pe, FILT_ERR_FIELD_NOT_FOUND, pos + field_pos);
return -EINVAL;
}
@@ -1739,6 +1742,8 @@ static int parse_pred(const char *str, void *data,
while (isspace(str[i]))
i++;
+ op_pos = i;
+
/* Make sure this op is supported */
for (op = 0; ops[op]; op++) {
/* This is why '<=' must come before '<' in ops[] */@@ -1747,7 +1752,7 @@ static int parse_pred(const char *str, void *data,
}
if (!ops[op]) {
- parse_error(pe, FILT_ERR_INVALID_OP, pos + i);
+ parse_error(pe, FILT_ERR_INVALID_OP, pos + op_pos);
goto err_free;
}
@@ -1844,7 +1849,7 @@ static int parse_pred(const char *str, void *data,
* (perf doesn't use it) and grab everything.
*/
if (strcmp(field->name, "ip") != 0) {
- parse_error(pe, FILT_ERR_IP_FIELD_ONLY, pos + i);
+ parse_error(pe, FILT_ERR_IP_FIELD_ONLY, pos + field_pos);
goto err_free;
}
pred->fn_num = FILTER_PRED_FN_NOP;@@ -2033,7 +2038,7 @@ static int parse_pred(const char *str, void *data,
case OP_EQ:
break;
default:
- parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + i);
+ parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + op_pos);
goto err_free;
}
@@ -2130,7 +2135,7 @@ static int parse_pred(const char *str, void *data,
}
if (op == OP_GLOB) {
- parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + i);
+ parse_error(pe, FILT_ERR_ILLEGAL_FIELD_OP, pos + op_pos);
goto err_free;
}
@@ -2169,7 +2174,7 @@ static int parse_pred(const char *str, void *data,
pred->fn_num = select_comparison_fn(pred->op, field->size,
field->is_signed);
if (pred->fn_num == FILTER_PRED_FN_NOP) {
- parse_error(pe, FILT_ERR_INVALID_OP, pos + i);
+ parse_error(pe, FILT_ERR_INVALID_OP, pos + op_pos);
goto err_free;
}
if (pred->op == OP_NE)diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/tracing-error-log.tc b/tools/testing/selftests/ftrace/test.d/ftrace/tracing-error-log.tc
index 6c190620db47..2c900873ce3c 100644
--- a/tools/testing/selftests/ftrace/test.d/ftrace/tracing-error-log.tc
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/tracing-error-log.tc
@@ -10,6 +10,6 @@ fail() { #msg
exit_fail
}
-ftrace_errlog_check 'event filter parse error' '((sig >= 10 && sig < 15) || dsig ^== 17) && comm != bash' 'events/signal/signal_generate/filter'
+ftrace_errlog_check 'event filter parse error' '((sig >= 10 && sig < 15) || ^dsig == 17) && comm != bash' 'events/signal/signal_generate/filter'
exit 0