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 container_of() 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); 383