blob: fad6c34c930d92a10df19b214af5238d347bbc23 [file] [log] [blame]
Jason Barone9d376f2009-02-05 11:51:38 -05001/*
2 * lib/dynamic_debug.c
3 *
4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their
5 * source module.
6 *
7 * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
8 * By Greg Banks <gnb@melbourne.sgi.com>
9 * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved.
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010010 * Copyright (C) 2011 Bart Van Assche. All Rights Reserved.
Du, Changbin578b1e02014-01-23 15:54:14 -080011 * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
Jason Barone9d376f2009-02-05 11:51:38 -050012 */
13
Joe Perches4ad275e2011-08-11 14:36:33 -040014#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
15
Jason Barone9d376f2009-02-05 11:51:38 -050016#include <linux/kernel.h>
17#include <linux/module.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070018#include <linux/moduleparam.h>
19#include <linux/kallsyms.h>
20#include <linux/types.h>
Jason Barone9d376f2009-02-05 11:51:38 -050021#include <linux/mutex.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070022#include <linux/proc_fs.h>
Jason Barone9d376f2009-02-05 11:51:38 -050023#include <linux/seq_file.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070024#include <linux/list.h>
25#include <linux/sysctl.h>
Jason Barone9d376f2009-02-05 11:51:38 -050026#include <linux/ctype.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070027#include <linux/string.h>
Du, Changbin578b1e02014-01-23 15:54:14 -080028#include <linux/parser.h>
Andy Shevchenkod338b132013-04-30 15:27:32 -070029#include <linux/string_helpers.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070030#include <linux/uaccess.h>
Jason Barone9d376f2009-02-05 11:51:38 -050031#include <linux/dynamic_debug.h>
32#include <linux/debugfs.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090033#include <linux/slab.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070034#include <linux/jump_label.h>
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010035#include <linux/hardirq.h>
Greg Kroah-Hartmane8d97922011-02-03 15:59:58 -080036#include <linux/sched.h>
Greg Kroah-Hartmanfef15d22012-05-07 16:47:32 -070037#include <linux/device.h>
Jason Baronffa10cb2011-08-11 14:36:48 -040038#include <linux/netdevice.h>
Jason Barone9d376f2009-02-05 11:51:38 -050039
Gal Pressman923abb92019-05-01 13:48:13 +030040#include <rdma/ib_verbs.h>
41
Jim Cromiee5ebffe2020-07-19 17:10:45 -060042extern struct _ddebug __start___dyndbg[];
43extern struct _ddebug __stop___dyndbg[];
Jason Barone9d376f2009-02-05 11:51:38 -050044
Jason Barone9d376f2009-02-05 11:51:38 -050045struct ddebug_table {
46 struct list_head link;
Rasmus Villemoes3e406b12015-11-06 16:30:15 -080047 const char *mod_name;
Jason Barone9d376f2009-02-05 11:51:38 -050048 unsigned int num_ddebugs;
Jason Barone9d376f2009-02-05 11:51:38 -050049 struct _ddebug *ddebugs;
50};
51
52struct ddebug_query {
53 const char *filename;
54 const char *module;
55 const char *function;
56 const char *format;
57 unsigned int first_lineno, last_lineno;
58};
59
60struct ddebug_iter {
61 struct ddebug_table *table;
62 unsigned int idx;
63};
64
65static DEFINE_MUTEX(ddebug_lock);
66static LIST_HEAD(ddebug_tables);
Joe Perchesf657fd22012-12-05 16:48:26 -050067static int verbose;
Jim Cromie74df1382011-12-19 17:12:24 -050068module_param(verbose, int, 0644);
Jason Barone9d376f2009-02-05 11:51:38 -050069
Jim Cromie2b678312011-12-19 17:13:12 -050070/* Return the path relative to source root */
71static inline const char *trim_prefix(const char *path)
72{
73 int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
74
75 if (strncmp(path, __FILE__, skip))
76 skip = 0; /* prefix mismatch, don't skip */
77
78 return path + skip;
79}
80
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010081static struct { unsigned flag:8; char opt_char; } opt_array[] = {
82 { _DPRINTK_FLAGS_PRINT, 'p' },
83 { _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
84 { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
85 { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
86 { _DPRINTK_FLAGS_INCL_TID, 't' },
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050087 { _DPRINTK_FLAGS_NONE, '_' },
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010088};
89
Jim Cromief678ce82020-07-19 17:10:47 -060090struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };
91
Jason Barone9d376f2009-02-05 11:51:38 -050092/* format a string into buf[] which describes the _ddebug's flags */
Jim Cromief678ce82020-07-19 17:10:47 -060093static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)
Jason Barone9d376f2009-02-05 11:51:38 -050094{
Jim Cromief678ce82020-07-19 17:10:47 -060095 char *p = fb->buf;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010096 int i;
Jason Barone9d376f2009-02-05 11:51:38 -050097
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010098 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
Jim Cromief678ce82020-07-19 17:10:47 -060099 if (flags & opt_array[i].flag)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100100 *p++ = opt_array[i].opt_char;
Jim Cromief678ce82020-07-19 17:10:47 -0600101 if (p == fb->buf)
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500102 *p++ = '_';
Jason Barone9d376f2009-02-05 11:51:38 -0500103 *p = '\0';
104
Jim Cromief678ce82020-07-19 17:10:47 -0600105 return fb->buf;
Jason Barone9d376f2009-02-05 11:51:38 -0500106}
107
Jim Cromie481c0e32020-07-19 17:10:44 -0600108#define vnpr_info(lvl, fmt, ...) \
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600109do { \
Jim Cromie481c0e32020-07-19 17:10:44 -0600110 if (verbose >= lvl) \
Joe Perchesf657fd22012-12-05 16:48:26 -0500111 pr_info(fmt, ##__VA_ARGS__); \
Jim Cromie574b3722011-12-19 17:13:16 -0500112} while (0)
113
Jim Cromie481c0e32020-07-19 17:10:44 -0600114#define vpr_info(fmt, ...) vnpr_info(1, fmt, ##__VA_ARGS__)
115#define v2pr_info(fmt, ...) vnpr_info(2, fmt, ##__VA_ARGS__)
116
Joe Perchesf657fd22012-12-05 16:48:26 -0500117static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
118{
119 /* trim any trailing newlines */
120 int fmtlen = 0;
121
122 if (query->format) {
123 fmtlen = strlen(query->format);
124 while (fmtlen && query->format[fmtlen - 1] == '\n')
125 fmtlen--;
126 }
127
128 vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
129 msg,
Jim Cromief62fc082020-07-19 17:10:51 -0600130 query->function ?: "",
131 query->filename ?: "",
132 query->module ?: "",
133 fmtlen, query->format ?: "",
Joe Perchesf657fd22012-12-05 16:48:26 -0500134 query->first_lineno, query->last_lineno);
135}
136
Jason Barone9d376f2009-02-05 11:51:38 -0500137/*
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500138 * Search the tables for _ddebug's which match the given `query' and
139 * apply the `flags' and `mask' to them. Returns number of matching
140 * callsites, normally the same as number of changes. If verbose,
141 * logs the changes. Takes ddebug_lock.
Jason Barone9d376f2009-02-05 11:51:38 -0500142 */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500143static int ddebug_change(const struct ddebug_query *query,
144 unsigned int flags, unsigned int mask)
Jason Barone9d376f2009-02-05 11:51:38 -0500145{
146 int i;
147 struct ddebug_table *dt;
148 unsigned int newflags;
149 unsigned int nfound = 0;
Jim Cromief678ce82020-07-19 17:10:47 -0600150 struct flagsbuf fbuf;
Jason Barone9d376f2009-02-05 11:51:38 -0500151
152 /* search for matching ddebugs */
153 mutex_lock(&ddebug_lock);
154 list_for_each_entry(dt, &ddebug_tables, link) {
155
156 /* match against the module name */
Du, Changbin578b1e02014-01-23 15:54:14 -0800157 if (query->module &&
158 !match_wildcard(query->module, dt->mod_name))
Jason Barone9d376f2009-02-05 11:51:38 -0500159 continue;
160
Joe Perchesf657fd22012-12-05 16:48:26 -0500161 for (i = 0; i < dt->num_ddebugs; i++) {
Jason Barone9d376f2009-02-05 11:51:38 -0500162 struct _ddebug *dp = &dt->ddebugs[i];
163
164 /* match against the source filename */
Jim Cromied6a238d2011-12-19 17:12:39 -0500165 if (query->filename &&
Du, Changbin578b1e02014-01-23 15:54:14 -0800166 !match_wildcard(query->filename, dp->filename) &&
167 !match_wildcard(query->filename,
168 kbasename(dp->filename)) &&
169 !match_wildcard(query->filename,
170 trim_prefix(dp->filename)))
Jason Barone9d376f2009-02-05 11:51:38 -0500171 continue;
172
173 /* match against the function */
Jim Cromied6a238d2011-12-19 17:12:39 -0500174 if (query->function &&
Du, Changbin578b1e02014-01-23 15:54:14 -0800175 !match_wildcard(query->function, dp->function))
Jason Barone9d376f2009-02-05 11:51:38 -0500176 continue;
177
178 /* match against the format */
Jim Cromied6a238d2011-12-19 17:12:39 -0500179 if (query->format &&
180 !strstr(dp->format, query->format))
Jason Barone9d376f2009-02-05 11:51:38 -0500181 continue;
182
183 /* match against the line number range */
184 if (query->first_lineno &&
185 dp->lineno < query->first_lineno)
186 continue;
187 if (query->last_lineno &&
188 dp->lineno > query->last_lineno)
189 continue;
190
191 nfound++;
192
193 newflags = (dp->flags & mask) | flags;
194 if (newflags == dp->flags)
195 continue;
Masahiro Yamadae9666d12018-12-31 00:14:15 +0900196#ifdef CONFIG_JUMP_LABEL
Jason Baron9049fc72016-08-03 13:46:39 -0700197 if (dp->flags & _DPRINTK_FLAGS_PRINT) {
198 if (!(flags & _DPRINTK_FLAGS_PRINT))
199 static_branch_disable(&dp->key.dd_key_true);
200 } else if (flags & _DPRINTK_FLAGS_PRINT)
201 static_branch_enable(&dp->key.dd_key_true);
202#endif
Jason Barone9d376f2009-02-05 11:51:38 -0500203 dp->flags = newflags;
Jim Cromie481c0e32020-07-19 17:10:44 -0600204 v2pr_info("changed %s:%d [%s]%s =%s\n",
Joe Perchesf657fd22012-12-05 16:48:26 -0500205 trim_prefix(dp->filename), dp->lineno,
206 dt->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600207 ddebug_describe_flags(dp->flags, &fbuf));
Jason Barone9d376f2009-02-05 11:51:38 -0500208 }
209 }
210 mutex_unlock(&ddebug_lock);
211
212 if (!nfound && verbose)
Joe Perches4ad275e2011-08-11 14:36:33 -0400213 pr_info("no matches for query\n");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500214
215 return nfound;
Jason Barone9d376f2009-02-05 11:51:38 -0500216}
217
218/*
Jason Barone9d376f2009-02-05 11:51:38 -0500219 * Split the buffer `buf' into space-separated words.
Greg Banks9898abb2009-02-06 12:54:26 +1100220 * Handles simple " and ' quoting, i.e. without nested,
221 * embedded or escaped \". Return the number of words
222 * or <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500223 */
224static int ddebug_tokenize(char *buf, char *words[], int maxwords)
225{
226 int nwords = 0;
227
Greg Banks9898abb2009-02-06 12:54:26 +1100228 while (*buf) {
229 char *end;
230
231 /* Skip leading whitespace */
André Goddard Rosae7d28602009-12-14 18:01:06 -0800232 buf = skip_spaces(buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100233 if (!*buf)
234 break; /* oh, it was trailing whitespace */
Jim Cromie8bd60262011-12-19 17:13:03 -0500235 if (*buf == '#')
236 break; /* token starts comment, skip rest of line */
Greg Banks9898abb2009-02-06 12:54:26 +1100237
Jim Cromie07100be2011-12-19 17:11:09 -0500238 /* find `end' of word, whitespace separated or quoted */
Greg Banks9898abb2009-02-06 12:54:26 +1100239 if (*buf == '"' || *buf == '\'') {
240 int quote = *buf++;
Joe Perchesf657fd22012-12-05 16:48:26 -0500241 for (end = buf; *end && *end != quote; end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100242 ;
Jim Cromie18c216c2012-12-05 16:48:27 -0500243 if (!*end) {
244 pr_err("unclosed quote: %s\n", buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100245 return -EINVAL; /* unclosed quote */
Jim Cromie18c216c2012-12-05 16:48:27 -0500246 }
Greg Banks9898abb2009-02-06 12:54:26 +1100247 } else {
Joe Perchesf657fd22012-12-05 16:48:26 -0500248 for (end = buf; *end && !isspace(*end); end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100249 ;
250 BUG_ON(end == buf);
251 }
Greg Banks9898abb2009-02-06 12:54:26 +1100252
Jim Cromie07100be2011-12-19 17:11:09 -0500253 /* `buf' is start of word, `end' is one past its end */
Jim Cromie18c216c2012-12-05 16:48:27 -0500254 if (nwords == maxwords) {
255 pr_err("too many words, legal max <=%d\n", maxwords);
Greg Banks9898abb2009-02-06 12:54:26 +1100256 return -EINVAL; /* ran out of words[] before bytes */
Jim Cromie18c216c2012-12-05 16:48:27 -0500257 }
Greg Banks9898abb2009-02-06 12:54:26 +1100258 if (*end)
259 *end++ = '\0'; /* terminate the word */
260 words[nwords++] = buf;
261 buf = end;
262 }
Jason Barone9d376f2009-02-05 11:51:38 -0500263
264 if (verbose) {
265 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400266 pr_info("split into words:");
Joe Perchesf657fd22012-12-05 16:48:26 -0500267 for (i = 0; i < nwords; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400268 pr_cont(" \"%s\"", words[i]);
269 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500270 }
271
272 return nwords;
273}
274
275/*
276 * Parse a single line number. Note that the empty string ""
277 * is treated as a special case and converted to zero, which
278 * is later treated as a "don't care" value.
279 */
280static inline int parse_lineno(const char *str, unsigned int *val)
281{
Jason Barone9d376f2009-02-05 11:51:38 -0500282 BUG_ON(str == NULL);
283 if (*str == '\0') {
284 *val = 0;
285 return 0;
286 }
Andrey Ryabinin45925992014-01-27 17:06:59 -0800287 if (kstrtouint(str, 10, val) < 0) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500288 pr_err("bad line-number: %s\n", str);
289 return -EINVAL;
290 }
291 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500292}
293
Jim Cromie80370722020-07-19 17:10:52 -0600294static int parse_linerange(struct ddebug_query *query, const char *first)
295{
296 char *last = strchr(first, '-');
297
298 if (query->first_lineno || query->last_lineno) {
299 pr_err("match-spec: line used 2x\n");
300 return -EINVAL;
301 }
302 if (last)
303 *last++ = '\0';
304 if (parse_lineno(first, &query->first_lineno) < 0)
305 return -EINVAL;
306 if (last) {
307 /* range <first>-<last> */
308 if (parse_lineno(last, &query->last_lineno) < 0)
309 return -EINVAL;
310
311 /* special case for last lineno not specified */
312 if (query->last_lineno == 0)
313 query->last_lineno = UINT_MAX;
314
315 if (query->last_lineno < query->first_lineno) {
316 pr_err("last-line:%d < 1st-line:%d\n",
317 query->last_lineno,
318 query->first_lineno);
319 return -EINVAL;
320 }
321 } else {
322 query->last_lineno = query->first_lineno;
323 }
324 vpr_info("parsed line %d-%d\n", query->first_lineno,
325 query->last_lineno);
326 return 0;
327}
328
Jim Cromie820874c2011-12-19 17:12:49 -0500329static int check_set(const char **dest, char *src, char *name)
330{
331 int rc = 0;
332
333 if (*dest) {
334 rc = -EINVAL;
Joe Perchesf657fd22012-12-05 16:48:26 -0500335 pr_err("match-spec:%s val:%s overridden by %s\n",
336 name, *dest, src);
Jim Cromie820874c2011-12-19 17:12:49 -0500337 }
338 *dest = src;
339 return rc;
340}
341
Jason Barone9d376f2009-02-05 11:51:38 -0500342/*
343 * Parse words[] as a ddebug query specification, which is a series
Jim Cromie14775b02020-07-19 17:10:54 -0600344 * of (keyword, value) pairs or combined keyword=value terms,
345 * chosen from these possibilities:
Jason Barone9d376f2009-02-05 11:51:38 -0500346 *
347 * func <function-name>
348 * file <full-pathname>
349 * file <base-filename>
350 * module <module-name>
351 * format <escaped-string-to-find-in-format>
352 * line <lineno>
353 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500354 *
355 * Only 1 of each type is allowed.
356 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500357 */
358static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600359 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500360{
361 unsigned int i;
jbaron@akamai.combd8c154a2013-08-27 16:50:03 +0000362 int rc = 0;
Jim Cromieaaebe322020-07-19 17:10:53 -0600363 char *fline;
Jim Cromie14775b02020-07-19 17:10:54 -0600364 char *keyword, *arg;
Jason Barone9d376f2009-02-05 11:51:38 -0500365
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600366 if (modname)
367 /* support $modname.dyndbg=<multiple queries> */
368 query->module = modname;
369
Jim Cromie14775b02020-07-19 17:10:54 -0600370 for (i = 0; i < nwords; i++) {
371 /* accept keyword=arg */
372 vpr_info("%d w:%s\n", i, words[i]);
373
374 keyword = words[i];
375 arg = strchr(keyword, '=');
376 if (arg) {
377 *arg++ = '\0';
378 } else {
379 i++; /* next word is arg */
380 if (!(i < nwords)) {
381 pr_err("missing arg to keyword: %s\n", keyword);
382 return -EINVAL;
383 }
384 arg = words[i];
385 }
386 vpr_info("%d key:%s arg:%s\n", i, keyword, arg);
387
388 if (!strcmp(keyword, "func")) {
389 rc = check_set(&query->function, arg, "func");
390 } else if (!strcmp(keyword, "file")) {
391 if (check_set(&query->filename, arg, "file"))
Jim Cromieaaebe322020-07-19 17:10:53 -0600392 return -EINVAL;
393
394 /* tail :$info is function or line-range */
395 fline = strchr(query->filename, ':');
396 if (!fline)
397 break;
398 *fline++ = '\0';
399 if (isalpha(*fline) || *fline == '*' || *fline == '?') {
400 /* take as function name */
401 if (check_set(&query->function, fline, "func"))
402 return -EINVAL;
403 } else {
404 if (parse_linerange(query, fline))
405 return -EINVAL;
406 }
Jim Cromie14775b02020-07-19 17:10:54 -0600407 } else if (!strcmp(keyword, "module")) {
408 rc = check_set(&query->module, arg, "module");
409 } else if (!strcmp(keyword, "format")) {
410 string_unescape_inplace(arg, UNESCAPE_SPACE |
Andy Shevchenkod338b132013-04-30 15:27:32 -0700411 UNESCAPE_OCTAL |
412 UNESCAPE_SPECIAL);
Jim Cromie14775b02020-07-19 17:10:54 -0600413 rc = check_set(&query->format, arg, "format");
414 } else if (!strcmp(keyword, "line")) {
415 if (parse_linerange(query, arg))
Jim Cromie820874c2011-12-19 17:12:49 -0500416 return -EINVAL;
Jason Barone9d376f2009-02-05 11:51:38 -0500417 } else {
Jim Cromie14775b02020-07-19 17:10:54 -0600418 pr_err("unknown keyword \"%s\"\n", keyword);
Jason Barone9d376f2009-02-05 11:51:38 -0500419 return -EINVAL;
420 }
Jim Cromie820874c2011-12-19 17:12:49 -0500421 if (rc)
422 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500423 }
Jim Cromie574b3722011-12-19 17:13:16 -0500424 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500425 return 0;
426}
427
428/*
429 * Parse `str' as a flags specification, format [-+=][p]+.
430 * Sets up *maskp and *flagsp to be used when changing the
431 * flags fields of matched _ddebug's. Returns 0 on success
432 * or <0 on error.
433 */
434static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
435 unsigned int *maskp)
436{
437 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100438 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500439
440 switch (*str) {
441 case '+':
442 case '-':
443 case '=':
444 op = *str++;
445 break;
446 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500447 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500448 return -EINVAL;
449 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600450 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500451
Joe Perchesf657fd22012-12-05 16:48:26 -0500452 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100453 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
454 if (*str == opt_array[i].opt_char) {
455 flags |= opt_array[i].flag;
456 break;
457 }
Jason Barone9d376f2009-02-05 11:51:38 -0500458 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500459 if (i < 0) {
Jim Cromie0b8f96b2020-07-19 17:10:48 -0600460 pr_err("unknown flag '%c'\n", *str);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100461 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500462 }
Jason Barone9d376f2009-02-05 11:51:38 -0500463 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600464 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500465
466 /* calculate final *flagsp, *maskp according to mask and op */
467 switch (op) {
468 case '=':
469 *maskp = 0;
470 *flagsp = flags;
471 break;
472 case '+':
473 *maskp = ~0U;
474 *flagsp = flags;
475 break;
476 case '-':
477 *maskp = ~flags;
478 *flagsp = 0;
479 break;
480 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600481 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500482 return 0;
483}
484
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600485static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200486{
487 unsigned int flags = 0, mask = 0;
Jim Cromie9c9d0ac2020-07-19 17:10:49 -0600488 struct ddebug_query query = {};
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200489#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500490 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200491 char *words[MAXWORDS];
492
493 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500494 if (nwords <= 0) {
495 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200496 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500497 }
498 /* check flags 1st (last arg) so query is pairs of spec,val */
499 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
500 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200501 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500502 }
503 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
504 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200505 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500506 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200507 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500508 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500509 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500510
511 return nfound;
512}
513
514/* handle multiple queries in query string, continue on error, return
515 last error or number of matching callsites. Module name is either
516 in param (for boot arg) or perhaps in query string.
517*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600518static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500519{
520 char *split;
521 int i, errs = 0, exitcode = 0, rc, nfound = 0;
522
523 for (i = 0; query; query = split) {
524 split = strpbrk(query, ";\n");
525 if (split)
526 *split++ = '\0';
527
528 query = skip_spaces(query);
529 if (!query || !*query || *query == '#')
530 continue;
531
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600532 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500533
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600534 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500535 if (rc < 0) {
536 errs++;
537 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500538 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500539 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500540 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500541 i++;
542 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600543 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500544 i, nfound, errs);
545
546 if (exitcode)
547 return exitcode;
548 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200549}
550
Jason Baron431625d2011-10-04 14:13:19 -0700551#define PREFIX_SIZE 64
552
553static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100554{
Jason Baron431625d2011-10-04 14:13:19 -0700555 if (PREFIX_SIZE - wrote > 0)
556 return PREFIX_SIZE - wrote;
557 return 0;
558}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100559
Jason Baron431625d2011-10-04 14:13:19 -0700560static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
561{
562 int pos_after_tid;
563 int pos = 0;
564
Joe Perches798efc62012-09-12 20:11:29 -0700565 *buf = '\0';
566
Jason Baron431625d2011-10-04 14:13:19 -0700567 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100568 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700569 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100570 else
Jason Baron431625d2011-10-04 14:13:19 -0700571 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700572 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100573 }
Jason Baron431625d2011-10-04 14:13:19 -0700574 pos_after_tid = pos;
575 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
576 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700577 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700578 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
579 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700580 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700581 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500582 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700583 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700584 if (pos - pos_after_tid)
585 pos += snprintf(buf + pos, remaining(pos), " ");
586 if (pos >= PREFIX_SIZE)
587 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400588
Jason Baron431625d2011-10-04 14:13:19 -0700589 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400590}
591
Joe Perches906d2012014-09-24 11:17:56 -0700592void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100593{
594 va_list args;
Jason Baron431625d2011-10-04 14:13:19 -0700595 struct va_format vaf;
596 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100597
598 BUG_ON(!descriptor);
599 BUG_ON(!fmt);
600
601 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700602
Jason Baron431625d2011-10-04 14:13:19 -0700603 vaf.fmt = fmt;
604 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700605
Joe Perches906d2012014-09-24 11:17:56 -0700606 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700607
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100608 va_end(args);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100609}
610EXPORT_SYMBOL(__dynamic_pr_debug);
611
Joe Perches906d2012014-09-24 11:17:56 -0700612void __dynamic_dev_dbg(struct _ddebug *descriptor,
Joe Perchescbc46632011-08-11 14:36:21 -0400613 const struct device *dev, const char *fmt, ...)
614{
615 struct va_format vaf;
616 va_list args;
Joe Perchescbc46632011-08-11 14:36:21 -0400617
618 BUG_ON(!descriptor);
619 BUG_ON(!fmt);
620
621 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700622
Joe Perchescbc46632011-08-11 14:36:21 -0400623 vaf.fmt = fmt;
624 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700625
626 if (!dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700627 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700628 } else {
629 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700630
Joe Perchesa39d4a82014-12-10 15:50:15 -0800631 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
Joe Perches906d2012014-09-24 11:17:56 -0700632 dynamic_emit_prefix(descriptor, buf),
633 dev_driver_string(dev), dev_name(dev),
634 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700635 }
636
Joe Perchescbc46632011-08-11 14:36:21 -0400637 va_end(args);
Joe Perchescbc46632011-08-11 14:36:21 -0400638}
639EXPORT_SYMBOL(__dynamic_dev_dbg);
640
Jason Baron0feefd92011-10-04 14:13:22 -0700641#ifdef CONFIG_NET
642
Joe Perches906d2012014-09-24 11:17:56 -0700643void __dynamic_netdev_dbg(struct _ddebug *descriptor,
644 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400645{
646 struct va_format vaf;
647 va_list args;
Jason Baronffa10cb2011-08-11 14:36:48 -0400648
649 BUG_ON(!descriptor);
650 BUG_ON(!fmt);
651
652 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700653
Jason Baronffa10cb2011-08-11 14:36:48 -0400654 vaf.fmt = fmt;
655 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700656
657 if (dev && dev->dev.parent) {
658 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700659
Joe Perchesa39d4a82014-12-10 15:50:15 -0800660 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
Joe Perches906d2012014-09-24 11:17:56 -0700661 "%s%s %s %s%s: %pV",
662 dynamic_emit_prefix(descriptor, buf),
663 dev_driver_string(dev->dev.parent),
664 dev_name(dev->dev.parent),
665 netdev_name(dev), netdev_reg_state(dev),
666 &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700667 } else if (dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700668 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
669 netdev_reg_state(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700670 } else {
Joe Perches906d2012014-09-24 11:17:56 -0700671 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700672 }
673
Jason Baronffa10cb2011-08-11 14:36:48 -0400674 va_end(args);
Jason Baronffa10cb2011-08-11 14:36:48 -0400675}
676EXPORT_SYMBOL(__dynamic_netdev_dbg);
677
Jason Baron0feefd92011-10-04 14:13:22 -0700678#endif
679
Gal Pressman923abb92019-05-01 13:48:13 +0300680#if IS_ENABLED(CONFIG_INFINIBAND)
681
682void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
683 const struct ib_device *ibdev, const char *fmt, ...)
684{
685 struct va_format vaf;
686 va_list args;
687
688 va_start(args, fmt);
689
690 vaf.fmt = fmt;
691 vaf.va = &args;
692
693 if (ibdev && ibdev->dev.parent) {
694 char buf[PREFIX_SIZE];
695
696 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
697 "%s%s %s %s: %pV",
698 dynamic_emit_prefix(descriptor, buf),
699 dev_driver_string(ibdev->dev.parent),
700 dev_name(ibdev->dev.parent),
701 dev_name(&ibdev->dev),
702 &vaf);
703 } else if (ibdev) {
704 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
705 } else {
706 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
707 }
708
709 va_end(args);
710}
711EXPORT_SYMBOL(__dynamic_ibdev_dbg);
712
713#endif
714
Jim Cromiebc757f62011-12-19 17:12:29 -0500715#define DDEBUG_STRING_SIZE 1024
716static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
717
Thomas Renningera648ec02010-08-06 16:11:02 +0200718static __init int ddebug_setup_query(char *str)
719{
Jim Cromiebc757f62011-12-19 17:12:29 -0500720 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400721 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200722 return 0;
723 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500724 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200725 return 1;
726}
727
728__setup("ddebug_query=", ddebug_setup_query);
729
Jason Barone9d376f2009-02-05 11:51:38 -0500730/*
Masatake YAMATO231821d2014-12-15 12:04:16 +0900731 * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
Jason Barone9d376f2009-02-05 11:51:38 -0500732 * command text from userspace, parses and executes it.
733 */
Jim Cromie72814912011-12-19 17:13:07 -0500734#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500735static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
736 size_t len, loff_t *offp)
737{
Jim Cromie72814912011-12-19 17:13:07 -0500738 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200739 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500740
741 if (len == 0)
742 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500743 if (len > USER_BUF_PAGE - 1) {
744 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500745 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500746 }
Al Viro16e5c1f2015-12-24 00:06:05 -0500747 tmpbuf = memdup_user_nul(ubuf, len);
748 if (IS_ERR(tmpbuf))
749 return PTR_ERR(tmpbuf);
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600750 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500751
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600752 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500753 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500754 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200755 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500756
757 *offp += len;
758 return len;
759}
760
761/*
762 * Set the iterator to point to the first _ddebug object
763 * and return a pointer to that first object. Returns
764 * NULL if there are no _ddebugs at all.
765 */
766static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
767{
768 if (list_empty(&ddebug_tables)) {
769 iter->table = NULL;
770 iter->idx = 0;
771 return NULL;
772 }
773 iter->table = list_entry(ddebug_tables.next,
774 struct ddebug_table, link);
775 iter->idx = 0;
776 return &iter->table->ddebugs[iter->idx];
777}
778
779/*
780 * Advance the iterator to point to the next _ddebug
781 * object from the one the iterator currently points at,
782 * and returns a pointer to the new _ddebug. Returns
783 * NULL if the iterator has seen all the _ddebugs.
784 */
785static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
786{
787 if (iter->table == NULL)
788 return NULL;
789 if (++iter->idx == iter->table->num_ddebugs) {
790 /* iterate to next table */
791 iter->idx = 0;
792 if (list_is_last(&iter->table->link, &ddebug_tables)) {
793 iter->table = NULL;
794 return NULL;
795 }
796 iter->table = list_entry(iter->table->link.next,
797 struct ddebug_table, link);
798 }
799 return &iter->table->ddebugs[iter->idx];
800}
801
802/*
803 * Seq_ops start method. Called at the start of every
804 * read() call from userspace. Takes the ddebug_lock and
805 * seeks the seq_file's iterator to the given position.
806 */
807static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
808{
809 struct ddebug_iter *iter = m->private;
810 struct _ddebug *dp;
811 int n = *pos;
812
Jason Barone9d376f2009-02-05 11:51:38 -0500813 mutex_lock(&ddebug_lock);
814
815 if (!n)
816 return SEQ_START_TOKEN;
817 if (n < 0)
818 return NULL;
819 dp = ddebug_iter_first(iter);
820 while (dp != NULL && --n > 0)
821 dp = ddebug_iter_next(iter);
822 return dp;
823}
824
825/*
826 * Seq_ops next method. Called several times within a read()
827 * call from userspace, with ddebug_lock held. Walks to the
828 * next _ddebug object with a special case for the header line.
829 */
830static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
831{
832 struct ddebug_iter *iter = m->private;
833 struct _ddebug *dp;
834
Jason Barone9d376f2009-02-05 11:51:38 -0500835 if (p == SEQ_START_TOKEN)
836 dp = ddebug_iter_first(iter);
837 else
838 dp = ddebug_iter_next(iter);
839 ++*pos;
840 return dp;
841}
842
843/*
844 * Seq_ops show method. Called several times within a read()
845 * call from userspace, with ddebug_lock held. Formats the
846 * current _ddebug as a single human-readable line, with a
847 * special case for the header line.
848 */
849static int ddebug_proc_show(struct seq_file *m, void *p)
850{
851 struct ddebug_iter *iter = m->private;
852 struct _ddebug *dp = p;
Jim Cromief678ce82020-07-19 17:10:47 -0600853 struct flagsbuf flags;
Jason Barone9d376f2009-02-05 11:51:38 -0500854
Jason Barone9d376f2009-02-05 11:51:38 -0500855 if (p == SEQ_START_TOKEN) {
856 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500857 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500858 return 0;
859 }
860
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500861 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500862 trim_prefix(dp->filename), dp->lineno,
863 iter->table->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600864 ddebug_describe_flags(dp->flags, &flags));
Jason Barone9d376f2009-02-05 11:51:38 -0500865 seq_escape(m, dp->format, "\t\r\n\"");
866 seq_puts(m, "\"\n");
867
868 return 0;
869}
870
871/*
872 * Seq_ops stop method. Called at the end of each read()
873 * call from userspace. Drops ddebug_lock.
874 */
875static void ddebug_proc_stop(struct seq_file *m, void *p)
876{
Jason Barone9d376f2009-02-05 11:51:38 -0500877 mutex_unlock(&ddebug_lock);
878}
879
880static const struct seq_operations ddebug_proc_seqops = {
881 .start = ddebug_proc_start,
882 .next = ddebug_proc_next,
883 .show = ddebug_proc_show,
884 .stop = ddebug_proc_stop
885};
886
Jason Barone9d376f2009-02-05 11:51:38 -0500887static int ddebug_proc_open(struct inode *inode, struct file *file)
888{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600889 vpr_info("called\n");
Rob Jones4bad78c2014-10-13 15:51:32 -0700890 return seq_open_private(file, &ddebug_proc_seqops,
891 sizeof(struct ddebug_iter));
Jason Barone9d376f2009-02-05 11:51:38 -0500892}
893
894static const struct file_operations ddebug_proc_fops = {
895 .owner = THIS_MODULE,
896 .open = ddebug_proc_open,
897 .read = seq_read,
898 .llseek = seq_lseek,
899 .release = seq_release_private,
900 .write = ddebug_proc_write
901};
902
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800903static const struct proc_ops proc_fops = {
904 .proc_open = ddebug_proc_open,
905 .proc_read = seq_read,
906 .proc_lseek = seq_lseek,
907 .proc_release = seq_release_private,
908 .proc_write = ddebug_proc_write
909};
910
Jason Barone9d376f2009-02-05 11:51:38 -0500911/*
912 * Allocate a new ddebug_table for the given module
913 * and add it to the global list.
914 */
915int ddebug_add_module(struct _ddebug *tab, unsigned int n,
916 const char *name)
917{
918 struct ddebug_table *dt;
Jason Barone9d376f2009-02-05 11:51:38 -0500919
920 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800921 if (dt == NULL) {
922 pr_err("error adding module: %s\n", name);
Jason Barone9d376f2009-02-05 11:51:38 -0500923 return -ENOMEM;
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800924 }
Rasmus Villemoescdf6d002019-03-07 16:27:37 -0800925 /*
926 * For built-in modules, name lives in .rodata and is
927 * immortal. For loaded modules, name points at the name[]
928 * member of struct module, which lives at least as long as
929 * this struct ddebug_table.
930 */
931 dt->mod_name = name;
Jason Barone9d376f2009-02-05 11:51:38 -0500932 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500933 dt->ddebugs = tab;
934
935 mutex_lock(&ddebug_lock);
Jim Cromie47e9f5a2020-07-19 17:10:50 -0600936 list_add(&dt->link, &ddebug_tables);
Jason Barone9d376f2009-02-05 11:51:38 -0500937 mutex_unlock(&ddebug_lock);
938
Jim Cromie481c0e32020-07-19 17:10:44 -0600939 v2pr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500940 return 0;
941}
Jason Barone9d376f2009-02-05 11:51:38 -0500942
Jim Cromie6ab676e2012-04-27 14:30:37 -0600943/* helper for ddebug_dyndbg_(boot|module)_param_cb */
944static int ddebug_dyndbg_param_cb(char *param, char *val,
945 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600946{
Jim Cromieb48420c2012-04-27 14:30:35 -0600947 char *sep;
948
949 sep = strchr(param, '.');
950 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600951 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600952 *sep = '\0';
953 modname = param;
954 param = sep + 1;
955 }
956 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600957 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600958
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600959 ddebug_exec_queries((val ? val : "+p"), modname);
960
Jim Cromieb48420c2012-04-27 14:30:35 -0600961 return 0; /* query failure shouldnt stop module load */
962}
963
Jim Cromie6ab676e2012-04-27 14:30:37 -0600964/* handle both dyndbg and $module.dyndbg params at boot */
965static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -0700966 const char *unused, void *arg)
Jim Cromieb48420c2012-04-27 14:30:35 -0600967{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600968 vpr_info("%s=\"%s\"\n", param, val);
969 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
970}
Jim Cromieb48420c2012-04-27 14:30:35 -0600971
Jim Cromie6ab676e2012-04-27 14:30:37 -0600972/*
973 * modprobe foo finds foo.params in boot-args, strips "foo.", and
974 * passes them to load_module(). This callback gets unknown params,
975 * processes dyndbg params, rejects others.
976 */
977int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
978{
979 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
980 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600981}
982
Jason Barone9d376f2009-02-05 11:51:38 -0500983static void ddebug_table_free(struct ddebug_table *dt)
984{
985 list_del_init(&dt->link);
Jason Barone9d376f2009-02-05 11:51:38 -0500986 kfree(dt);
987}
988
989/*
990 * Called in response to a module being unloaded. Removes
991 * any ddebug_table's which point at the module.
992 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000993int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500994{
995 struct ddebug_table *dt, *nextdt;
996 int ret = -ENOENT;
997
Jim Cromie481c0e32020-07-19 17:10:44 -0600998 v2pr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500999
1000 mutex_lock(&ddebug_lock);
1001 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
Rasmus Villemoes4573fe12019-03-07 16:27:41 -08001002 if (dt->mod_name == mod_name) {
Jason Barone9d376f2009-02-05 11:51:38 -05001003 ddebug_table_free(dt);
1004 ret = 0;
Rasmus Villemoes4573fe12019-03-07 16:27:41 -08001005 break;
Jason Barone9d376f2009-02-05 11:51:38 -05001006 }
1007 }
1008 mutex_unlock(&ddebug_lock);
1009 return ret;
1010}
Jason Barone9d376f2009-02-05 11:51:38 -05001011
1012static void ddebug_remove_all_tables(void)
1013{
1014 mutex_lock(&ddebug_lock);
1015 while (!list_empty(&ddebug_tables)) {
1016 struct ddebug_table *dt = list_entry(ddebug_tables.next,
1017 struct ddebug_table,
1018 link);
1019 ddebug_table_free(dt);
1020 }
1021 mutex_unlock(&ddebug_lock);
1022}
1023
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001024static __initdata int ddebug_init_success;
1025
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001026static int __init dynamic_debug_init_control(void)
Jason Barone9d376f2009-02-05 11:51:38 -05001027{
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001028 struct proc_dir_entry *procfs_dir;
1029 struct dentry *debugfs_dir;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001030
1031 if (!ddebug_init_success)
1032 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -05001033
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001034 /* Create the control file in debugfs if it is enabled */
1035 if (debugfs_initialized()) {
1036 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
1037 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1038 &ddebug_proc_fops);
1039 }
1040
1041 /* Also create the control file in procfs */
1042 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1043 if (procfs_dir)
1044 proc_create("control", 0644, procfs_dir, &proc_fops);
Greg Kroah-Hartman9fd714c2019-06-12 17:35:34 +02001045
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001046 return 0;
1047}
1048
1049static int __init dynamic_debug_init(void)
1050{
1051 struct _ddebug *iter, *iter_start;
1052 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001053 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001054 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001055 int n = 0, entries = 0, modct = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001056
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001057 if (&__start___dyndbg == &__stop___dyndbg) {
Orson Zhaiceabef72020-06-07 21:40:14 -07001058 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1059 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1060 return 1;
1061 }
1062 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1063 ddebug_init_success = 1;
1064 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -05001065 }
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001066 iter = __start___dyndbg;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001067 modname = iter->modname;
1068 iter_start = iter;
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001069 for (; iter < __stop___dyndbg; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001070 entries++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001071 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001072 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001073 ret = ddebug_add_module(iter_start, n, modname);
1074 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001075 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001076 n = 0;
1077 modname = iter->modname;
1078 iter_start = iter;
1079 }
1080 n++;
1081 }
1082 ret = ddebug_add_module(iter_start, n, modname);
1083 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001084 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001085
Jim Cromieaf442392012-04-27 14:30:38 -06001086 ddebug_init_success = 1;
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001087 vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in __dyndbg section\n",
Joe Perchesf657fd22012-12-05 16:48:26 -05001088 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001089 (int)(entries * sizeof(struct _ddebug)));
Jim Cromieaf442392012-04-27 14:30:38 -06001090
1091 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001092 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001093 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001094 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001095 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001096 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001097 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001098 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001099 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001100 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001101 /* now that ddebug tables are loaded, process all boot args
1102 * again to find and activate queries given in dyndbg params.
1103 * While this has already been done for known boot params, it
1104 * ignored the unknown ones (dyndbg in particular). Reusing
1105 * parse_args avoids ad-hoc parsing. This will also attempt
1106 * to activate queries for not-yet-loaded modules, which is
1107 * slightly noisy if verbose, but harmless.
1108 */
1109 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1110 parse_args("dyndbg params", cmdline, NULL,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -07001111 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
Jim Cromieb48420c2012-04-27 14:30:35 -06001112 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001113 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001114
Jim Cromieaf442392012-04-27 14:30:38 -06001115out_err:
1116 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001117 return 0;
1118}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001119/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001120early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001121
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001122/* Debugfs setup must be done later */
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001123fs_initcall(dynamic_debug_init_control);