- struct lttng_event_notifier_group *group = event_notifier_enabler->group;
- const struct lttng_kernel_event_desc *desc;
- uint64_t user_token = event_notifier_enabler->parent.user_token;
- uint64_t error_counter_index = event_notifier_enabler->error_counter_index;
- unsigned int i;
- int ret = 0;
-
- /* iterate over all syscall and create event_notifier that match */
- for (i = 0; i < table_len; i++) {
- struct lttng_kernel_event_notifier_private *event_notifier_priv;
- struct lttng_kernel_event_notifier *event_notifier;
- struct lttng_kernel_abi_event_notifier event_notifier_param;
- struct hlist_head *head;
- int found = 0;
-
- desc = table[i].desc;
- if (!desc) {
- /* Unknown syscall */
- continue;
- }
-
- if (!lttng_desc_match_enabler(desc,
- lttng_event_notifier_enabler_as_enabler(event_notifier_enabler)))
- continue;
-
- /*
- * Check if already created.
- */
- head = utils_borrow_hash_table_bucket(group->event_notifiers_ht.table,
- LTTNG_EVENT_NOTIFIER_HT_SIZE, desc->event_name);
- lttng_hlist_for_each_entry(event_notifier_priv, head, hlist) {
- if (event_notifier_priv->parent.desc == desc
- && event_notifier_priv->parent.user_token == event_notifier_enabler->parent.user_token)
- found = 1;
- }
- if (found)
- continue;
-
- memset(&event_notifier_param, 0, sizeof(event_notifier_param));
- switch (type) {
- case SC_TYPE_ENTRY:
- event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
- event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
- break;
- case SC_TYPE_EXIT:
- event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
- event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_NATIVE;
- break;
- case SC_TYPE_COMPAT_ENTRY:
- event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_ENTRY;
- event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
- break;
- case SC_TYPE_COMPAT_EXIT:
- event_notifier_param.event.u.syscall.entryexit = LTTNG_KERNEL_ABI_SYSCALL_EXIT;
- event_notifier_param.event.u.syscall.abi = LTTNG_KERNEL_ABI_SYSCALL_ABI_COMPAT;
- break;
- }
- strncat(event_notifier_param.event.name, desc->event_name,
- LTTNG_KERNEL_ABI_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
- event_notifier_param.event.name[LTTNG_KERNEL_ABI_SYM_NAME_LEN - 1] = '\0';
- event_notifier_param.event.instrumentation = LTTNG_KERNEL_ABI_SYSCALL;
-
- event_notifier = _lttng_event_notifier_create(desc, user_token,
- error_counter_index, group, &event_notifier_param,
- event_notifier_param.event.instrumentation);
- if (IS_ERR(event_notifier)) {
- printk(KERN_INFO "Unable to create event_notifier %s\n",
- desc->event_name);
- ret = -ENOMEM;
- goto end;
- }
-
- event_notifier->priv->parent.u.syscall.syscall_id = i;
- }
-
-end:
- return ret;
-
-}
-
-int lttng_syscalls_create_matching_event_notifiers(
- struct lttng_event_notifier_enabler *event_notifier_enabler)
-{
- int ret;
- struct lttng_event_enabler_common *base_enabler =
- lttng_event_notifier_enabler_as_enabler(event_notifier_enabler);
- enum lttng_kernel_abi_syscall_entryexit entryexit =
- base_enabler->event_param.u.syscall.entryexit;
-
- if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRY || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
- ret = create_matching_event_notifiers(event_notifier_enabler,
- sc_table.table, sc_table.len, SC_TYPE_ENTRY);
- if (ret)
- goto end;
-
- ret = create_matching_event_notifiers(event_notifier_enabler,
- compat_sc_table.table, compat_sc_table.len,
- SC_TYPE_COMPAT_ENTRY);
- if (ret)
- goto end;
-
- ret = create_unknown_event_notifier(event_notifier_enabler,
- SC_TYPE_ENTRY);
- if (ret)
- goto end;
-
- ret = create_unknown_event_notifier(event_notifier_enabler,
- SC_TYPE_COMPAT_ENTRY);
- if (ret)
- goto end;
- }
-
- if (entryexit == LTTNG_KERNEL_ABI_SYSCALL_EXIT || entryexit == LTTNG_KERNEL_ABI_SYSCALL_ENTRYEXIT) {
- ret = create_matching_event_notifiers(event_notifier_enabler,
- sc_exit_table.table, sc_exit_table.len,
- SC_TYPE_EXIT);
- if (ret)
- goto end;
-
- ret = create_unknown_event_notifier(event_notifier_enabler,
- SC_TYPE_EXIT);
- if (ret)
- goto end;
-
- ret = create_matching_event_notifiers(event_notifier_enabler,
- compat_sc_exit_table.table, compat_sc_exit_table.len,
- SC_TYPE_COMPAT_EXIT);
- if (ret)
- goto end;
-
- ret = create_unknown_event_notifier(event_notifier_enabler,
- SC_TYPE_COMPAT_EXIT);
- if (ret)
- goto end;
- }
-
-end:
- return ret;
-}
-
-/*
- * Unregister the syscall event_notifier probes from the callsites.
- */
-int lttng_syscalls_unregister_event_notifier_group(
- struct lttng_event_notifier_group *event_notifier_group)
-{
- struct lttng_kernel_syscall_table *syscall_table = &event_notifier_group->syscall_table;
- int ret;
-
- /*
- * Only register the event_notifier probe on the `sys_enter` callsite for now.
- * At the moment, we don't think it's desirable to have one fired
- * event_notifier for the entry and one for the exit of a syscall.
- */
- if (syscall_table->sys_enter_registered) {
- ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
- (void *) syscall_entry_event_probe, syscall_table);
- if (ret)
- return ret;
- syscall_table->sys_enter_registered = 0;
- }
- if (syscall_table->sys_exit_registered) {
- ret = lttng_wrapper_tracepoint_probe_unregister("sys_exit",
- (void *) syscall_exit_event_probe, syscall_table);
- if (ret)
- return ret;
- syscall_table->sys_enter_registered = 0;
- }
-
- kfree(syscall_table->syscall_dispatch);
- kfree(syscall_table->syscall_exit_dispatch);
-#ifdef CONFIG_COMPAT
- kfree(syscall_table->compat_syscall_dispatch);
- kfree(syscall_table->compat_syscall_exit_dispatch);
-#endif
- return 0;
-}
-
-int lttng_syscalls_unregister_channel(struct lttng_kernel_channel_buffer *chan)
-{
- struct lttng_kernel_syscall_table *syscall_table = &chan->priv->parent.syscall_table;