GNU Linux-libre 4.19.211-gnu1
[releases.git] / kernel / trace / trace_printk.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * trace binary printk
4  *
5  * Copyright (C) 2008 Lai Jiangshan <laijs@cn.fujitsu.com>
6  *
7  */
8 #include <linux/seq_file.h>
9 #include <linux/uaccess.h>
10 #include <linux/kernel.h>
11 #include <linux/ftrace.h>
12 #include <linux/string.h>
13 #include <linux/module.h>
14 #include <linux/mutex.h>
15 #include <linux/ctype.h>
16 #include <linux/list.h>
17 #include <linux/slab.h>
18
19 #include "trace.h"
20
21 #ifdef CONFIG_MODULES
22
23 /*
24  * modules trace_printk()'s formats are autosaved in struct trace_bprintk_fmt
25  * which are queued on trace_bprintk_fmt_list.
26  */
27 static LIST_HEAD(trace_bprintk_fmt_list);
28
29 /* serialize accesses to trace_bprintk_fmt_list */
30 static DEFINE_MUTEX(btrace_mutex);
31
32 struct trace_bprintk_fmt {
33         struct list_head list;
34         const char *fmt;
35 };
36
37 static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
38 {
39         struct trace_bprintk_fmt *pos;
40
41         if (!fmt)
42                 return ERR_PTR(-EINVAL);
43
44         list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
45                 if (!strcmp(pos->fmt, fmt))
46                         return pos;
47         }
48         return NULL;
49 }
50
51 static
52 void hold_module_trace_bprintk_format(const char **start, const char **end)
53 {
54         const char **iter;
55         char *fmt;
56
57         /* allocate the trace_printk per cpu buffers */
58         if (start != end)
59                 trace_printk_init_buffers();
60
61         mutex_lock(&btrace_mutex);
62         for (iter = start; iter < end; iter++) {
63                 struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
64                 if (tb_fmt) {
65                         if (!IS_ERR(tb_fmt))
66                                 *iter = tb_fmt->fmt;
67                         continue;
68                 }
69
70                 fmt = NULL;
71                 tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL);
72                 if (tb_fmt) {
73                         fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL);
74                         if (fmt) {
75                                 list_add_tail(&tb_fmt->list, &trace_bprintk_fmt_list);
76                                 strcpy(fmt, *iter);
77                                 tb_fmt->fmt = fmt;
78                         } else
79                                 kfree(tb_fmt);
80                 }
81                 *iter = fmt;
82
83         }
84         mutex_unlock(&btrace_mutex);
85 }
86
87 static int module_trace_bprintk_format_notify(struct notifier_block *self,
88                 unsigned long val, void *data)
89 {
90         struct module *mod = data;
91         if (mod->num_trace_bprintk_fmt) {
92                 const char **start = mod->trace_bprintk_fmt_start;
93                 const char **end = start + mod->num_trace_bprintk_fmt;
94
95                 if (val == MODULE_STATE_COMING)
96                         hold_module_trace_bprintk_format(start, end);
97         }
98         return 0;
99 }
100
101 /*
102  * The debugfs/tracing/printk_formats file maps the addresses with
103  * the ASCII formats that are used in the bprintk events in the
104  * buffer. For userspace tools to be able to decode the events from
105  * the buffer, they need to be able to map the address with the format.
106  *
107  * The addresses of the bprintk formats are in their own section
108  * __trace_printk_fmt. But for modules we copy them into a link list.
109  * The code to print the formats and their addresses passes around the
110  * address of the fmt string. If the fmt address passed into the seq
111  * functions is within the kernel core __trace_printk_fmt section, then
112  * it simply uses the next pointer in the list.
113  *
114  * When the fmt pointer is outside the kernel core __trace_printk_fmt
115  * section, then we need to read the link list pointers. The trick is
116  * we pass the address of the string to the seq function just like
117  * we do for the kernel core formats. To get back the structure that
118  * holds the format, we simply use containerof() and then go to the
119  * next format in the list.
120  */
121 static const char **
122 find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
123 {
124         struct trace_bprintk_fmt *mod_fmt;
125
126         if (list_empty(&trace_bprintk_fmt_list))
127                 return NULL;
128
129         /*
130          * v will point to the address of the fmt record from t_next
131          * v will be NULL from t_start.
132          * If this is the first pointer or called from start
133          * then we need to walk the list.
134          */
135         if (!v || start_index == *pos) {
136                 struct trace_bprintk_fmt *p;
137
138                 /* search the module list */
139                 list_for_each_entry(p, &trace_bprintk_fmt_list, list) {
140                         if (start_index == *pos)
141                                 return &p->fmt;
142                         start_index++;
143                 }
144                 /* pos > index */
145                 return NULL;
146         }
147
148         /*
149          * v points to the address of the fmt field in the mod list
150          * structure that holds the module print format.
151          */
152         mod_fmt = container_of(v, typeof(*mod_fmt), fmt);
153         if (mod_fmt->list.next == &trace_bprintk_fmt_list)
154                 return NULL;
155
156         mod_fmt = container_of(mod_fmt->list.next, typeof(*mod_fmt), list);
157
158         return &mod_fmt->fmt;
159 }
160
161 static void format_mod_start(void)
162 {
163         mutex_lock(&btrace_mutex);
164 }
165
166 static void format_mod_stop(void)
167 {
168         mutex_unlock(&btrace_mutex);
169 }
170
171 #else /* !CONFIG_MODULES */
172 __init static int
173 module_trace_bprintk_format_notify(struct notifier_block *self,
174                 unsigned long val, void *data)
175 {
176         return 0;
177 }
178 static inline const char **
179 find_next_mod_format(int start_index, void *v, const char **fmt, loff_t *pos)
180 {
181         return NULL;
182 }
183 static inline void format_mod_start(void) { }
184 static inline void format_mod_stop(void) { }
185 #endif /* CONFIG_MODULES */
186
187 static bool __read_mostly trace_printk_enabled = true;
188
189 void trace_printk_control(bool enabled)
190 {
191         trace_printk_enabled = enabled;
192 }
193
194 __initdata_or_module static
195 struct notifier_block module_trace_bprintk_format_nb = {
196         .notifier_call = module_trace_bprintk_format_notify,
197 };
198
199 int __trace_bprintk(unsigned long ip, const char *fmt, ...)
200 {
201         int ret;
202         va_list ap;
203
204         if (unlikely(!fmt))
205                 return 0;
206
207         if (!trace_printk_enabled)
208                 return 0;
209
210         va_start(ap, fmt);
211         ret = trace_vbprintk(ip, fmt, ap);
212         va_end(ap);
213         return ret;
214 }
215 EXPORT_SYMBOL_GPL(__trace_bprintk);
216
217 int __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap)
218 {
219         if (unlikely(!fmt))
220                 return 0;
221
222         if (!trace_printk_enabled)
223                 return 0;
224
225         return trace_vbprintk(ip, fmt, ap);
226 }
227 EXPORT_SYMBOL_GPL(__ftrace_vbprintk);
228
229 int __trace_printk(unsigned long ip, const char *fmt, ...)
230 {
231         int ret;
232         va_list ap;
233
234         if (!trace_printk_enabled)
235                 return 0;
236
237         va_start(ap, fmt);
238         ret = trace_vprintk(ip, fmt, ap);
239         va_end(ap);
240         return ret;
241 }
242 EXPORT_SYMBOL_GPL(__trace_printk);
243
244 int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap)
245 {
246         if (!trace_printk_enabled)
247                 return 0;
248
249         return trace_vprintk(ip, fmt, ap);
250 }
251 EXPORT_SYMBOL_GPL(__ftrace_vprintk);
252
253 static const char **find_next(void *v, loff_t *pos)
254 {
255         const char **fmt = v;
256         int start_index;
257         int last_index;
258
259         start_index = __stop___trace_bprintk_fmt - __start___trace_bprintk_fmt;
260
261         if (*pos < start_index)
262                 return __start___trace_bprintk_fmt + *pos;
263
264         /*
265          * The __tracepoint_str section is treated the same as the
266          * __trace_printk_fmt section. The difference is that the
267          * __trace_printk_fmt section should only be used by trace_printk()
268          * in a debugging environment, as if anything exists in that section
269          * the trace_prink() helper buffers are allocated, which would just
270          * waste space in a production environment.
271          *
272          * The __tracepoint_str sections on the other hand are used by
273          * tracepoints which need to map pointers to their strings to
274          * the ASCII text for userspace.
275          */
276         last_index = start_index;
277         start_index = __stop___tracepoint_str - __start___tracepoint_str;
278
279         if (*pos < last_index + start_index)
280                 return __start___tracepoint_str + (*pos - last_index);
281
282         start_index += last_index;
283         return find_next_mod_format(start_index, v, fmt, pos);
284 }
285
286 static void *
287 t_start(struct seq_file *m, loff_t *pos)
288 {
289         format_mod_start();
290         return find_next(NULL, pos);
291 }
292
293 static void *t_next(struct seq_file *m, void * v, loff_t *pos)
294 {
295         (*pos)++;
296         return find_next(v, pos);
297 }
298
299 static int t_show(struct seq_file *m, void *v)
300 {
301         const char **fmt = v;
302         const char *str = *fmt;
303         int i;
304
305         if (!*fmt)
306                 return 0;
307
308         seq_printf(m, "0x%lx : \"", *(unsigned long *)fmt);
309
310         /*
311          * Tabs and new lines need to be converted.
312          */
313         for (i = 0; str[i]; i++) {
314                 switch (str[i]) {
315                 case '\n':
316                         seq_puts(m, "\\n");
317                         break;
318                 case '\t':
319                         seq_puts(m, "\\t");
320                         break;
321                 case '\\':
322                         seq_putc(m, '\\');
323                         break;
324                 case '"':
325                         seq_puts(m, "\\\"");
326                         break;
327                 default:
328                         seq_putc(m, str[i]);
329                 }
330         }
331         seq_puts(m, "\"\n");
332
333         return 0;
334 }
335
336 static void t_stop(struct seq_file *m, void *p)
337 {
338         format_mod_stop();
339 }
340
341 static const struct seq_operations show_format_seq_ops = {
342         .start = t_start,
343         .next = t_next,
344         .show = t_show,
345         .stop = t_stop,
346 };
347
348 static int
349 ftrace_formats_open(struct inode *inode, struct file *file)
350 {
351         return seq_open(file, &show_format_seq_ops);
352 }
353
354 static const struct file_operations ftrace_formats_fops = {
355         .open = ftrace_formats_open,
356         .read = seq_read,
357         .llseek = seq_lseek,
358         .release = seq_release,
359 };
360
361 static __init int init_trace_printk_function_export(void)
362 {
363         struct dentry *d_tracer;
364
365         d_tracer = tracing_init_dentry();
366         if (IS_ERR(d_tracer))
367                 return 0;
368
369         trace_create_file("printk_formats", 0444, d_tracer,
370                                     NULL, &ftrace_formats_fops);
371
372         return 0;
373 }
374
375 fs_initcall(init_trace_printk_function_export);
376
377 static __init int init_trace_printk(void)
378 {
379         return register_module_notifier(&module_trace_bprintk_format_nb);
380 }
381
382 early_initcall(init_trace_printk);