aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_probe.c')
-rw-r--r--kernel/trace/trace_probe.c291
1 files changed, 205 insertions, 86 deletions
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 8f8411e7835f..a347faced959 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -13,6 +13,11 @@
13 13
14#include "trace_probe.h" 14#include "trace_probe.h"
15 15
16#undef C
17#define C(a, b) b
18
19static const char *trace_probe_err_text[] = { ERRORS };
20
16static const char *reserved_field_names[] = { 21static const char *reserved_field_names[] = {
17 "common_type", 22 "common_type",
18 "common_flags", 23 "common_flags",
@@ -133,6 +138,60 @@ fail:
133 return NULL; 138 return NULL;
134} 139}
135 140
141static struct trace_probe_log trace_probe_log;
142
143void trace_probe_log_init(const char *subsystem, int argc, const char **argv)
144{
145 trace_probe_log.subsystem = subsystem;
146 trace_probe_log.argc = argc;
147 trace_probe_log.argv = argv;
148 trace_probe_log.index = 0;
149}
150
151void trace_probe_log_clear(void)
152{
153 memset(&trace_probe_log, 0, sizeof(trace_probe_log));
154}
155
156void trace_probe_log_set_index(int index)
157{
158 trace_probe_log.index = index;
159}
160
161void __trace_probe_log_err(int offset, int err_type)
162{
163 char *command, *p;
164 int i, len = 0, pos = 0;
165
166 if (!trace_probe_log.argv)
167 return;
168
169 /* Recalcurate the length and allocate buffer */
170 for (i = 0; i < trace_probe_log.argc; i++) {
171 if (i == trace_probe_log.index)
172 pos = len;
173 len += strlen(trace_probe_log.argv[i]) + 1;
174 }
175 command = kzalloc(len, GFP_KERNEL);
176 if (!command)
177 return;
178
179 /* And make a command string from argv array */
180 p = command;
181 for (i = 0; i < trace_probe_log.argc; i++) {
182 len = strlen(trace_probe_log.argv[i]);
183 strcpy(p, trace_probe_log.argv[i]);
184 p[len] = ' ';
185 p += len + 1;
186 }
187 *(p - 1) = '\0';
188
189 tracing_log_err(NULL, trace_probe_log.subsystem, command,
190 trace_probe_err_text, err_type, pos + offset);
191
192 kfree(command);
193}
194
136/* Split symbol and offset. */ 195/* Split symbol and offset. */
137int traceprobe_split_symbol_offset(char *symbol, long *offset) 196int traceprobe_split_symbol_offset(char *symbol, long *offset)
138{ 197{
@@ -156,7 +215,7 @@ int traceprobe_split_symbol_offset(char *symbol, long *offset)
156 215
157/* @buf must has MAX_EVENT_NAME_LEN size */ 216/* @buf must has MAX_EVENT_NAME_LEN size */
158int traceprobe_parse_event_name(const char **pevent, const char **pgroup, 217int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
159 char *buf) 218 char *buf, int offset)
160{ 219{
161 const char *slash, *event = *pevent; 220 const char *slash, *event = *pevent;
162 int len; 221 int len;
@@ -164,32 +223,33 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
164 slash = strchr(event, '/'); 223 slash = strchr(event, '/');
165 if (slash) { 224 if (slash) {
166 if (slash == event) { 225 if (slash == event) {
167 pr_info("Group name is not specified\n"); 226 trace_probe_log_err(offset, NO_GROUP_NAME);
168 return -EINVAL; 227 return -EINVAL;
169 } 228 }
170 if (slash - event + 1 > MAX_EVENT_NAME_LEN) { 229 if (slash - event + 1 > MAX_EVENT_NAME_LEN) {
171 pr_info("Group name is too long\n"); 230 trace_probe_log_err(offset, GROUP_TOO_LONG);
172 return -E2BIG; 231 return -EINVAL;
173 } 232 }
174 strlcpy(buf, event, slash - event + 1); 233 strlcpy(buf, event, slash - event + 1);
175 if (!is_good_name(buf)) { 234 if (!is_good_name(buf)) {
176 pr_info("Group name must follow the same rules as C identifiers\n"); 235 trace_probe_log_err(offset, BAD_GROUP_NAME);
177 return -EINVAL; 236 return -EINVAL;
178 } 237 }
179 *pgroup = buf; 238 *pgroup = buf;
180 *pevent = slash + 1; 239 *pevent = slash + 1;
240 offset += slash - event + 1;
181 event = *pevent; 241 event = *pevent;
182 } 242 }
183 len = strlen(event); 243 len = strlen(event);
184 if (len == 0) { 244 if (len == 0) {
185 pr_info("Event name is not specified\n"); 245 trace_probe_log_err(offset, NO_EVENT_NAME);
186 return -EINVAL; 246 return -EINVAL;
187 } else if (len > MAX_EVENT_NAME_LEN) { 247 } else if (len > MAX_EVENT_NAME_LEN) {
188 pr_info("Event name is too long\n"); 248 trace_probe_log_err(offset, EVENT_TOO_LONG);
189 return -E2BIG; 249 return -EINVAL;
190 } 250 }
191 if (!is_good_name(event)) { 251 if (!is_good_name(event)) {
192 pr_info("Event name must follow the same rules as C identifiers\n"); 252 trace_probe_log_err(offset, BAD_EVENT_NAME);
193 return -EINVAL; 253 return -EINVAL;
194 } 254 }
195 return 0; 255 return 0;
@@ -198,56 +258,67 @@ int traceprobe_parse_event_name(const char **pevent, const char **pgroup,
198#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) 258#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
199 259
200static int parse_probe_vars(char *arg, const struct fetch_type *t, 260static int parse_probe_vars(char *arg, const struct fetch_type *t,
201 struct fetch_insn *code, unsigned int flags) 261 struct fetch_insn *code, unsigned int flags, int offs)
202{ 262{
203 unsigned long param; 263 unsigned long param;
204 int ret = 0; 264 int ret = 0;
205 int len; 265 int len;
206 266
207 if (strcmp(arg, "retval") == 0) { 267 if (strcmp(arg, "retval") == 0) {
208 if (flags & TPARG_FL_RETURN) 268 if (flags & TPARG_FL_RETURN) {
209 code->op = FETCH_OP_RETVAL; 269 code->op = FETCH_OP_RETVAL;
210 else 270 } else {
271 trace_probe_log_err(offs, RETVAL_ON_PROBE);
211 ret = -EINVAL; 272 ret = -EINVAL;
273 }
212 } else if ((len = str_has_prefix(arg, "stack"))) { 274 } else if ((len = str_has_prefix(arg, "stack"))) {
213 if (arg[len] == '\0') { 275 if (arg[len] == '\0') {
214 code->op = FETCH_OP_STACKP; 276 code->op = FETCH_OP_STACKP;
215 } else if (isdigit(arg[len])) { 277 } else if (isdigit(arg[len])) {
216 ret = kstrtoul(arg + len, 10, &param); 278 ret = kstrtoul(arg + len, 10, &param);
217 if (ret || ((flags & TPARG_FL_KERNEL) && 279 if (ret) {
218 param > PARAM_MAX_STACK)) 280 goto inval_var;
281 } else if ((flags & TPARG_FL_KERNEL) &&
282 param > PARAM_MAX_STACK) {
283 trace_probe_log_err(offs, BAD_STACK_NUM);
219 ret = -EINVAL; 284 ret = -EINVAL;
220 else { 285 } else {
221 code->op = FETCH_OP_STACK; 286 code->op = FETCH_OP_STACK;
222 code->param = (unsigned int)param; 287 code->param = (unsigned int)param;
223 } 288 }
224 } else 289 } else
225 ret = -EINVAL; 290 goto inval_var;
226 } else if (strcmp(arg, "comm") == 0) { 291 } else if (strcmp(arg, "comm") == 0) {
227 code->op = FETCH_OP_COMM; 292 code->op = FETCH_OP_COMM;
228#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API 293#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
229 } else if (((flags & TPARG_FL_MASK) == 294 } else if (((flags & TPARG_FL_MASK) ==
230 (TPARG_FL_KERNEL | TPARG_FL_FENTRY)) && 295 (TPARG_FL_KERNEL | TPARG_FL_FENTRY)) &&
231 (len = str_has_prefix(arg, "arg"))) { 296 (len = str_has_prefix(arg, "arg"))) {
232 if (!isdigit(arg[len]))
233 return -EINVAL;
234 ret = kstrtoul(arg + len, 10, &param); 297 ret = kstrtoul(arg + len, 10, &param);
235 if (ret || !param || param > PARAM_MAX_STACK) 298 if (ret) {
299 goto inval_var;
300 } else if (!param || param > PARAM_MAX_STACK) {
301 trace_probe_log_err(offs, BAD_ARG_NUM);
236 return -EINVAL; 302 return -EINVAL;
303 }
237 code->op = FETCH_OP_ARG; 304 code->op = FETCH_OP_ARG;
238 code->param = (unsigned int)param - 1; 305 code->param = (unsigned int)param - 1;
239#endif 306#endif
240 } else 307 } else
241 ret = -EINVAL; 308 goto inval_var;
242 309
243 return ret; 310 return ret;
311
312inval_var:
313 trace_probe_log_err(offs, BAD_VAR);
314 return -EINVAL;
244} 315}
245 316
246/* Recursive argument parser */ 317/* Recursive argument parser */
247static int 318static int
248parse_probe_arg(char *arg, const struct fetch_type *type, 319parse_probe_arg(char *arg, const struct fetch_type *type,
249 struct fetch_insn **pcode, struct fetch_insn *end, 320 struct fetch_insn **pcode, struct fetch_insn *end,
250 unsigned int flags) 321 unsigned int flags, int offs)
251{ 322{
252 struct fetch_insn *code = *pcode; 323 struct fetch_insn *code = *pcode;
253 unsigned long param; 324 unsigned long param;
@@ -257,7 +328,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
257 328
258 switch (arg[0]) { 329 switch (arg[0]) {
259 case '$': 330 case '$':
260 ret = parse_probe_vars(arg + 1, type, code, flags); 331 ret = parse_probe_vars(arg + 1, type, code, flags, offs);
261 break; 332 break;
262 333
263 case '%': /* named register */ 334 case '%': /* named register */
@@ -266,47 +337,57 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
266 code->op = FETCH_OP_REG; 337 code->op = FETCH_OP_REG;
267 code->param = (unsigned int)ret; 338 code->param = (unsigned int)ret;
268 ret = 0; 339 ret = 0;
269 } 340 } else
341 trace_probe_log_err(offs, BAD_REG_NAME);
270 break; 342 break;
271 343
272 case '@': /* memory, file-offset or symbol */ 344 case '@': /* memory, file-offset or symbol */
273 if (isdigit(arg[1])) { 345 if (isdigit(arg[1])) {
274 ret = kstrtoul(arg + 1, 0, &param); 346 ret = kstrtoul(arg + 1, 0, &param);
275 if (ret) 347 if (ret) {
348 trace_probe_log_err(offs, BAD_MEM_ADDR);
276 break; 349 break;
350 }
277 /* load address */ 351 /* load address */
278 code->op = FETCH_OP_IMM; 352 code->op = FETCH_OP_IMM;
279 code->immediate = param; 353 code->immediate = param;
280 } else if (arg[1] == '+') { 354 } else if (arg[1] == '+') {
281 /* kprobes don't support file offsets */ 355 /* kprobes don't support file offsets */
282 if (flags & TPARG_FL_KERNEL) 356 if (flags & TPARG_FL_KERNEL) {
357 trace_probe_log_err(offs, FILE_ON_KPROBE);
283 return -EINVAL; 358 return -EINVAL;
284 359 }
285 ret = kstrtol(arg + 2, 0, &offset); 360 ret = kstrtol(arg + 2, 0, &offset);
286 if (ret) 361 if (ret) {
362 trace_probe_log_err(offs, BAD_FILE_OFFS);
287 break; 363 break;
364 }
288 365
289 code->op = FETCH_OP_FOFFS; 366 code->op = FETCH_OP_FOFFS;
290 code->immediate = (unsigned long)offset; // imm64? 367 code->immediate = (unsigned long)offset; // imm64?
291 } else { 368 } else {
292 /* uprobes don't support symbols */ 369 /* uprobes don't support symbols */
293 if (!(flags & TPARG_FL_KERNEL)) 370 if (!(flags & TPARG_FL_KERNEL)) {
371 trace_probe_log_err(offs, SYM_ON_UPROBE);
294 return -EINVAL; 372 return -EINVAL;
295 373 }
296 /* Preserve symbol for updating */ 374 /* Preserve symbol for updating */
297 code->op = FETCH_NOP_SYMBOL; 375 code->op = FETCH_NOP_SYMBOL;
298 code->data = kstrdup(arg + 1, GFP_KERNEL); 376 code->data = kstrdup(arg + 1, GFP_KERNEL);
299 if (!code->data) 377 if (!code->data)
300 return -ENOMEM; 378 return -ENOMEM;
301 if (++code == end) 379 if (++code == end) {
302 return -E2BIG; 380 trace_probe_log_err(offs, TOO_MANY_OPS);
303 381 return -EINVAL;
382 }
304 code->op = FETCH_OP_IMM; 383 code->op = FETCH_OP_IMM;
305 code->immediate = 0; 384 code->immediate = 0;
306 } 385 }
307 /* These are fetching from memory */ 386 /* These are fetching from memory */
308 if (++code == end) 387 if (++code == end) {
309 return -E2BIG; 388 trace_probe_log_err(offs, TOO_MANY_OPS);
389 return -EINVAL;
390 }
310 *pcode = code; 391 *pcode = code;
311 code->op = FETCH_OP_DEREF; 392 code->op = FETCH_OP_DEREF;
312 code->offset = offset; 393 code->offset = offset;
@@ -317,28 +398,38 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
317 /* fall through */ 398 /* fall through */
318 case '-': 399 case '-':
319 tmp = strchr(arg, '('); 400 tmp = strchr(arg, '(');
320 if (!tmp) 401 if (!tmp) {
402 trace_probe_log_err(offs, DEREF_NEED_BRACE);
321 return -EINVAL; 403 return -EINVAL;
322 404 }
323 *tmp = '\0'; 405 *tmp = '\0';
324 ret = kstrtol(arg, 0, &offset); 406 ret = kstrtol(arg, 0, &offset);
325 if (ret) 407 if (ret) {
408 trace_probe_log_err(offs, BAD_DEREF_OFFS);
326 break; 409 break;
327 410 }
411 offs += (tmp + 1 - arg) + (arg[0] != '-' ? 1 : 0);
328 arg = tmp + 1; 412 arg = tmp + 1;
329 tmp = strrchr(arg, ')'); 413 tmp = strrchr(arg, ')');
330 414 if (!tmp) {
331 if (tmp) { 415 trace_probe_log_err(offs + strlen(arg),
416 DEREF_OPEN_BRACE);
417 return -EINVAL;
418 } else {
332 const struct fetch_type *t2 = find_fetch_type(NULL); 419 const struct fetch_type *t2 = find_fetch_type(NULL);
333 420
334 *tmp = '\0'; 421 *tmp = '\0';
335 ret = parse_probe_arg(arg, t2, &code, end, flags); 422 ret = parse_probe_arg(arg, t2, &code, end, flags, offs);
336 if (ret) 423 if (ret)
337 break; 424 break;
338 if (code->op == FETCH_OP_COMM) 425 if (code->op == FETCH_OP_COMM) {
426 trace_probe_log_err(offs, COMM_CANT_DEREF);
339 return -EINVAL; 427 return -EINVAL;
340 if (++code == end) 428 }
341 return -E2BIG; 429 if (++code == end) {
430 trace_probe_log_err(offs, TOO_MANY_OPS);
431 return -EINVAL;
432 }
342 *pcode = code; 433 *pcode = code;
343 434
344 code->op = FETCH_OP_DEREF; 435 code->op = FETCH_OP_DEREF;
@@ -348,6 +439,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
348 } 439 }
349 if (!ret && code->op == FETCH_OP_NOP) { 440 if (!ret && code->op == FETCH_OP_NOP) {
350 /* Parsed, but do not find fetch method */ 441 /* Parsed, but do not find fetch method */
442 trace_probe_log_err(offs, BAD_FETCH_ARG);
351 ret = -EINVAL; 443 ret = -EINVAL;
352 } 444 }
353 return ret; 445 return ret;
@@ -379,7 +471,7 @@ static int __parse_bitfield_probe_arg(const char *bf,
379 return -EINVAL; 471 return -EINVAL;
380 code++; 472 code++;
381 if (code->op != FETCH_OP_NOP) 473 if (code->op != FETCH_OP_NOP)
382 return -E2BIG; 474 return -EINVAL;
383 *pcode = code; 475 *pcode = code;
384 476
385 code->op = FETCH_OP_MOD_BF; 477 code->op = FETCH_OP_MOD_BF;
@@ -392,44 +484,66 @@ static int __parse_bitfield_probe_arg(const char *bf,
392 484
393/* String length checking wrapper */ 485/* String length checking wrapper */
394static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size, 486static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
395 struct probe_arg *parg, unsigned int flags) 487 struct probe_arg *parg, unsigned int flags, int offset)
396{ 488{
397 struct fetch_insn *code, *scode, *tmp = NULL; 489 struct fetch_insn *code, *scode, *tmp = NULL;
398 char *t, *t2; 490 char *t, *t2, *t3;
399 int ret, len; 491 int ret, len;
400 492
401 if (strlen(arg) > MAX_ARGSTR_LEN) { 493 len = strlen(arg);
402 pr_info("Argument is too long.: %s\n", arg); 494 if (len > MAX_ARGSTR_LEN) {
403 return -ENOSPC; 495 trace_probe_log_err(offset, ARG_TOO_LONG);
496 return -EINVAL;
497 } else if (len == 0) {
498 trace_probe_log_err(offset, NO_ARG_BODY);
499 return -EINVAL;
404 } 500 }
501
405 parg->comm = kstrdup(arg, GFP_KERNEL); 502 parg->comm = kstrdup(arg, GFP_KERNEL);
406 if (!parg->comm) { 503 if (!parg->comm)
407 pr_info("Failed to allocate memory for command '%s'.\n", arg);
408 return -ENOMEM; 504 return -ENOMEM;
409 } 505
410 t = strchr(arg, ':'); 506 t = strchr(arg, ':');
411 if (t) { 507 if (t) {
412 *t = '\0'; 508 *t = '\0';
413 t2 = strchr(++t, '['); 509 t2 = strchr(++t, '[');
414 if (t2) { 510 if (t2) {
415 *t2 = '\0'; 511 *t2++ = '\0';
416 parg->count = simple_strtoul(t2 + 1, &t2, 0); 512 t3 = strchr(t2, ']');
417 if (strcmp(t2, "]") || parg->count == 0) 513 if (!t3) {
514 offset += t2 + strlen(t2) - arg;
515 trace_probe_log_err(offset,
516 ARRAY_NO_CLOSE);
517 return -EINVAL;
518 } else if (t3[1] != '\0') {
519 trace_probe_log_err(offset + t3 + 1 - arg,
520 BAD_ARRAY_SUFFIX);
418 return -EINVAL; 521 return -EINVAL;
419 if (parg->count > MAX_ARRAY_LEN) 522 }
420 return -E2BIG; 523 *t3 = '\0';
524 if (kstrtouint(t2, 0, &parg->count) || !parg->count) {
525 trace_probe_log_err(offset + t2 - arg,
526 BAD_ARRAY_NUM);
527 return -EINVAL;
528 }
529 if (parg->count > MAX_ARRAY_LEN) {
530 trace_probe_log_err(offset + t2 - arg,
531 ARRAY_TOO_BIG);
532 return -EINVAL;
533 }
421 } 534 }
422 } 535 }
423 /* 536
424 * The default type of $comm should be "string", and it can't be 537 /* Since $comm can not be dereferred, we can find $comm by strcmp */
425 * dereferenced. 538 if (strcmp(arg, "$comm") == 0) {
426 */ 539 /* The type of $comm must be "string", and not an array. */
427 if (!t && strcmp(arg, "$comm") == 0) 540 if (parg->count || (t && strcmp(t, "string")))
541 return -EINVAL;
428 parg->type = find_fetch_type("string"); 542 parg->type = find_fetch_type("string");
429 else 543 } else
430 parg->type = find_fetch_type(t); 544 parg->type = find_fetch_type(t);
431 if (!parg->type) { 545 if (!parg->type) {
432 pr_info("Unsupported type: %s\n", t); 546 trace_probe_log_err(offset + (t ? (t - arg) : 0), BAD_TYPE);
433 return -EINVAL; 547 return -EINVAL;
434 } 548 }
435 parg->offset = *size; 549 parg->offset = *size;
@@ -444,13 +558,13 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
444 parg->count); 558 parg->count);
445 } 559 }
446 560
447 code = tmp = kzalloc(sizeof(*code) * FETCH_INSN_MAX, GFP_KERNEL); 561 code = tmp = kcalloc(FETCH_INSN_MAX, sizeof(*code), GFP_KERNEL);
448 if (!code) 562 if (!code)
449 return -ENOMEM; 563 return -ENOMEM;
450 code[FETCH_INSN_MAX - 1].op = FETCH_OP_END; 564 code[FETCH_INSN_MAX - 1].op = FETCH_OP_END;
451 565
452 ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1], 566 ret = parse_probe_arg(arg, parg->type, &code, &code[FETCH_INSN_MAX - 1],
453 flags); 567 flags, offset);
454 if (ret) 568 if (ret)
455 goto fail; 569 goto fail;
456 570
@@ -458,7 +572,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
458 if (!strcmp(parg->type->name, "string")) { 572 if (!strcmp(parg->type->name, "string")) {
459 if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM && 573 if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM &&
460 code->op != FETCH_OP_COMM) { 574 code->op != FETCH_OP_COMM) {
461 pr_info("string only accepts memory or address.\n"); 575 trace_probe_log_err(offset + (t ? (t - arg) : 0),
576 BAD_STRING);
462 ret = -EINVAL; 577 ret = -EINVAL;
463 goto fail; 578 goto fail;
464 } 579 }
@@ -470,7 +585,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
470 */ 585 */
471 code++; 586 code++;
472 if (code->op != FETCH_OP_NOP) { 587 if (code->op != FETCH_OP_NOP) {
473 ret = -E2BIG; 588 trace_probe_log_err(offset, TOO_MANY_OPS);
589 ret = -EINVAL;
474 goto fail; 590 goto fail;
475 } 591 }
476 } 592 }
@@ -483,7 +599,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
483 } else { 599 } else {
484 code++; 600 code++;
485 if (code->op != FETCH_OP_NOP) { 601 if (code->op != FETCH_OP_NOP) {
486 ret = -E2BIG; 602 trace_probe_log_err(offset, TOO_MANY_OPS);
603 ret = -EINVAL;
487 goto fail; 604 goto fail;
488 } 605 }
489 code->op = FETCH_OP_ST_RAW; 606 code->op = FETCH_OP_ST_RAW;
@@ -493,20 +610,24 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
493 /* Modify operation */ 610 /* Modify operation */
494 if (t != NULL) { 611 if (t != NULL) {
495 ret = __parse_bitfield_probe_arg(t, parg->type, &code); 612 ret = __parse_bitfield_probe_arg(t, parg->type, &code);
496 if (ret) 613 if (ret) {
614 trace_probe_log_err(offset + t - arg, BAD_BITFIELD);
497 goto fail; 615 goto fail;
616 }
498 } 617 }
499 /* Loop(Array) operation */ 618 /* Loop(Array) operation */
500 if (parg->count) { 619 if (parg->count) {
501 if (scode->op != FETCH_OP_ST_MEM && 620 if (scode->op != FETCH_OP_ST_MEM &&
502 scode->op != FETCH_OP_ST_STRING) { 621 scode->op != FETCH_OP_ST_STRING) {
503 pr_info("array only accepts memory or address\n"); 622 trace_probe_log_err(offset + (t ? (t - arg) : 0),
623 BAD_STRING);
504 ret = -EINVAL; 624 ret = -EINVAL;
505 goto fail; 625 goto fail;
506 } 626 }
507 code++; 627 code++;
508 if (code->op != FETCH_OP_NOP) { 628 if (code->op != FETCH_OP_NOP) {
509 ret = -E2BIG; 629 trace_probe_log_err(offset, TOO_MANY_OPS);
630 ret = -EINVAL;
510 goto fail; 631 goto fail;
511 } 632 }
512 code->op = FETCH_OP_LP_ARRAY; 633 code->op = FETCH_OP_LP_ARRAY;
@@ -516,7 +637,7 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
516 code->op = FETCH_OP_END; 637 code->op = FETCH_OP_END;
517 638
518 /* Shrink down the code buffer */ 639 /* Shrink down the code buffer */
519 parg->code = kzalloc(sizeof(*code) * (code - tmp + 1), GFP_KERNEL); 640 parg->code = kcalloc(code - tmp + 1, sizeof(*code), GFP_KERNEL);
520 if (!parg->code) 641 if (!parg->code)
521 ret = -ENOMEM; 642 ret = -ENOMEM;
522 else 643 else
@@ -555,15 +676,19 @@ int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, char *arg,
555{ 676{
556 struct probe_arg *parg = &tp->args[i]; 677 struct probe_arg *parg = &tp->args[i];
557 char *body; 678 char *body;
558 int ret;
559 679
560 /* Increment count for freeing args in error case */ 680 /* Increment count for freeing args in error case */
561 tp->nr_args++; 681 tp->nr_args++;
562 682
563 body = strchr(arg, '='); 683 body = strchr(arg, '=');
564 if (body) { 684 if (body) {
565 if (body - arg > MAX_ARG_NAME_LEN || body == arg) 685 if (body - arg > MAX_ARG_NAME_LEN) {
686 trace_probe_log_err(0, ARG_NAME_TOO_LONG);
687 return -EINVAL;
688 } else if (body == arg) {
689 trace_probe_log_err(0, NO_ARG_NAME);
566 return -EINVAL; 690 return -EINVAL;
691 }
567 parg->name = kmemdup_nul(arg, body - arg, GFP_KERNEL); 692 parg->name = kmemdup_nul(arg, body - arg, GFP_KERNEL);
568 body++; 693 body++;
569 } else { 694 } else {
@@ -575,22 +700,16 @@ int traceprobe_parse_probe_arg(struct trace_probe *tp, int i, char *arg,
575 return -ENOMEM; 700 return -ENOMEM;
576 701
577 if (!is_good_name(parg->name)) { 702 if (!is_good_name(parg->name)) {
578 pr_info("Invalid argument[%d] name: %s\n", 703 trace_probe_log_err(0, BAD_ARG_NAME);
579 i, parg->name);
580 return -EINVAL; 704 return -EINVAL;
581 } 705 }
582
583 if (traceprobe_conflict_field_name(parg->name, tp->args, i)) { 706 if (traceprobe_conflict_field_name(parg->name, tp->args, i)) {
584 pr_info("Argument[%d]: '%s' conflicts with another field.\n", 707 trace_probe_log_err(0, USED_ARG_NAME);
585 i, parg->name);
586 return -EINVAL; 708 return -EINVAL;
587 } 709 }
588
589 /* Parse fetch argument */ 710 /* Parse fetch argument */
590 ret = traceprobe_parse_probe_arg_body(body, &tp->size, parg, flags); 711 return traceprobe_parse_probe_arg_body(body, &tp->size, parg, flags,
591 if (ret) 712 body - arg);
592 pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
593 return ret;
594} 713}
595 714
596void traceprobe_free_probe_arg(struct probe_arg *arg) 715void traceprobe_free_probe_arg(struct probe_arg *arg)