-int lttng_syscalls_register_event_notifier(struct lttng_event_notifier_enabler *event_notifier_enabler, void *filter)
-{
- struct lttng_event_notifier_group *group = event_notifier_enabler->group;
- unsigned int i;
- int ret = 0;
-
- wrapper_vmalloc_sync_mappings();
-
- if (!group->event_notifier_syscall_dispatch) {
- group->event_notifier_syscall_dispatch = kzalloc(sizeof(struct list_head)
- * ARRAY_SIZE(sc_table), GFP_KERNEL);
- if (!group->event_notifier_syscall_dispatch)
- return -ENOMEM;
-
- /* Initialize all list_head */
- for (i = 0; i < ARRAY_SIZE(sc_table); i++)
- INIT_LIST_HEAD(&group->event_notifier_syscall_dispatch[i]);
- }
-
-#ifdef CONFIG_COMPAT
- if (!group->event_notifier_compat_syscall_dispatch) {
- group->event_notifier_compat_syscall_dispatch = kzalloc(sizeof(struct list_head)
- * ARRAY_SIZE(compat_sc_table), GFP_KERNEL);
- if (!group->event_notifier_syscall_dispatch)
- return -ENOMEM;
-
- /* Initialize all list_head */
- for (i = 0; i < ARRAY_SIZE(compat_sc_table); i++)
- INIT_LIST_HEAD(&group->event_notifier_compat_syscall_dispatch[i]);
- }
-#endif
-
- if (!group->sys_enter_registered) {
- ret = lttng_wrapper_tracepoint_probe_register("sys_enter",
- (void *) syscall_entry_event_notifier_probe, group);
- if (ret)
- return ret;
- group->sys_enter_registered = 1;
- }
-
- return ret;
-}
-
-static int create_matching_event_notifiers(struct lttng_event_notifier_enabler *event_notifier_enabler,
- void *filter, const struct trace_syscall_entry *table,
- size_t table_len, bool is_compat)
-{
- struct lttng_event_notifier_group *group = event_notifier_enabler->group;
- const struct lttng_event_desc *desc;
- uint64_t user_token = event_notifier_enabler->base.user_token;
- 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_event_notifier *event_notifier;
- struct lttng_kernel_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->name);
- lttng_hlist_for_each_entry(event_notifier, head, hlist) {
- if (event_notifier->desc == desc
- && event_notifier->user_token == event_notifier_enabler->base.user_token)
- found = 1;
- }
- if (found)
- continue;
-
- memset(&event_notifier_param, 0, sizeof(event_notifier_param));
- strncat(event_notifier_param.event.name, desc->name,
- LTTNG_KERNEL_SYM_NAME_LEN - strlen(event_notifier_param.event.name) - 1);
- event_notifier_param.event.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0';
- event_notifier_param.event.instrumentation = LTTNG_KERNEL_SYSCALL;
-
- event_notifier = _lttng_event_notifier_create(desc, user_token, group,
- &event_notifier_param, filter,
- event_notifier_param.event.instrumentation);
- if (IS_ERR(event_notifier)) {
- printk(KERN_INFO "Unable to create event_notifier %s\n",
- desc->name);
- ret = -ENOMEM;
- goto end;
- }
-
- event_notifier->u.syscall.syscall_id = i;
- event_notifier->u.syscall.is_compat = is_compat;
- }
-end:
- return ret;
-
-}
-
-int lttng_syscals_create_matching_event_notifiers(struct lttng_event_notifier_enabler *event_notifier_enabler, void *filter)
-{
- int ret;
-
- ret = create_matching_event_notifiers(event_notifier_enabler, filter, sc_table,
- ARRAY_SIZE(sc_table), false);
- if (ret)
- goto end;
-
- ret = create_matching_event_notifiers(event_notifier_enabler, filter, compat_sc_table,
- ARRAY_SIZE(compat_sc_table), true);
-end:
- return ret;
-}
-
-/*
- * Unregister the syscall event_notifier probes from the callsites.
- */
-int lttng_syscalls_unregister_event_notifier(struct lttng_event_notifier_group *event_notifier_group)
-{
- 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 (event_notifier_group->sys_enter_registered) {
- ret = lttng_wrapper_tracepoint_probe_unregister("sys_enter",
- (void *) syscall_entry_event_notifier_probe, event_notifier_group);
- if (ret)
- return ret;
- event_notifier_group->sys_enter_registered = 0;
- }
-
- kfree(event_notifier_group->event_notifier_syscall_dispatch);
-#ifdef CONFIG_COMPAT
- kfree(event_notifier_group->event_notifier_compat_syscall_dispatch);
-#endif
- return 0;
-}
-