0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/kallsyms.h>
0010 #include <linux/security.h>
0011 #include <linux/mutex.h>
0012 #include <linux/slab.h>
0013 #include <linux/stacktrace.h>
0014 #include <linux/rculist.h>
0015 #include <linux/tracefs.h>
0016
0017
0018 #include <linux/trace_events.h>
0019 #include <trace/events/mmflags.h>
0020
0021 #include "trace_synth.h"
0022
0023 #undef ERRORS
0024 #define ERRORS \
0025 C(BAD_NAME, "Illegal name"), \
0026 C(INVALID_CMD, "Command must be of the form: <name> field[;field] ..."),\
0027 C(INVALID_DYN_CMD, "Command must be of the form: s or -:[synthetic/]<name> field[;field] ..."),\
0028 C(EVENT_EXISTS, "Event already exists"), \
0029 C(TOO_MANY_FIELDS, "Too many fields"), \
0030 C(INCOMPLETE_TYPE, "Incomplete type"), \
0031 C(INVALID_TYPE, "Invalid type"), \
0032 C(INVALID_FIELD, "Invalid field"), \
0033 C(INVALID_ARRAY_SPEC, "Invalid array specification"),
0034
0035 #undef C
0036 #define C(a, b) SYNTH_ERR_##a
0037
0038 enum { ERRORS };
0039
0040 #undef C
0041 #define C(a, b) b
0042
0043 static const char *err_text[] = { ERRORS };
0044
0045 static char *last_cmd;
0046
0047 static int errpos(const char *str)
0048 {
0049 if (!str || !last_cmd)
0050 return 0;
0051
0052 return err_pos(last_cmd, str);
0053 }
0054
0055 static void last_cmd_set(const char *str)
0056 {
0057 if (!str)
0058 return;
0059
0060 kfree(last_cmd);
0061
0062 last_cmd = kstrdup(str, GFP_KERNEL);
0063 }
0064
0065 static void synth_err(u8 err_type, u16 err_pos)
0066 {
0067 if (!last_cmd)
0068 return;
0069
0070 tracing_log_err(NULL, "synthetic_events", last_cmd, err_text,
0071 err_type, err_pos);
0072 }
0073
0074 static int create_synth_event(const char *raw_command);
0075 static int synth_event_show(struct seq_file *m, struct dyn_event *ev);
0076 static int synth_event_release(struct dyn_event *ev);
0077 static bool synth_event_is_busy(struct dyn_event *ev);
0078 static bool synth_event_match(const char *system, const char *event,
0079 int argc, const char **argv, struct dyn_event *ev);
0080
0081 static struct dyn_event_operations synth_event_ops = {
0082 .create = create_synth_event,
0083 .show = synth_event_show,
0084 .is_busy = synth_event_is_busy,
0085 .free = synth_event_release,
0086 .match = synth_event_match,
0087 };
0088
0089 static bool is_synth_event(struct dyn_event *ev)
0090 {
0091 return ev->ops == &synth_event_ops;
0092 }
0093
0094 static struct synth_event *to_synth_event(struct dyn_event *ev)
0095 {
0096 return container_of(ev, struct synth_event, devent);
0097 }
0098
0099 static bool synth_event_is_busy(struct dyn_event *ev)
0100 {
0101 struct synth_event *event = to_synth_event(ev);
0102
0103 return event->ref != 0;
0104 }
0105
0106 static bool synth_event_match(const char *system, const char *event,
0107 int argc, const char **argv, struct dyn_event *ev)
0108 {
0109 struct synth_event *sev = to_synth_event(ev);
0110
0111 return strcmp(sev->name, event) == 0 &&
0112 (!system || strcmp(system, SYNTH_SYSTEM) == 0);
0113 }
0114
0115 struct synth_trace_event {
0116 struct trace_entry ent;
0117 u64 fields[];
0118 };
0119
0120 static int synth_event_define_fields(struct trace_event_call *call)
0121 {
0122 struct synth_trace_event trace;
0123 int offset = offsetof(typeof(trace), fields);
0124 struct synth_event *event = call->data;
0125 unsigned int i, size, n_u64;
0126 char *name, *type;
0127 bool is_signed;
0128 int ret = 0;
0129
0130 for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
0131 size = event->fields[i]->size;
0132 is_signed = event->fields[i]->is_signed;
0133 type = event->fields[i]->type;
0134 name = event->fields[i]->name;
0135 ret = trace_define_field(call, type, name, offset, size,
0136 is_signed, FILTER_OTHER);
0137 if (ret)
0138 break;
0139
0140 event->fields[i]->offset = n_u64;
0141
0142 if (event->fields[i]->is_string && !event->fields[i]->is_dynamic) {
0143 offset += STR_VAR_LEN_MAX;
0144 n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
0145 } else {
0146 offset += sizeof(u64);
0147 n_u64++;
0148 }
0149 }
0150
0151 event->n_u64 = n_u64;
0152
0153 return ret;
0154 }
0155
0156 static bool synth_field_signed(char *type)
0157 {
0158 if (str_has_prefix(type, "u"))
0159 return false;
0160 if (strcmp(type, "gfp_t") == 0)
0161 return false;
0162
0163 return true;
0164 }
0165
0166 static int synth_field_is_string(char *type)
0167 {
0168 if (strstr(type, "char[") != NULL)
0169 return true;
0170
0171 return false;
0172 }
0173
0174 static int synth_field_string_size(char *type)
0175 {
0176 char buf[4], *end, *start;
0177 unsigned int len;
0178 int size, err;
0179
0180 start = strstr(type, "char[");
0181 if (start == NULL)
0182 return -EINVAL;
0183 start += sizeof("char[") - 1;
0184
0185 end = strchr(type, ']');
0186 if (!end || end < start || type + strlen(type) > end + 1)
0187 return -EINVAL;
0188
0189 len = end - start;
0190 if (len > 3)
0191 return -EINVAL;
0192
0193 if (len == 0)
0194 return 0;
0195
0196 strncpy(buf, start, len);
0197 buf[len] = '\0';
0198
0199 err = kstrtouint(buf, 0, &size);
0200 if (err)
0201 return err;
0202
0203 if (size > STR_VAR_LEN_MAX)
0204 return -EINVAL;
0205
0206 return size;
0207 }
0208
0209 static int synth_field_size(char *type)
0210 {
0211 int size = 0;
0212
0213 if (strcmp(type, "s64") == 0)
0214 size = sizeof(s64);
0215 else if (strcmp(type, "u64") == 0)
0216 size = sizeof(u64);
0217 else if (strcmp(type, "s32") == 0)
0218 size = sizeof(s32);
0219 else if (strcmp(type, "u32") == 0)
0220 size = sizeof(u32);
0221 else if (strcmp(type, "s16") == 0)
0222 size = sizeof(s16);
0223 else if (strcmp(type, "u16") == 0)
0224 size = sizeof(u16);
0225 else if (strcmp(type, "s8") == 0)
0226 size = sizeof(s8);
0227 else if (strcmp(type, "u8") == 0)
0228 size = sizeof(u8);
0229 else if (strcmp(type, "char") == 0)
0230 size = sizeof(char);
0231 else if (strcmp(type, "unsigned char") == 0)
0232 size = sizeof(unsigned char);
0233 else if (strcmp(type, "int") == 0)
0234 size = sizeof(int);
0235 else if (strcmp(type, "unsigned int") == 0)
0236 size = sizeof(unsigned int);
0237 else if (strcmp(type, "long") == 0)
0238 size = sizeof(long);
0239 else if (strcmp(type, "unsigned long") == 0)
0240 size = sizeof(unsigned long);
0241 else if (strcmp(type, "bool") == 0)
0242 size = sizeof(bool);
0243 else if (strcmp(type, "pid_t") == 0)
0244 size = sizeof(pid_t);
0245 else if (strcmp(type, "gfp_t") == 0)
0246 size = sizeof(gfp_t);
0247 else if (synth_field_is_string(type))
0248 size = synth_field_string_size(type);
0249
0250 return size;
0251 }
0252
0253 static const char *synth_field_fmt(char *type)
0254 {
0255 const char *fmt = "%llu";
0256
0257 if (strcmp(type, "s64") == 0)
0258 fmt = "%lld";
0259 else if (strcmp(type, "u64") == 0)
0260 fmt = "%llu";
0261 else if (strcmp(type, "s32") == 0)
0262 fmt = "%d";
0263 else if (strcmp(type, "u32") == 0)
0264 fmt = "%u";
0265 else if (strcmp(type, "s16") == 0)
0266 fmt = "%d";
0267 else if (strcmp(type, "u16") == 0)
0268 fmt = "%u";
0269 else if (strcmp(type, "s8") == 0)
0270 fmt = "%d";
0271 else if (strcmp(type, "u8") == 0)
0272 fmt = "%u";
0273 else if (strcmp(type, "char") == 0)
0274 fmt = "%d";
0275 else if (strcmp(type, "unsigned char") == 0)
0276 fmt = "%u";
0277 else if (strcmp(type, "int") == 0)
0278 fmt = "%d";
0279 else if (strcmp(type, "unsigned int") == 0)
0280 fmt = "%u";
0281 else if (strcmp(type, "long") == 0)
0282 fmt = "%ld";
0283 else if (strcmp(type, "unsigned long") == 0)
0284 fmt = "%lu";
0285 else if (strcmp(type, "bool") == 0)
0286 fmt = "%d";
0287 else if (strcmp(type, "pid_t") == 0)
0288 fmt = "%d";
0289 else if (strcmp(type, "gfp_t") == 0)
0290 fmt = "%x";
0291 else if (synth_field_is_string(type))
0292 fmt = "%.*s";
0293
0294 return fmt;
0295 }
0296
0297 static void print_synth_event_num_val(struct trace_seq *s,
0298 char *print_fmt, char *name,
0299 int size, u64 val, char *space)
0300 {
0301 switch (size) {
0302 case 1:
0303 trace_seq_printf(s, print_fmt, name, (u8)val, space);
0304 break;
0305
0306 case 2:
0307 trace_seq_printf(s, print_fmt, name, (u16)val, space);
0308 break;
0309
0310 case 4:
0311 trace_seq_printf(s, print_fmt, name, (u32)val, space);
0312 break;
0313
0314 default:
0315 trace_seq_printf(s, print_fmt, name, val, space);
0316 break;
0317 }
0318 }
0319
0320 static enum print_line_t print_synth_event(struct trace_iterator *iter,
0321 int flags,
0322 struct trace_event *event)
0323 {
0324 struct trace_array *tr = iter->tr;
0325 struct trace_seq *s = &iter->seq;
0326 struct synth_trace_event *entry;
0327 struct synth_event *se;
0328 unsigned int i, n_u64;
0329 char print_fmt[32];
0330 const char *fmt;
0331
0332 entry = (struct synth_trace_event *)iter->ent;
0333 se = container_of(event, struct synth_event, call.event);
0334
0335 trace_seq_printf(s, "%s: ", se->name);
0336
0337 for (i = 0, n_u64 = 0; i < se->n_fields; i++) {
0338 if (trace_seq_has_overflowed(s))
0339 goto end;
0340
0341 fmt = synth_field_fmt(se->fields[i]->type);
0342
0343
0344 if (tr && tr->trace_flags & TRACE_ITER_VERBOSE)
0345 trace_seq_printf(s, "%s ", fmt);
0346
0347 snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt);
0348
0349
0350 if (se->fields[i]->is_string) {
0351 if (se->fields[i]->is_dynamic) {
0352 u32 offset, data_offset;
0353 char *str_field;
0354
0355 offset = (u32)entry->fields[n_u64];
0356 data_offset = offset & 0xffff;
0357
0358 str_field = (char *)entry + data_offset;
0359
0360 trace_seq_printf(s, print_fmt, se->fields[i]->name,
0361 STR_VAR_LEN_MAX,
0362 str_field,
0363 i == se->n_fields - 1 ? "" : " ");
0364 n_u64++;
0365 } else {
0366 trace_seq_printf(s, print_fmt, se->fields[i]->name,
0367 STR_VAR_LEN_MAX,
0368 (char *)&entry->fields[n_u64],
0369 i == se->n_fields - 1 ? "" : " ");
0370 n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
0371 }
0372 } else {
0373 struct trace_print_flags __flags[] = {
0374 __def_gfpflag_names, {-1, NULL} };
0375 char *space = (i == se->n_fields - 1 ? "" : " ");
0376
0377 print_synth_event_num_val(s, print_fmt,
0378 se->fields[i]->name,
0379 se->fields[i]->size,
0380 entry->fields[n_u64],
0381 space);
0382
0383 if (strcmp(se->fields[i]->type, "gfp_t") == 0) {
0384 trace_seq_puts(s, " (");
0385 trace_print_flags_seq(s, "|",
0386 entry->fields[n_u64],
0387 __flags);
0388 trace_seq_putc(s, ')');
0389 }
0390 n_u64++;
0391 }
0392 }
0393 end:
0394 trace_seq_putc(s, '\n');
0395
0396 return trace_handle_return(s);
0397 }
0398
0399 static struct trace_event_functions synth_event_funcs = {
0400 .trace = print_synth_event
0401 };
0402
0403 static unsigned int trace_string(struct synth_trace_event *entry,
0404 struct synth_event *event,
0405 char *str_val,
0406 bool is_dynamic,
0407 unsigned int data_size,
0408 unsigned int *n_u64)
0409 {
0410 unsigned int len = 0;
0411 char *str_field;
0412
0413 if (is_dynamic) {
0414 u32 data_offset;
0415
0416 data_offset = offsetof(typeof(*entry), fields);
0417 data_offset += event->n_u64 * sizeof(u64);
0418 data_offset += data_size;
0419
0420 str_field = (char *)entry + data_offset;
0421
0422 len = strlen(str_val) + 1;
0423 strscpy(str_field, str_val, len);
0424
0425 data_offset |= len << 16;
0426 *(u32 *)&entry->fields[*n_u64] = data_offset;
0427
0428 (*n_u64)++;
0429 } else {
0430 str_field = (char *)&entry->fields[*n_u64];
0431
0432 strscpy(str_field, str_val, STR_VAR_LEN_MAX);
0433 (*n_u64) += STR_VAR_LEN_MAX / sizeof(u64);
0434 }
0435
0436 return len;
0437 }
0438
0439 static notrace void trace_event_raw_event_synth(void *__data,
0440 u64 *var_ref_vals,
0441 unsigned int *var_ref_idx)
0442 {
0443 unsigned int i, n_u64, val_idx, len, data_size = 0;
0444 struct trace_event_file *trace_file = __data;
0445 struct synth_trace_event *entry;
0446 struct trace_event_buffer fbuffer;
0447 struct trace_buffer *buffer;
0448 struct synth_event *event;
0449 int fields_size = 0;
0450
0451 event = trace_file->event_call->data;
0452
0453 if (trace_trigger_soft_disabled(trace_file))
0454 return;
0455
0456 fields_size = event->n_u64 * sizeof(u64);
0457
0458 for (i = 0; i < event->n_dynamic_fields; i++) {
0459 unsigned int field_pos = event->dynamic_fields[i]->field_pos;
0460 char *str_val;
0461
0462 val_idx = var_ref_idx[field_pos];
0463 str_val = (char *)(long)var_ref_vals[val_idx];
0464
0465 len = strlen(str_val) + 1;
0466
0467 fields_size += len;
0468 }
0469
0470
0471
0472
0473
0474 buffer = trace_file->tr->array_buffer.buffer;
0475 ring_buffer_nest_start(buffer);
0476
0477 entry = trace_event_buffer_reserve(&fbuffer, trace_file,
0478 sizeof(*entry) + fields_size);
0479 if (!entry)
0480 goto out;
0481
0482 for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
0483 val_idx = var_ref_idx[i];
0484 if (event->fields[i]->is_string) {
0485 char *str_val = (char *)(long)var_ref_vals[val_idx];
0486
0487 len = trace_string(entry, event, str_val,
0488 event->fields[i]->is_dynamic,
0489 data_size, &n_u64);
0490 data_size += len;
0491 } else {
0492 struct synth_field *field = event->fields[i];
0493 u64 val = var_ref_vals[val_idx];
0494
0495 switch (field->size) {
0496 case 1:
0497 *(u8 *)&entry->fields[n_u64] = (u8)val;
0498 break;
0499
0500 case 2:
0501 *(u16 *)&entry->fields[n_u64] = (u16)val;
0502 break;
0503
0504 case 4:
0505 *(u32 *)&entry->fields[n_u64] = (u32)val;
0506 break;
0507
0508 default:
0509 entry->fields[n_u64] = val;
0510 break;
0511 }
0512 n_u64++;
0513 }
0514 }
0515
0516 trace_event_buffer_commit(&fbuffer);
0517 out:
0518 ring_buffer_nest_end(buffer);
0519 }
0520
0521 static void free_synth_event_print_fmt(struct trace_event_call *call)
0522 {
0523 if (call) {
0524 kfree(call->print_fmt);
0525 call->print_fmt = NULL;
0526 }
0527 }
0528
0529 static int __set_synth_event_print_fmt(struct synth_event *event,
0530 char *buf, int len)
0531 {
0532 const char *fmt;
0533 int pos = 0;
0534 int i;
0535
0536
0537 #define LEN_OR_ZERO (len ? len - pos : 0)
0538
0539 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
0540 for (i = 0; i < event->n_fields; i++) {
0541 fmt = synth_field_fmt(event->fields[i]->type);
0542 pos += snprintf(buf + pos, LEN_OR_ZERO, "%s=%s%s",
0543 event->fields[i]->name, fmt,
0544 i == event->n_fields - 1 ? "" : ", ");
0545 }
0546 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"");
0547
0548 for (i = 0; i < event->n_fields; i++) {
0549 if (event->fields[i]->is_string &&
0550 event->fields[i]->is_dynamic)
0551 pos += snprintf(buf + pos, LEN_OR_ZERO,
0552 ", __get_str(%s)", event->fields[i]->name);
0553 else
0554 pos += snprintf(buf + pos, LEN_OR_ZERO,
0555 ", REC->%s", event->fields[i]->name);
0556 }
0557
0558 #undef LEN_OR_ZERO
0559
0560
0561 return pos;
0562 }
0563
0564 static int set_synth_event_print_fmt(struct trace_event_call *call)
0565 {
0566 struct synth_event *event = call->data;
0567 char *print_fmt;
0568 int len;
0569
0570
0571 len = __set_synth_event_print_fmt(event, NULL, 0);
0572
0573 print_fmt = kmalloc(len + 1, GFP_KERNEL);
0574 if (!print_fmt)
0575 return -ENOMEM;
0576
0577
0578 __set_synth_event_print_fmt(event, print_fmt, len + 1);
0579 call->print_fmt = print_fmt;
0580
0581 return 0;
0582 }
0583
0584 static void free_synth_field(struct synth_field *field)
0585 {
0586 kfree(field->type);
0587 kfree(field->name);
0588 kfree(field);
0589 }
0590
0591 static int check_field_version(const char *prefix, const char *field_type,
0592 const char *field_name)
0593 {
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605 return 1;
0606 }
0607
0608 static struct synth_field *parse_synth_field(int argc, char **argv,
0609 int *consumed, int *field_version)
0610 {
0611 const char *prefix = NULL, *field_type = argv[0], *field_name, *array;
0612 struct synth_field *field;
0613 int len, ret = -ENOMEM;
0614 struct seq_buf s;
0615 ssize_t size;
0616
0617 if (!strcmp(field_type, "unsigned")) {
0618 if (argc < 3) {
0619 synth_err(SYNTH_ERR_INCOMPLETE_TYPE, errpos(field_type));
0620 return ERR_PTR(-EINVAL);
0621 }
0622 prefix = "unsigned ";
0623 field_type = argv[1];
0624 field_name = argv[2];
0625 *consumed += 3;
0626 } else {
0627 field_name = argv[1];
0628 *consumed += 2;
0629 }
0630
0631 if (!field_name) {
0632 synth_err(SYNTH_ERR_INVALID_FIELD, errpos(field_type));
0633 return ERR_PTR(-EINVAL);
0634 }
0635
0636 *field_version = check_field_version(prefix, field_type, field_name);
0637
0638 field = kzalloc(sizeof(*field), GFP_KERNEL);
0639 if (!field)
0640 return ERR_PTR(-ENOMEM);
0641
0642 len = strlen(field_name);
0643 array = strchr(field_name, '[');
0644 if (array)
0645 len -= strlen(array);
0646
0647 field->name = kmemdup_nul(field_name, len, GFP_KERNEL);
0648 if (!field->name)
0649 goto free;
0650
0651 if (!is_good_name(field->name)) {
0652 synth_err(SYNTH_ERR_BAD_NAME, errpos(field_name));
0653 ret = -EINVAL;
0654 goto free;
0655 }
0656
0657 len = strlen(field_type) + 1;
0658
0659 if (array)
0660 len += strlen(array);
0661
0662 if (prefix)
0663 len += strlen(prefix);
0664
0665 field->type = kzalloc(len, GFP_KERNEL);
0666 if (!field->type)
0667 goto free;
0668
0669 seq_buf_init(&s, field->type, len);
0670 if (prefix)
0671 seq_buf_puts(&s, prefix);
0672 seq_buf_puts(&s, field_type);
0673 if (array)
0674 seq_buf_puts(&s, array);
0675 if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
0676 goto free;
0677
0678 s.buffer[s.len] = '\0';
0679
0680 size = synth_field_size(field->type);
0681 if (size < 0) {
0682 if (array)
0683 synth_err(SYNTH_ERR_INVALID_ARRAY_SPEC, errpos(field_name));
0684 else
0685 synth_err(SYNTH_ERR_INVALID_TYPE, errpos(field_type));
0686 ret = -EINVAL;
0687 goto free;
0688 } else if (size == 0) {
0689 if (synth_field_is_string(field->type)) {
0690 char *type;
0691
0692 len = sizeof("__data_loc ") + strlen(field->type) + 1;
0693 type = kzalloc(len, GFP_KERNEL);
0694 if (!type)
0695 goto free;
0696
0697 seq_buf_init(&s, type, len);
0698 seq_buf_puts(&s, "__data_loc ");
0699 seq_buf_puts(&s, field->type);
0700
0701 if (WARN_ON_ONCE(!seq_buf_buffer_left(&s)))
0702 goto free;
0703 s.buffer[s.len] = '\0';
0704
0705 kfree(field->type);
0706 field->type = type;
0707
0708 field->is_dynamic = true;
0709 size = sizeof(u64);
0710 } else {
0711 synth_err(SYNTH_ERR_INVALID_TYPE, errpos(field_type));
0712 ret = -EINVAL;
0713 goto free;
0714 }
0715 }
0716 field->size = size;
0717
0718 if (synth_field_is_string(field->type))
0719 field->is_string = true;
0720
0721 field->is_signed = synth_field_signed(field->type);
0722 out:
0723 return field;
0724 free:
0725 free_synth_field(field);
0726 field = ERR_PTR(ret);
0727 goto out;
0728 }
0729
0730 static void free_synth_tracepoint(struct tracepoint *tp)
0731 {
0732 if (!tp)
0733 return;
0734
0735 kfree(tp->name);
0736 kfree(tp);
0737 }
0738
0739 static struct tracepoint *alloc_synth_tracepoint(char *name)
0740 {
0741 struct tracepoint *tp;
0742
0743 tp = kzalloc(sizeof(*tp), GFP_KERNEL);
0744 if (!tp)
0745 return ERR_PTR(-ENOMEM);
0746
0747 tp->name = kstrdup(name, GFP_KERNEL);
0748 if (!tp->name) {
0749 kfree(tp);
0750 return ERR_PTR(-ENOMEM);
0751 }
0752
0753 return tp;
0754 }
0755
0756 struct synth_event *find_synth_event(const char *name)
0757 {
0758 struct dyn_event *pos;
0759 struct synth_event *event;
0760
0761 for_each_dyn_event(pos) {
0762 if (!is_synth_event(pos))
0763 continue;
0764 event = to_synth_event(pos);
0765 if (strcmp(event->name, name) == 0)
0766 return event;
0767 }
0768
0769 return NULL;
0770 }
0771
0772 static struct trace_event_fields synth_event_fields_array[] = {
0773 { .type = TRACE_FUNCTION_TYPE,
0774 .define_fields = synth_event_define_fields },
0775 {}
0776 };
0777
0778 static int register_synth_event(struct synth_event *event)
0779 {
0780 struct trace_event_call *call = &event->call;
0781 int ret = 0;
0782
0783 event->call.class = &event->class;
0784 event->class.system = kstrdup(SYNTH_SYSTEM, GFP_KERNEL);
0785 if (!event->class.system) {
0786 ret = -ENOMEM;
0787 goto out;
0788 }
0789
0790 event->tp = alloc_synth_tracepoint(event->name);
0791 if (IS_ERR(event->tp)) {
0792 ret = PTR_ERR(event->tp);
0793 event->tp = NULL;
0794 goto out;
0795 }
0796
0797 INIT_LIST_HEAD(&call->class->fields);
0798 call->event.funcs = &synth_event_funcs;
0799 call->class->fields_array = synth_event_fields_array;
0800
0801 ret = register_trace_event(&call->event);
0802 if (!ret) {
0803 ret = -ENODEV;
0804 goto out;
0805 }
0806 call->flags = TRACE_EVENT_FL_TRACEPOINT;
0807 call->class->reg = trace_event_reg;
0808 call->class->probe = trace_event_raw_event_synth;
0809 call->data = event;
0810 call->tp = event->tp;
0811
0812 ret = trace_add_event_call(call);
0813 if (ret) {
0814 pr_warn("Failed to register synthetic event: %s\n",
0815 trace_event_name(call));
0816 goto err;
0817 }
0818
0819 ret = set_synth_event_print_fmt(call);
0820 if (ret < 0) {
0821 trace_remove_event_call(call);
0822 goto err;
0823 }
0824 out:
0825 return ret;
0826 err:
0827 unregister_trace_event(&call->event);
0828 goto out;
0829 }
0830
0831 static int unregister_synth_event(struct synth_event *event)
0832 {
0833 struct trace_event_call *call = &event->call;
0834 int ret;
0835
0836 ret = trace_remove_event_call(call);
0837
0838 return ret;
0839 }
0840
0841 static void free_synth_event(struct synth_event *event)
0842 {
0843 unsigned int i;
0844
0845 if (!event)
0846 return;
0847
0848 for (i = 0; i < event->n_fields; i++)
0849 free_synth_field(event->fields[i]);
0850
0851 kfree(event->fields);
0852 kfree(event->dynamic_fields);
0853 kfree(event->name);
0854 kfree(event->class.system);
0855 free_synth_tracepoint(event->tp);
0856 free_synth_event_print_fmt(&event->call);
0857 kfree(event);
0858 }
0859
0860 static struct synth_event *alloc_synth_event(const char *name, int n_fields,
0861 struct synth_field **fields)
0862 {
0863 unsigned int i, j, n_dynamic_fields = 0;
0864 struct synth_event *event;
0865
0866 event = kzalloc(sizeof(*event), GFP_KERNEL);
0867 if (!event) {
0868 event = ERR_PTR(-ENOMEM);
0869 goto out;
0870 }
0871
0872 event->name = kstrdup(name, GFP_KERNEL);
0873 if (!event->name) {
0874 kfree(event);
0875 event = ERR_PTR(-ENOMEM);
0876 goto out;
0877 }
0878
0879 event->fields = kcalloc(n_fields, sizeof(*event->fields), GFP_KERNEL);
0880 if (!event->fields) {
0881 free_synth_event(event);
0882 event = ERR_PTR(-ENOMEM);
0883 goto out;
0884 }
0885
0886 for (i = 0; i < n_fields; i++)
0887 if (fields[i]->is_dynamic)
0888 n_dynamic_fields++;
0889
0890 if (n_dynamic_fields) {
0891 event->dynamic_fields = kcalloc(n_dynamic_fields,
0892 sizeof(*event->dynamic_fields),
0893 GFP_KERNEL);
0894 if (!event->dynamic_fields) {
0895 free_synth_event(event);
0896 event = ERR_PTR(-ENOMEM);
0897 goto out;
0898 }
0899 }
0900
0901 dyn_event_init(&event->devent, &synth_event_ops);
0902
0903 for (i = 0, j = 0; i < n_fields; i++) {
0904 fields[i]->field_pos = i;
0905 event->fields[i] = fields[i];
0906
0907 if (fields[i]->is_dynamic)
0908 event->dynamic_fields[j++] = fields[i];
0909 }
0910 event->n_dynamic_fields = j;
0911 event->n_fields = n_fields;
0912 out:
0913 return event;
0914 }
0915
0916 static int synth_event_check_arg_fn(void *data)
0917 {
0918 struct dynevent_arg_pair *arg_pair = data;
0919 int size;
0920
0921 size = synth_field_size((char *)arg_pair->lhs);
0922 if (size == 0) {
0923 if (strstr((char *)arg_pair->lhs, "["))
0924 return 0;
0925 }
0926
0927 return size ? 0 : -EINVAL;
0928 }
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941
0942
0943
0944 int synth_event_add_field(struct dynevent_cmd *cmd, const char *type,
0945 const char *name)
0946 {
0947 struct dynevent_arg_pair arg_pair;
0948 int ret;
0949
0950 if (cmd->type != DYNEVENT_TYPE_SYNTH)
0951 return -EINVAL;
0952
0953 if (!type || !name)
0954 return -EINVAL;
0955
0956 dynevent_arg_pair_init(&arg_pair, 0, ';');
0957
0958 arg_pair.lhs = type;
0959 arg_pair.rhs = name;
0960
0961 ret = dynevent_arg_pair_add(cmd, &arg_pair, synth_event_check_arg_fn);
0962 if (ret)
0963 return ret;
0964
0965 if (++cmd->n_fields > SYNTH_FIELDS_MAX)
0966 ret = -EINVAL;
0967
0968 return ret;
0969 }
0970 EXPORT_SYMBOL_GPL(synth_event_add_field);
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988 int synth_event_add_field_str(struct dynevent_cmd *cmd, const char *type_name)
0989 {
0990 struct dynevent_arg arg;
0991 int ret;
0992
0993 if (cmd->type != DYNEVENT_TYPE_SYNTH)
0994 return -EINVAL;
0995
0996 if (!type_name)
0997 return -EINVAL;
0998
0999 dynevent_arg_init(&arg, ';');
1000
1001 arg.str = type_name;
1002
1003 ret = dynevent_arg_add(cmd, &arg, NULL);
1004 if (ret)
1005 return ret;
1006
1007 if (++cmd->n_fields > SYNTH_FIELDS_MAX)
1008 ret = -EINVAL;
1009
1010 return ret;
1011 }
1012 EXPORT_SYMBOL_GPL(synth_event_add_field_str);
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 int synth_event_add_fields(struct dynevent_cmd *cmd,
1032 struct synth_field_desc *fields,
1033 unsigned int n_fields)
1034 {
1035 unsigned int i;
1036 int ret = 0;
1037
1038 for (i = 0; i < n_fields; i++) {
1039 if (fields[i].type == NULL || fields[i].name == NULL) {
1040 ret = -EINVAL;
1041 break;
1042 }
1043
1044 ret = synth_event_add_field(cmd, fields[i].type, fields[i].name);
1045 if (ret)
1046 break;
1047 }
1048
1049 return ret;
1050 }
1051 EXPORT_SYMBOL_GPL(synth_event_add_fields);
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 int __synth_event_gen_cmd_start(struct dynevent_cmd *cmd, const char *name,
1082 struct module *mod, ...)
1083 {
1084 struct dynevent_arg arg;
1085 va_list args;
1086 int ret;
1087
1088 cmd->event_name = name;
1089 cmd->private_data = mod;
1090
1091 if (cmd->type != DYNEVENT_TYPE_SYNTH)
1092 return -EINVAL;
1093
1094 dynevent_arg_init(&arg, 0);
1095 arg.str = name;
1096 ret = dynevent_arg_add(cmd, &arg, NULL);
1097 if (ret)
1098 return ret;
1099
1100 va_start(args, mod);
1101 for (;;) {
1102 const char *type, *name;
1103
1104 type = va_arg(args, const char *);
1105 if (!type)
1106 break;
1107 name = va_arg(args, const char *);
1108 if (!name)
1109 break;
1110
1111 if (++cmd->n_fields > SYNTH_FIELDS_MAX) {
1112 ret = -EINVAL;
1113 break;
1114 }
1115
1116 ret = synth_event_add_field(cmd, type, name);
1117 if (ret)
1118 break;
1119 }
1120 va_end(args);
1121
1122 return ret;
1123 }
1124 EXPORT_SYMBOL_GPL(__synth_event_gen_cmd_start);
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150 int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, const char *name,
1151 struct module *mod,
1152 struct synth_field_desc *fields,
1153 unsigned int n_fields)
1154 {
1155 struct dynevent_arg arg;
1156 unsigned int i;
1157 int ret = 0;
1158
1159 cmd->event_name = name;
1160 cmd->private_data = mod;
1161
1162 if (cmd->type != DYNEVENT_TYPE_SYNTH)
1163 return -EINVAL;
1164
1165 if (n_fields > SYNTH_FIELDS_MAX)
1166 return -EINVAL;
1167
1168 dynevent_arg_init(&arg, 0);
1169 arg.str = name;
1170 ret = dynevent_arg_add(cmd, &arg, NULL);
1171 if (ret)
1172 return ret;
1173
1174 for (i = 0; i < n_fields; i++) {
1175 if (fields[i].type == NULL || fields[i].name == NULL)
1176 return -EINVAL;
1177
1178 ret = synth_event_add_field(cmd, fields[i].type, fields[i].name);
1179 if (ret)
1180 break;
1181 }
1182
1183 return ret;
1184 }
1185 EXPORT_SYMBOL_GPL(synth_event_gen_cmd_array_start);
1186
1187 static int __create_synth_event(const char *name, const char *raw_fields)
1188 {
1189 char **argv, *field_str, *tmp_fields, *saved_fields = NULL;
1190 struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
1191 int consumed, cmd_version = 1, n_fields_this_loop;
1192 int i, argc, n_fields = 0, ret = 0;
1193 struct synth_event *event = NULL;
1194
1195
1196
1197
1198
1199
1200
1201
1202 if (name[0] == '\0') {
1203 synth_err(SYNTH_ERR_INVALID_CMD, 0);
1204 return -EINVAL;
1205 }
1206
1207 if (!is_good_name(name)) {
1208 synth_err(SYNTH_ERR_BAD_NAME, errpos(name));
1209 return -EINVAL;
1210 }
1211
1212 mutex_lock(&event_mutex);
1213
1214 event = find_synth_event(name);
1215 if (event) {
1216 synth_err(SYNTH_ERR_EVENT_EXISTS, errpos(name));
1217 ret = -EEXIST;
1218 goto err;
1219 }
1220
1221 tmp_fields = saved_fields = kstrdup(raw_fields, GFP_KERNEL);
1222 if (!tmp_fields) {
1223 ret = -ENOMEM;
1224 goto err;
1225 }
1226
1227 while ((field_str = strsep(&tmp_fields, ";")) != NULL) {
1228 argv = argv_split(GFP_KERNEL, field_str, &argc);
1229 if (!argv) {
1230 ret = -ENOMEM;
1231 goto err;
1232 }
1233
1234 if (!argc) {
1235 argv_free(argv);
1236 continue;
1237 }
1238
1239 n_fields_this_loop = 0;
1240 consumed = 0;
1241 while (argc > consumed) {
1242 int field_version;
1243
1244 field = parse_synth_field(argc - consumed,
1245 argv + consumed, &consumed,
1246 &field_version);
1247 if (IS_ERR(field)) {
1248 ret = PTR_ERR(field);
1249 goto err_free_arg;
1250 }
1251
1252
1253
1254
1255
1256 if (field_version > cmd_version)
1257 cmd_version = field_version;
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 if (cmd_version > 1 && n_fields_this_loop >= 1) {
1270 synth_err(SYNTH_ERR_INVALID_CMD, errpos(field_str));
1271 ret = -EINVAL;
1272 goto err_free_arg;
1273 }
1274
1275 fields[n_fields++] = field;
1276 if (n_fields == SYNTH_FIELDS_MAX) {
1277 synth_err(SYNTH_ERR_TOO_MANY_FIELDS, 0);
1278 ret = -EINVAL;
1279 goto err_free_arg;
1280 }
1281
1282 n_fields_this_loop++;
1283 }
1284 argv_free(argv);
1285
1286 if (consumed < argc) {
1287 synth_err(SYNTH_ERR_INVALID_CMD, 0);
1288 ret = -EINVAL;
1289 goto err;
1290 }
1291
1292 }
1293
1294 if (n_fields == 0) {
1295 synth_err(SYNTH_ERR_INVALID_CMD, 0);
1296 ret = -EINVAL;
1297 goto err;
1298 }
1299
1300 event = alloc_synth_event(name, n_fields, fields);
1301 if (IS_ERR(event)) {
1302 ret = PTR_ERR(event);
1303 event = NULL;
1304 goto err;
1305 }
1306 ret = register_synth_event(event);
1307 if (!ret)
1308 dyn_event_add(&event->devent, &event->call);
1309 else
1310 free_synth_event(event);
1311 out:
1312 mutex_unlock(&event_mutex);
1313
1314 kfree(saved_fields);
1315
1316 return ret;
1317 err_free_arg:
1318 argv_free(argv);
1319 err:
1320 for (i = 0; i < n_fields; i++)
1321 free_synth_field(fields[i]);
1322
1323 goto out;
1324 }
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350 int synth_event_create(const char *name, struct synth_field_desc *fields,
1351 unsigned int n_fields, struct module *mod)
1352 {
1353 struct dynevent_cmd cmd;
1354 char *buf;
1355 int ret;
1356
1357 buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
1358 if (!buf)
1359 return -ENOMEM;
1360
1361 synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
1362
1363 ret = synth_event_gen_cmd_array_start(&cmd, name, mod,
1364 fields, n_fields);
1365 if (ret)
1366 goto out;
1367
1368 ret = synth_event_gen_cmd_end(&cmd);
1369 out:
1370 kfree(buf);
1371
1372 return ret;
1373 }
1374 EXPORT_SYMBOL_GPL(synth_event_create);
1375
1376 static int destroy_synth_event(struct synth_event *se)
1377 {
1378 int ret;
1379
1380 if (se->ref)
1381 return -EBUSY;
1382
1383 if (trace_event_dyn_busy(&se->call))
1384 return -EBUSY;
1385
1386 ret = unregister_synth_event(se);
1387 if (!ret) {
1388 dyn_event_remove(&se->devent);
1389 free_synth_event(se);
1390 }
1391
1392 return ret;
1393 }
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403 int synth_event_delete(const char *event_name)
1404 {
1405 struct synth_event *se = NULL;
1406 struct module *mod = NULL;
1407 int ret = -ENOENT;
1408
1409 mutex_lock(&event_mutex);
1410 se = find_synth_event(event_name);
1411 if (se) {
1412 mod = se->mod;
1413 ret = destroy_synth_event(se);
1414 }
1415 mutex_unlock(&event_mutex);
1416
1417 if (mod) {
1418 mutex_lock(&trace_types_lock);
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429 tracing_reset_all_online_cpus();
1430 mutex_unlock(&trace_types_lock);
1431 }
1432
1433 return ret;
1434 }
1435 EXPORT_SYMBOL_GPL(synth_event_delete);
1436
1437 static int check_command(const char *raw_command)
1438 {
1439 char **argv = NULL, *cmd, *saved_cmd, *name_and_field;
1440 int argc, ret = 0;
1441
1442 cmd = saved_cmd = kstrdup(raw_command, GFP_KERNEL);
1443 if (!cmd)
1444 return -ENOMEM;
1445
1446 name_and_field = strsep(&cmd, ";");
1447 if (!name_and_field) {
1448 ret = -EINVAL;
1449 goto free;
1450 }
1451
1452 if (name_and_field[0] == '!')
1453 goto free;
1454
1455 argv = argv_split(GFP_KERNEL, name_and_field, &argc);
1456 if (!argv) {
1457 ret = -ENOMEM;
1458 goto free;
1459 }
1460 argv_free(argv);
1461
1462 if (argc < 3)
1463 ret = -EINVAL;
1464 free:
1465 kfree(saved_cmd);
1466
1467 return ret;
1468 }
1469
1470 static int create_or_delete_synth_event(const char *raw_command)
1471 {
1472 char *name = NULL, *fields, *p;
1473 int ret = 0;
1474
1475 raw_command = skip_spaces(raw_command);
1476 if (raw_command[0] == '\0')
1477 return ret;
1478
1479 last_cmd_set(raw_command);
1480
1481 ret = check_command(raw_command);
1482 if (ret) {
1483 synth_err(SYNTH_ERR_INVALID_CMD, 0);
1484 return ret;
1485 }
1486
1487 p = strpbrk(raw_command, " \t");
1488 if (!p && raw_command[0] != '!') {
1489 synth_err(SYNTH_ERR_INVALID_CMD, 0);
1490 ret = -EINVAL;
1491 goto free;
1492 }
1493
1494 name = kmemdup_nul(raw_command, p ? p - raw_command : strlen(raw_command), GFP_KERNEL);
1495 if (!name)
1496 return -ENOMEM;
1497
1498 if (name[0] == '!') {
1499 ret = synth_event_delete(name + 1);
1500 goto free;
1501 }
1502
1503 fields = skip_spaces(p);
1504
1505 ret = __create_synth_event(name, fields);
1506 free:
1507 kfree(name);
1508
1509 return ret;
1510 }
1511
1512 static int synth_event_run_command(struct dynevent_cmd *cmd)
1513 {
1514 struct synth_event *se;
1515 int ret;
1516
1517 ret = create_or_delete_synth_event(cmd->seq.buffer);
1518 if (ret)
1519 return ret;
1520
1521 se = find_synth_event(cmd->event_name);
1522 if (WARN_ON(!se))
1523 return -ENOENT;
1524
1525 se->mod = cmd->private_data;
1526
1527 return ret;
1528 }
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 void synth_event_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen)
1540 {
1541 dynevent_cmd_init(cmd, buf, maxlen, DYNEVENT_TYPE_SYNTH,
1542 synth_event_run_command);
1543 }
1544 EXPORT_SYMBOL_GPL(synth_event_cmd_init);
1545
1546 static inline int
1547 __synth_event_trace_init(struct trace_event_file *file,
1548 struct synth_event_trace_state *trace_state)
1549 {
1550 int ret = 0;
1551
1552 memset(trace_state, '\0', sizeof(*trace_state));
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563 if (!(file->flags & EVENT_FILE_FL_ENABLED) ||
1564 trace_trigger_soft_disabled(file)) {
1565 trace_state->disabled = true;
1566 ret = -ENOENT;
1567 goto out;
1568 }
1569
1570 trace_state->event = file->event_call->data;
1571 out:
1572 return ret;
1573 }
1574
1575 static inline int
1576 __synth_event_trace_start(struct trace_event_file *file,
1577 struct synth_event_trace_state *trace_state,
1578 int dynamic_fields_size)
1579 {
1580 int entry_size, fields_size = 0;
1581 int ret = 0;
1582
1583 fields_size = trace_state->event->n_u64 * sizeof(u64);
1584 fields_size += dynamic_fields_size;
1585
1586
1587
1588
1589
1590 trace_state->buffer = file->tr->array_buffer.buffer;
1591 ring_buffer_nest_start(trace_state->buffer);
1592
1593 entry_size = sizeof(*trace_state->entry) + fields_size;
1594 trace_state->entry = trace_event_buffer_reserve(&trace_state->fbuffer,
1595 file,
1596 entry_size);
1597 if (!trace_state->entry) {
1598 ring_buffer_nest_end(trace_state->buffer);
1599 ret = -EINVAL;
1600 }
1601
1602 return ret;
1603 }
1604
1605 static inline void
1606 __synth_event_trace_end(struct synth_event_trace_state *trace_state)
1607 {
1608 trace_event_buffer_commit(&trace_state->fbuffer);
1609
1610 ring_buffer_nest_end(trace_state->buffer);
1611 }
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632 int synth_event_trace(struct trace_event_file *file, unsigned int n_vals, ...)
1633 {
1634 unsigned int i, n_u64, len, data_size = 0;
1635 struct synth_event_trace_state state;
1636 va_list args;
1637 int ret;
1638
1639 ret = __synth_event_trace_init(file, &state);
1640 if (ret) {
1641 if (ret == -ENOENT)
1642 ret = 0;
1643 return ret;
1644 }
1645
1646 if (state.event->n_dynamic_fields) {
1647 va_start(args, n_vals);
1648
1649 for (i = 0; i < state.event->n_fields; i++) {
1650 u64 val = va_arg(args, u64);
1651
1652 if (state.event->fields[i]->is_string &&
1653 state.event->fields[i]->is_dynamic) {
1654 char *str_val = (char *)(long)val;
1655
1656 data_size += strlen(str_val) + 1;
1657 }
1658 }
1659
1660 va_end(args);
1661 }
1662
1663 ret = __synth_event_trace_start(file, &state, data_size);
1664 if (ret)
1665 return ret;
1666
1667 if (n_vals != state.event->n_fields) {
1668 ret = -EINVAL;
1669 goto out;
1670 }
1671
1672 data_size = 0;
1673
1674 va_start(args, n_vals);
1675 for (i = 0, n_u64 = 0; i < state.event->n_fields; i++) {
1676 u64 val;
1677
1678 val = va_arg(args, u64);
1679
1680 if (state.event->fields[i]->is_string) {
1681 char *str_val = (char *)(long)val;
1682
1683 len = trace_string(state.entry, state.event, str_val,
1684 state.event->fields[i]->is_dynamic,
1685 data_size, &n_u64);
1686 data_size += len;
1687 } else {
1688 struct synth_field *field = state.event->fields[i];
1689
1690 switch (field->size) {
1691 case 1:
1692 *(u8 *)&state.entry->fields[n_u64] = (u8)val;
1693 break;
1694
1695 case 2:
1696 *(u16 *)&state.entry->fields[n_u64] = (u16)val;
1697 break;
1698
1699 case 4:
1700 *(u32 *)&state.entry->fields[n_u64] = (u32)val;
1701 break;
1702
1703 default:
1704 state.entry->fields[n_u64] = val;
1705 break;
1706 }
1707 n_u64++;
1708 }
1709 }
1710 va_end(args);
1711 out:
1712 __synth_event_trace_end(&state);
1713
1714 return ret;
1715 }
1716 EXPORT_SYMBOL_GPL(synth_event_trace);
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736 int synth_event_trace_array(struct trace_event_file *file, u64 *vals,
1737 unsigned int n_vals)
1738 {
1739 unsigned int i, n_u64, field_pos, len, data_size = 0;
1740 struct synth_event_trace_state state;
1741 char *str_val;
1742 int ret;
1743
1744 ret = __synth_event_trace_init(file, &state);
1745 if (ret) {
1746 if (ret == -ENOENT)
1747 ret = 0;
1748 return ret;
1749 }
1750
1751 if (state.event->n_dynamic_fields) {
1752 for (i = 0; i < state.event->n_dynamic_fields; i++) {
1753 field_pos = state.event->dynamic_fields[i]->field_pos;
1754 str_val = (char *)(long)vals[field_pos];
1755 len = strlen(str_val) + 1;
1756 data_size += len;
1757 }
1758 }
1759
1760 ret = __synth_event_trace_start(file, &state, data_size);
1761 if (ret)
1762 return ret;
1763
1764 if (n_vals != state.event->n_fields) {
1765 ret = -EINVAL;
1766 goto out;
1767 }
1768
1769 data_size = 0;
1770
1771 for (i = 0, n_u64 = 0; i < state.event->n_fields; i++) {
1772 if (state.event->fields[i]->is_string) {
1773 char *str_val = (char *)(long)vals[i];
1774
1775 len = trace_string(state.entry, state.event, str_val,
1776 state.event->fields[i]->is_dynamic,
1777 data_size, &n_u64);
1778 data_size += len;
1779 } else {
1780 struct synth_field *field = state.event->fields[i];
1781 u64 val = vals[i];
1782
1783 switch (field->size) {
1784 case 1:
1785 *(u8 *)&state.entry->fields[n_u64] = (u8)val;
1786 break;
1787
1788 case 2:
1789 *(u16 *)&state.entry->fields[n_u64] = (u16)val;
1790 break;
1791
1792 case 4:
1793 *(u32 *)&state.entry->fields[n_u64] = (u32)val;
1794 break;
1795
1796 default:
1797 state.entry->fields[n_u64] = val;
1798 break;
1799 }
1800 n_u64++;
1801 }
1802 }
1803 out:
1804 __synth_event_trace_end(&state);
1805
1806 return ret;
1807 }
1808 EXPORT_SYMBOL_GPL(synth_event_trace_array);
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838 int synth_event_trace_start(struct trace_event_file *file,
1839 struct synth_event_trace_state *trace_state)
1840 {
1841 int ret;
1842
1843 if (!trace_state)
1844 return -EINVAL;
1845
1846 ret = __synth_event_trace_init(file, trace_state);
1847 if (ret) {
1848 if (ret == -ENOENT)
1849 ret = 0;
1850 return ret;
1851 }
1852
1853 if (trace_state->event->n_dynamic_fields)
1854 return -ENOTSUPP;
1855
1856 ret = __synth_event_trace_start(file, trace_state, 0);
1857
1858 return ret;
1859 }
1860 EXPORT_SYMBOL_GPL(synth_event_trace_start);
1861
1862 static int __synth_event_add_val(const char *field_name, u64 val,
1863 struct synth_event_trace_state *trace_state)
1864 {
1865 struct synth_field *field = NULL;
1866 struct synth_trace_event *entry;
1867 struct synth_event *event;
1868 int i, ret = 0;
1869
1870 if (!trace_state) {
1871 ret = -EINVAL;
1872 goto out;
1873 }
1874
1875
1876 if (field_name) {
1877 if (trace_state->add_next) {
1878 ret = -EINVAL;
1879 goto out;
1880 }
1881 trace_state->add_name = true;
1882 } else {
1883 if (trace_state->add_name) {
1884 ret = -EINVAL;
1885 goto out;
1886 }
1887 trace_state->add_next = true;
1888 }
1889
1890 if (trace_state->disabled)
1891 goto out;
1892
1893 event = trace_state->event;
1894 if (trace_state->add_name) {
1895 for (i = 0; i < event->n_fields; i++) {
1896 field = event->fields[i];
1897 if (strcmp(field->name, field_name) == 0)
1898 break;
1899 }
1900 if (!field) {
1901 ret = -EINVAL;
1902 goto out;
1903 }
1904 } else {
1905 if (trace_state->cur_field >= event->n_fields) {
1906 ret = -EINVAL;
1907 goto out;
1908 }
1909 field = event->fields[trace_state->cur_field++];
1910 }
1911
1912 entry = trace_state->entry;
1913 if (field->is_string) {
1914 char *str_val = (char *)(long)val;
1915 char *str_field;
1916
1917 if (field->is_dynamic) {
1918 ret = -EINVAL;
1919 goto out;
1920 }
1921
1922 if (!str_val) {
1923 ret = -EINVAL;
1924 goto out;
1925 }
1926
1927 str_field = (char *)&entry->fields[field->offset];
1928 strscpy(str_field, str_val, STR_VAR_LEN_MAX);
1929 } else {
1930 switch (field->size) {
1931 case 1:
1932 *(u8 *)&trace_state->entry->fields[field->offset] = (u8)val;
1933 break;
1934
1935 case 2:
1936 *(u16 *)&trace_state->entry->fields[field->offset] = (u16)val;
1937 break;
1938
1939 case 4:
1940 *(u32 *)&trace_state->entry->fields[field->offset] = (u32)val;
1941 break;
1942
1943 default:
1944 trace_state->entry->fields[field->offset] = val;
1945 break;
1946 }
1947 }
1948 out:
1949 return ret;
1950 }
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980 int synth_event_add_next_val(u64 val,
1981 struct synth_event_trace_state *trace_state)
1982 {
1983 return __synth_event_add_val(NULL, val, trace_state);
1984 }
1985 EXPORT_SYMBOL_GPL(synth_event_add_next_val);
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015 int synth_event_add_val(const char *field_name, u64 val,
2016 struct synth_event_trace_state *trace_state)
2017 {
2018 return __synth_event_add_val(field_name, val, trace_state);
2019 }
2020 EXPORT_SYMBOL_GPL(synth_event_add_val);
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042 int synth_event_trace_end(struct synth_event_trace_state *trace_state)
2043 {
2044 if (!trace_state)
2045 return -EINVAL;
2046
2047 __synth_event_trace_end(trace_state);
2048
2049 return 0;
2050 }
2051 EXPORT_SYMBOL_GPL(synth_event_trace_end);
2052
2053 static int create_synth_event(const char *raw_command)
2054 {
2055 char *fields, *p;
2056 const char *name;
2057 int len, ret = 0;
2058
2059 raw_command = skip_spaces(raw_command);
2060 if (raw_command[0] == '\0')
2061 return ret;
2062
2063 last_cmd_set(raw_command);
2064
2065 name = raw_command;
2066
2067
2068 if (name[0] != 's' || name[1] != ':')
2069 return -ECANCELED;
2070 name += 2;
2071
2072 p = strpbrk(raw_command, " \t");
2073 if (!p) {
2074 synth_err(SYNTH_ERR_INVALID_CMD, 0);
2075 return -EINVAL;
2076 }
2077
2078 fields = skip_spaces(p);
2079
2080
2081 if (strchr(name, '/')) {
2082 len = str_has_prefix(name, SYNTH_SYSTEM "/");
2083 if (len == 0) {
2084 synth_err(SYNTH_ERR_INVALID_DYN_CMD, 0);
2085 return -EINVAL;
2086 }
2087 name += len;
2088 }
2089
2090 len = name - raw_command;
2091
2092 ret = check_command(raw_command + len);
2093 if (ret) {
2094 synth_err(SYNTH_ERR_INVALID_CMD, 0);
2095 return ret;
2096 }
2097
2098 name = kmemdup_nul(raw_command + len, p - raw_command - len, GFP_KERNEL);
2099 if (!name)
2100 return -ENOMEM;
2101
2102 ret = __create_synth_event(name, fields);
2103
2104 kfree(name);
2105
2106 return ret;
2107 }
2108
2109 static int synth_event_release(struct dyn_event *ev)
2110 {
2111 struct synth_event *event = to_synth_event(ev);
2112 int ret;
2113
2114 if (event->ref)
2115 return -EBUSY;
2116
2117 if (trace_event_dyn_busy(&event->call))
2118 return -EBUSY;
2119
2120 ret = unregister_synth_event(event);
2121 if (ret)
2122 return ret;
2123
2124 dyn_event_remove(ev);
2125 free_synth_event(event);
2126 return 0;
2127 }
2128
2129 static int __synth_event_show(struct seq_file *m, struct synth_event *event)
2130 {
2131 struct synth_field *field;
2132 unsigned int i;
2133 char *type, *t;
2134
2135 seq_printf(m, "%s\t", event->name);
2136
2137 for (i = 0; i < event->n_fields; i++) {
2138 field = event->fields[i];
2139
2140 type = field->type;
2141 t = strstr(type, "__data_loc");
2142 if (t) {
2143 t += sizeof("__data_loc");
2144 type = t;
2145 }
2146
2147
2148 seq_printf(m, "%s %s%s", type, field->name,
2149 i == event->n_fields - 1 ? "" : "; ");
2150 }
2151
2152 seq_putc(m, '\n');
2153
2154 return 0;
2155 }
2156
2157 static int synth_event_show(struct seq_file *m, struct dyn_event *ev)
2158 {
2159 struct synth_event *event = to_synth_event(ev);
2160
2161 seq_printf(m, "s:%s/", event->class.system);
2162
2163 return __synth_event_show(m, event);
2164 }
2165
2166 static int synth_events_seq_show(struct seq_file *m, void *v)
2167 {
2168 struct dyn_event *ev = v;
2169
2170 if (!is_synth_event(ev))
2171 return 0;
2172
2173 return __synth_event_show(m, to_synth_event(ev));
2174 }
2175
2176 static const struct seq_operations synth_events_seq_op = {
2177 .start = dyn_event_seq_start,
2178 .next = dyn_event_seq_next,
2179 .stop = dyn_event_seq_stop,
2180 .show = synth_events_seq_show,
2181 };
2182
2183 static int synth_events_open(struct inode *inode, struct file *file)
2184 {
2185 int ret;
2186
2187 ret = security_locked_down(LOCKDOWN_TRACEFS);
2188 if (ret)
2189 return ret;
2190
2191 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
2192 ret = dyn_events_release_all(&synth_event_ops);
2193 if (ret < 0)
2194 return ret;
2195 }
2196
2197 return seq_open(file, &synth_events_seq_op);
2198 }
2199
2200 static ssize_t synth_events_write(struct file *file,
2201 const char __user *buffer,
2202 size_t count, loff_t *ppos)
2203 {
2204 return trace_parse_run_command(file, buffer, count, ppos,
2205 create_or_delete_synth_event);
2206 }
2207
2208 static const struct file_operations synth_events_fops = {
2209 .open = synth_events_open,
2210 .write = synth_events_write,
2211 .read = seq_read,
2212 .llseek = seq_lseek,
2213 .release = seq_release,
2214 };
2215
2216
2217
2218
2219
2220 static __init int trace_events_synth_init_early(void)
2221 {
2222 int err = 0;
2223
2224 err = dyn_event_register(&synth_event_ops);
2225 if (err)
2226 pr_warn("Could not register synth_event_ops\n");
2227
2228 return err;
2229 }
2230 core_initcall(trace_events_synth_init_early);
2231
2232 static __init int trace_events_synth_init(void)
2233 {
2234 struct dentry *entry = NULL;
2235 int err = 0;
2236 err = tracing_init_dentry();
2237 if (err)
2238 goto err;
2239
2240 entry = tracefs_create_file("synthetic_events", TRACE_MODE_WRITE,
2241 NULL, NULL, &synth_events_fops);
2242 if (!entry) {
2243 err = -ENODEV;
2244 goto err;
2245 }
2246
2247 return err;
2248 err:
2249 pr_warn("Could not create tracefs 'synthetic_events' entry\n");
2250
2251 return err;
2252 }
2253
2254 fs_initcall(trace_events_synth_init);