Namespace kprobe functions relating to events
[lttng-modules.git] / src / probes / lttng-kprobes.c
CommitLineData
b7cdc182 1/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
9f36eaed 2 *
886d51a3 3 * probes/lttng-kprobes.c
d6d808f3
MD
4 *
5 * LTTng kprobes integration module.
6 *
886d51a3 7 * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
d6d808f3
MD
8 */
9
10#include <linux/module.h>
11#include <linux/kprobes.h>
f17701fb 12#include <linux/slab.h>
2df37e95 13#include <lttng/events.h>
24591303 14#include <ringbuffer/frontend_types.h>
156a3977
MD
15#include <wrapper/vmalloc.h>
16#include <wrapper/irqflags.h>
2df37e95 17#include <lttng/tracer.h>
caa068b5 18#include <blacklist/kprobes.h>
d6d808f3 19
f17701fb 20static
8bf17deb 21int lttng_kprobes_event_handler_pre(struct kprobe *p, struct pt_regs *regs)
d6d808f3 22{
a90917c3
MD
23 struct lttng_event *event =
24 container_of(p, struct lttng_event, u.kprobe.kp);
79150a49
JD
25 struct lttng_probe_ctx lttng_probe_ctx = {
26 .event = event,
ccecf3fb 27 .interruptible = !lttng_regs_irqs_disabled(regs),
79150a49 28 };
a90917c3 29 struct lttng_channel *chan = event->chan;
d6d808f3
MD
30 struct lib_ring_buffer_ctx ctx;
31 int ret;
32 unsigned long data = (unsigned long) p->addr;
33
585e5dcc 34 if (unlikely(!LTTNG_READ_ONCE(chan->session->active)))
f17701fb 35 return 0;
585e5dcc 36 if (unlikely(!LTTNG_READ_ONCE(chan->enabled)))
e64957da 37 return 0;
585e5dcc 38 if (unlikely(!LTTNG_READ_ONCE(event->enabled)))
e64957da
MD
39 return 0;
40
79150a49 41 lib_ring_buffer_ctx_init(&ctx, chan->chan, &lttng_probe_ctx, sizeof(data),
a90917c3 42 lttng_alignof(data), -1);
4e1f08f4 43 ret = chan->ops->event_reserve(&ctx, event->id);
d6d808f3 44 if (ret < 0)
f17701fb 45 return 0;
a90917c3 46 lib_ring_buffer_align_ctx(&ctx, lttng_alignof(data));
d6d808f3
MD
47 chan->ops->event_write(&ctx, &data, sizeof(data));
48 chan->ops->event_commit(&ctx);
f17701fb 49 return 0;
d6d808f3 50}
f17701fb
MD
51
52/*
53 * Create event description
54 */
55static
a90917c3 56int lttng_create_kprobe_event(const char *name, struct lttng_event *event)
f17701fb
MD
57{
58 struct lttng_event_field *field;
d3dbe23c 59 struct lttng_event_desc *desc;
f17701fb
MD
60 int ret;
61
d3dbe23c
MD
62 desc = kzalloc(sizeof(*event->desc), GFP_KERNEL);
63 if (!desc)
f17701fb 64 return -ENOMEM;
d3dbe23c
MD
65 desc->name = kstrdup(name, GFP_KERNEL);
66 if (!desc->name) {
f17701fb
MD
67 ret = -ENOMEM;
68 goto error_str;
69 }
d3dbe23c
MD
70 desc->nr_fields = 1;
71 desc->fields = field =
f17701fb 72 kzalloc(1 * sizeof(struct lttng_event_field), GFP_KERNEL);
0d1a681e
MD
73 if (!field) {
74 ret = -ENOMEM;
75 goto error_field;
76 }
f17701fb
MD
77 field->name = "ip";
78 field->type.atype = atype_integer;
ceabb767
MD
79 field->type.u.integer.size = sizeof(unsigned long) * CHAR_BIT;
80 field->type.u.integer.alignment = lttng_alignof(unsigned long) * CHAR_BIT;
81 field->type.u.integer.signedness = lttng_is_signed_type(unsigned long);
82 field->type.u.integer.reverse_byte_order = 0;
83 field->type.u.integer.base = 16;
84 field->type.u.integer.encoding = lttng_encode_none;
dc7f600a 85 desc->owner = THIS_MODULE;
d3dbe23c 86 event->desc = desc;
f17701fb
MD
87
88 return 0;
89
0d1a681e
MD
90error_field:
91 kfree(desc->name);
f17701fb 92error_str:
d3dbe23c 93 kfree(desc);
f17701fb
MD
94 return ret;
95}
96
8bf17deb
FD
97static
98int _lttng_kprobes_register(const char *symbol_name,
f17701fb
MD
99 uint64_t offset,
100 uint64_t addr,
8bf17deb
FD
101 struct lttng_kprobe *lttng_kp,
102 kprobe_pre_handler_t pre_handler)
f17701fb
MD
103{
104 int ret;
105
c37f2a9b
MD
106 /* Kprobes expects a NULL symbol name if unused */
107 if (symbol_name[0] == '\0')
108 symbol_name = NULL;
109
8bf17deb
FD
110 memset(&lttng_kp->kp, 0, sizeof(lttng_kp->kp));
111 lttng_kp->kp.pre_handler = pre_handler;
112
c37f2a9b 113 if (symbol_name) {
8bf17deb 114 lttng_kp->symbol_name =
f8695253 115 kzalloc(LTTNG_KERNEL_SYM_NAME_LEN * sizeof(char),
c37f2a9b 116 GFP_KERNEL);
8bf17deb 117 if (!lttng_kp->symbol_name) {
c37f2a9b
MD
118 ret = -ENOMEM;
119 goto name_error;
120 }
8bf17deb 121 memcpy(lttng_kp->symbol_name, symbol_name,
f8695253 122 LTTNG_KERNEL_SYM_NAME_LEN * sizeof(char));
8bf17deb 123 lttng_kp->kp.symbol_name = lttng_kp->symbol_name;
f17701fb 124 }
8bf17deb
FD
125
126 lttng_kp->kp.offset = offset;
127 lttng_kp->kp.addr = (void *) (unsigned long) addr;
16a9a591
MD
128
129 /*
130 * Ensure the memory we just allocated don't trigger page faults.
131 * Well.. kprobes itself puts the page fault handler on the blacklist,
132 * but we can never be too careful.
133 */
263b6c88 134 wrapper_vmalloc_sync_mappings();
16a9a591 135
8bf17deb 136 ret = register_kprobe(&lttng_kp->kp);
f17701fb
MD
137 if (ret)
138 goto register_error;
8bf17deb 139
f17701fb
MD
140 return 0;
141
142register_error:
8bf17deb 143 kfree(lttng_kp->symbol_name);
f17701fb 144name_error:
8bf17deb
FD
145 return ret;
146}
147
148int lttng_kprobes_register_event(const char *name,
149 const char *symbol_name,
150 uint64_t offset,
151 uint64_t addr,
152 struct lttng_event *event)
153{
154 int ret;
155
156 ret = lttng_create_kprobe_event(name, event);
157 if (ret)
158 goto error;
159
160 ret = _lttng_kprobes_register(symbol_name, offset, addr,
161 &event->u.kprobe, lttng_kprobes_event_handler_pre);
162 if (ret)
163 goto register_error;
164
165 return 0;
166
167register_error:
0d1a681e 168 kfree(event->desc->fields);
f17701fb
MD
169 kfree(event->desc->name);
170 kfree(event->desc);
171error:
172 return ret;
173}
8bf17deb 174EXPORT_SYMBOL_GPL(lttng_kprobes_register_event);
f17701fb 175
8bf17deb 176void lttng_kprobes_unregister_event(struct lttng_event *event)
f17701fb
MD
177{
178 unregister_kprobe(&event->u.kprobe.kp);
edeb3137 179}
8bf17deb 180EXPORT_SYMBOL_GPL(lttng_kprobes_unregister_event);
edeb3137 181
8bf17deb 182void lttng_kprobes_destroy_event_private(struct lttng_event *event)
edeb3137 183{
f17701fb 184 kfree(event->u.kprobe.symbol_name);
0d1a681e 185 kfree(event->desc->fields);
f17701fb
MD
186 kfree(event->desc->name);
187 kfree(event->desc);
188}
8bf17deb 189EXPORT_SYMBOL_GPL(lttng_kprobes_destroy_event_private);
d6d808f3
MD
190
191MODULE_LICENSE("GPL and additional rights");
1c124020
MJ
192MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
193MODULE_DESCRIPTION("LTTng kprobes probes");
13ab8b0a
MD
194MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "."
195 __stringify(LTTNG_MODULES_MINOR_VERSION) "."
196 __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)
197 LTTNG_MODULES_EXTRAVERSION);
This page took 0.051221 seconds and 4 git commands to generate.