1 /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
3 * probes/lttng-kprobes.c
5 * LTTng kprobes integration module.
7 * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
10 #include <linux/module.h>
11 #include <linux/kprobes.h>
12 #include <linux/slab.h>
13 #include <lttng/events.h>
14 #include <lttng/events-internal.h>
15 #include <ringbuffer/frontend_types.h>
16 #include <wrapper/vmalloc.h>
17 #include <wrapper/irqflags.h>
18 #include <lttng/tracer.h>
19 #include <blacklist/kprobes.h>
22 int lttng_kprobes_event_handler_pre(struct kprobe
*p
, struct pt_regs
*regs
)
24 struct lttng_kernel_event_common_private
*event_priv
=
25 container_of(p
, struct lttng_kernel_event_common_private
, u
.kprobe
.kp
);
26 struct lttng_kernel_event_common
*event
= event_priv
->pub
;
27 struct lttng_kernel_probe_ctx lttng_probe_ctx
= {
29 .interruptible
= !lttng_regs_irqs_disabled(regs
),
31 unsigned long data
= (unsigned long) p
->addr
;
33 switch (event
->type
) {
34 case LTTNG_KERNEL_EVENT_TYPE_RECORDER
:
36 struct lttng_kernel_event_recorder_private
*event_recorder_priv
=
37 container_of(event_priv
, struct lttng_kernel_event_recorder_private
, parent
);
38 struct lttng_kernel_event_recorder
*event_recorder
=
39 event_recorder_priv
->pub
;
40 struct lttng_channel
*chan
= event_recorder
->chan
;
42 if (unlikely(!LTTNG_READ_ONCE(chan
->session
->active
)))
44 if (unlikely(!LTTNG_READ_ONCE(chan
->enabled
)))
48 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER
:
54 if (unlikely(!LTTNG_READ_ONCE(event
->enabled
)))
57 switch (event
->type
) {
58 case LTTNG_KERNEL_EVENT_TYPE_RECORDER
:
60 struct lttng_kernel_event_recorder
*event_recorder
=
61 container_of(event
, struct lttng_kernel_event_recorder
, parent
);
62 struct lttng_channel
*chan
= event_recorder
->chan
;
63 struct lttng_kernel_ring_buffer_ctx ctx
;
66 lib_ring_buffer_ctx_init(&ctx
, event_recorder
, sizeof(data
),
67 lttng_alignof(data
), <tng_probe_ctx
);
68 ret
= chan
->ops
->event_reserve(&ctx
);
71 lib_ring_buffer_align_ctx(&ctx
, lttng_alignof(data
));
72 chan
->ops
->event_write(&ctx
, &data
, sizeof(data
));
73 chan
->ops
->event_commit(&ctx
);
76 case LTTNG_KERNEL_EVENT_TYPE_NOTIFIER
:
78 struct lttng_kernel_event_notifier
*event_notifier
=
79 container_of(event
, struct lttng_kernel_event_notifier
, parent
);
80 struct lttng_kernel_notification_ctx notif_ctx
;
82 notif_ctx
.eval_capture
= LTTNG_READ_ONCE(event_notifier
->eval_capture
);
83 event_notifier
->notification_send(event_notifier
, NULL
, NULL
, ¬if_ctx
);
92 static const struct lttng_kernel_type_common
*event_type
=
93 lttng_kernel_static_type_integer_from_type(unsigned long, __BYTE_ORDER
, 16);
96 * Create event description
99 int lttng_create_kprobe_event(const char *name
, struct lttng_kernel_event_recorder
*event_recorder
)
101 const struct lttng_kernel_event_field
**fieldp_array
;
102 struct lttng_kernel_event_field
*field
;
103 struct lttng_kernel_event_desc
*desc
;
106 desc
= kzalloc(sizeof(*desc
), GFP_KERNEL
);
109 desc
->event_name
= kstrdup(name
, GFP_KERNEL
);
110 if (!desc
->event_name
) {
115 fieldp_array
= kzalloc(1 * sizeof(struct lttng_kernel_event_field
*), GFP_KERNEL
);
118 goto error_fieldp_array
;
120 desc
->fields
= fieldp_array
;
121 desc
->fields
[0] = field
=
122 kzalloc(sizeof(struct lttng_kernel_event_field
), GFP_KERNEL
);
128 field
->type
= event_type
;
129 desc
->owner
= THIS_MODULE
;
130 event_recorder
->priv
->parent
.desc
= desc
;
137 kfree(desc
->event_name
);
144 * Create event_notifier description
147 int lttng_create_kprobe_event_notifier(const char *name
, struct lttng_kernel_event_notifier
*event_notifier
)
149 struct lttng_kernel_event_desc
*desc
;
152 desc
= kzalloc(sizeof(*desc
), GFP_KERNEL
);
155 desc
->event_name
= kstrdup(name
, GFP_KERNEL
);
156 if (!desc
->event_name
) {
162 desc
->owner
= THIS_MODULE
;
163 event_notifier
->priv
->parent
.desc
= desc
;
173 int _lttng_kprobes_register(const char *symbol_name
,
176 struct lttng_kprobe
*lttng_kp
,
177 kprobe_pre_handler_t pre_handler
)
181 /* Kprobes expects a NULL symbol name if unused */
182 if (symbol_name
[0] == '\0')
185 memset(<tng_kp
->kp
, 0, sizeof(lttng_kp
->kp
));
186 lttng_kp
->kp
.pre_handler
= pre_handler
;
189 lttng_kp
->symbol_name
=
190 kzalloc(LTTNG_KERNEL_ABI_SYM_NAME_LEN
* sizeof(char),
192 if (!lttng_kp
->symbol_name
) {
196 memcpy(lttng_kp
->symbol_name
, symbol_name
,
197 LTTNG_KERNEL_ABI_SYM_NAME_LEN
* sizeof(char));
198 lttng_kp
->kp
.symbol_name
= lttng_kp
->symbol_name
;
201 lttng_kp
->kp
.offset
= offset
;
202 lttng_kp
->kp
.addr
= (void *) (unsigned long) addr
;
205 * Ensure the memory we just allocated don't notify page faults.
206 * Well.. kprobes itself puts the page fault handler on the blacklist,
207 * but we can never be too careful.
209 wrapper_vmalloc_sync_mappings();
211 ret
= register_kprobe(<tng_kp
->kp
);
218 kfree(lttng_kp
->symbol_name
);
223 int lttng_kprobes_register_event(const char *name
,
224 const char *symbol_name
,
227 struct lttng_kernel_event_recorder
*event_recorder
)
231 ret
= lttng_create_kprobe_event(name
, event_recorder
);
235 ret
= _lttng_kprobes_register(symbol_name
, offset
, addr
,
236 &event_recorder
->priv
->parent
.u
.kprobe
, lttng_kprobes_event_handler_pre
);
243 kfree(event_recorder
->priv
->parent
.desc
->fields
);
244 kfree(event_recorder
->priv
->parent
.desc
->event_name
);
245 kfree(event_recorder
->priv
->parent
.desc
);
249 EXPORT_SYMBOL_GPL(lttng_kprobes_register_event
);
251 int lttng_kprobes_register_event_notifier(const char *symbol_name
,
254 struct lttng_kernel_event_notifier
*event_notifier
)
257 ret
= lttng_create_kprobe_event_notifier(symbol_name
, event_notifier
);
261 ret
= _lttng_kprobes_register(symbol_name
, offset
, addr
,
262 &event_notifier
->priv
->parent
.u
.kprobe
, lttng_kprobes_event_handler_pre
);
269 kfree(event_notifier
->priv
->parent
.desc
->event_name
);
270 kfree(event_notifier
->priv
->parent
.desc
);
274 EXPORT_SYMBOL_GPL(lttng_kprobes_register_event_notifier
);
276 void lttng_kprobes_unregister_event(struct lttng_kernel_event_recorder
*event_recorder
)
278 unregister_kprobe(&event_recorder
->priv
->parent
.u
.kprobe
.kp
);
280 EXPORT_SYMBOL_GPL(lttng_kprobes_unregister_event
);
282 void lttng_kprobes_unregister_event_notifier(struct lttng_kernel_event_notifier
*event_notifier
)
284 unregister_kprobe(&event_notifier
->priv
->parent
.u
.kprobe
.kp
);
286 EXPORT_SYMBOL_GPL(lttng_kprobes_unregister_event_notifier
);
288 void lttng_kprobes_destroy_event_private(struct lttng_kernel_event_recorder
*event_recorder
)
290 kfree(event_recorder
->priv
->parent
.u
.kprobe
.symbol_name
);
291 kfree(event_recorder
->priv
->parent
.desc
->fields
[0]);
292 kfree(event_recorder
->priv
->parent
.desc
->fields
);
293 kfree(event_recorder
->priv
->parent
.desc
->event_name
);
294 kfree(event_recorder
->priv
->parent
.desc
);
296 EXPORT_SYMBOL_GPL(lttng_kprobes_destroy_event_private
);
298 void lttng_kprobes_destroy_event_notifier_private(struct lttng_kernel_event_notifier
*event_notifier
)
300 kfree(event_notifier
->priv
->parent
.u
.kprobe
.symbol_name
);
301 kfree(event_notifier
->priv
->parent
.desc
->event_name
);
302 kfree(event_notifier
->priv
->parent
.desc
);
304 EXPORT_SYMBOL_GPL(lttng_kprobes_destroy_event_notifier_private
);
306 MODULE_LICENSE("GPL and additional rights");
307 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
308 MODULE_DESCRIPTION("LTTng kprobes probes");
309 MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION
) "."
310 __stringify(LTTNG_MODULES_MINOR_VERSION
) "."
311 __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION
)
312 LTTNG_MODULES_EXTRAVERSION
);