blob: 7eb963b1bd1159ac6c8a63204eee471727da8426 [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
344 * of (keyword, value) pairs chosen from these possibilities:
345 *
346 * func <function-name>
347 * file <full-pathname>
348 * file <base-filename>
349 * module <module-name>
350 * format <escaped-string-to-find-in-format>
351 * line <lineno>
352 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500353 *
354 * Only 1 of each type is allowed.
355 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500356 */
357static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600358 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500359{
360 unsigned int i;
jbaron@akamai.combd8c154a2013-08-27 16:50:03 +0000361 int rc = 0;
Jim Cromieaaebe322020-07-19 17:10:53 -0600362 char *fline;
Jason Barone9d376f2009-02-05 11:51:38 -0500363
364 /* check we have an even number of words */
Jim Cromie18c216c2012-12-05 16:48:27 -0500365 if (nwords % 2 != 0) {
366 pr_err("expecting pairs of match-spec <value>\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500367 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500368 }
Jason Barone9d376f2009-02-05 11:51:38 -0500369
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600370 if (modname)
371 /* support $modname.dyndbg=<multiple queries> */
372 query->module = modname;
373
Joe Perchesf657fd22012-12-05 16:48:26 -0500374 for (i = 0; i < nwords; i += 2) {
375 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500376 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500377 } else if (!strcmp(words[i], "file")) {
Jim Cromieaaebe322020-07-19 17:10:53 -0600378 if (check_set(&query->filename, words[i+1], "file"))
379 return -EINVAL;
380
381 /* tail :$info is function or line-range */
382 fline = strchr(query->filename, ':');
383 if (!fline)
384 break;
385 *fline++ = '\0';
386 if (isalpha(*fline) || *fline == '*' || *fline == '?') {
387 /* take as function name */
388 if (check_set(&query->function, fline, "func"))
389 return -EINVAL;
390 } else {
391 if (parse_linerange(query, fline))
392 return -EINVAL;
393 }
Joe Perchesf657fd22012-12-05 16:48:26 -0500394 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500395 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500396 } else if (!strcmp(words[i], "format")) {
Andy Shevchenkod338b132013-04-30 15:27:32 -0700397 string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
398 UNESCAPE_OCTAL |
399 UNESCAPE_SPECIAL);
400 rc = check_set(&query->format, words[i+1], "format");
Joe Perchesf657fd22012-12-05 16:48:26 -0500401 } else if (!strcmp(words[i], "line")) {
Jim Cromie80370722020-07-19 17:10:52 -0600402 if (parse_linerange(query, words[i+1]))
Jim Cromie820874c2011-12-19 17:12:49 -0500403 return -EINVAL;
Jason Barone9d376f2009-02-05 11:51:38 -0500404 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500405 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500406 return -EINVAL;
407 }
Jim Cromie820874c2011-12-19 17:12:49 -0500408 if (rc)
409 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500410 }
Jim Cromie574b3722011-12-19 17:13:16 -0500411 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500412 return 0;
413}
414
415/*
416 * Parse `str' as a flags specification, format [-+=][p]+.
417 * Sets up *maskp and *flagsp to be used when changing the
418 * flags fields of matched _ddebug's. Returns 0 on success
419 * or <0 on error.
420 */
421static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
422 unsigned int *maskp)
423{
424 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100425 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500426
427 switch (*str) {
428 case '+':
429 case '-':
430 case '=':
431 op = *str++;
432 break;
433 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500434 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500435 return -EINVAL;
436 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600437 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500438
Joe Perchesf657fd22012-12-05 16:48:26 -0500439 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100440 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
441 if (*str == opt_array[i].opt_char) {
442 flags |= opt_array[i].flag;
443 break;
444 }
Jason Barone9d376f2009-02-05 11:51:38 -0500445 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500446 if (i < 0) {
Jim Cromie0b8f96b2020-07-19 17:10:48 -0600447 pr_err("unknown flag '%c'\n", *str);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100448 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500449 }
Jason Barone9d376f2009-02-05 11:51:38 -0500450 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600451 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500452
453 /* calculate final *flagsp, *maskp according to mask and op */
454 switch (op) {
455 case '=':
456 *maskp = 0;
457 *flagsp = flags;
458 break;
459 case '+':
460 *maskp = ~0U;
461 *flagsp = flags;
462 break;
463 case '-':
464 *maskp = ~flags;
465 *flagsp = 0;
466 break;
467 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600468 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500469 return 0;
470}
471
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600472static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200473{
474 unsigned int flags = 0, mask = 0;
Jim Cromie9c9d0ac2020-07-19 17:10:49 -0600475 struct ddebug_query query = {};
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200476#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500477 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200478 char *words[MAXWORDS];
479
480 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500481 if (nwords <= 0) {
482 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200483 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500484 }
485 /* check flags 1st (last arg) so query is pairs of spec,val */
486 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
487 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200488 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500489 }
490 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
491 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200492 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500493 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200494 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500495 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500496 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500497
498 return nfound;
499}
500
501/* handle multiple queries in query string, continue on error, return
502 last error or number of matching callsites. Module name is either
503 in param (for boot arg) or perhaps in query string.
504*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600505static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500506{
507 char *split;
508 int i, errs = 0, exitcode = 0, rc, nfound = 0;
509
510 for (i = 0; query; query = split) {
511 split = strpbrk(query, ";\n");
512 if (split)
513 *split++ = '\0';
514
515 query = skip_spaces(query);
516 if (!query || !*query || *query == '#')
517 continue;
518
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600519 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500520
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600521 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500522 if (rc < 0) {
523 errs++;
524 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500525 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500526 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500527 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500528 i++;
529 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600530 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500531 i, nfound, errs);
532
533 if (exitcode)
534 return exitcode;
535 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200536}
537
Jason Baron431625d2011-10-04 14:13:19 -0700538#define PREFIX_SIZE 64
539
540static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100541{
Jason Baron431625d2011-10-04 14:13:19 -0700542 if (PREFIX_SIZE - wrote > 0)
543 return PREFIX_SIZE - wrote;
544 return 0;
545}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100546
Jason Baron431625d2011-10-04 14:13:19 -0700547static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
548{
549 int pos_after_tid;
550 int pos = 0;
551
Joe Perches798efc62012-09-12 20:11:29 -0700552 *buf = '\0';
553
Jason Baron431625d2011-10-04 14:13:19 -0700554 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100555 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700556 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100557 else
Jason Baron431625d2011-10-04 14:13:19 -0700558 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700559 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100560 }
Jason Baron431625d2011-10-04 14:13:19 -0700561 pos_after_tid = pos;
562 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
563 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700564 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700565 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
566 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700567 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700568 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500569 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700570 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700571 if (pos - pos_after_tid)
572 pos += snprintf(buf + pos, remaining(pos), " ");
573 if (pos >= PREFIX_SIZE)
574 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400575
Jason Baron431625d2011-10-04 14:13:19 -0700576 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400577}
578
Joe Perches906d2012014-09-24 11:17:56 -0700579void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100580{
581 va_list args;
Jason Baron431625d2011-10-04 14:13:19 -0700582 struct va_format vaf;
583 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100584
585 BUG_ON(!descriptor);
586 BUG_ON(!fmt);
587
588 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700589
Jason Baron431625d2011-10-04 14:13:19 -0700590 vaf.fmt = fmt;
591 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700592
Joe Perches906d2012014-09-24 11:17:56 -0700593 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700594
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100595 va_end(args);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100596}
597EXPORT_SYMBOL(__dynamic_pr_debug);
598
Joe Perches906d2012014-09-24 11:17:56 -0700599void __dynamic_dev_dbg(struct _ddebug *descriptor,
Joe Perchescbc46632011-08-11 14:36:21 -0400600 const struct device *dev, const char *fmt, ...)
601{
602 struct va_format vaf;
603 va_list args;
Joe Perchescbc46632011-08-11 14:36:21 -0400604
605 BUG_ON(!descriptor);
606 BUG_ON(!fmt);
607
608 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700609
Joe Perchescbc46632011-08-11 14:36:21 -0400610 vaf.fmt = fmt;
611 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700612
613 if (!dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700614 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700615 } else {
616 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700617
Joe Perchesa39d4a82014-12-10 15:50:15 -0800618 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
Joe Perches906d2012014-09-24 11:17:56 -0700619 dynamic_emit_prefix(descriptor, buf),
620 dev_driver_string(dev), dev_name(dev),
621 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700622 }
623
Joe Perchescbc46632011-08-11 14:36:21 -0400624 va_end(args);
Joe Perchescbc46632011-08-11 14:36:21 -0400625}
626EXPORT_SYMBOL(__dynamic_dev_dbg);
627
Jason Baron0feefd92011-10-04 14:13:22 -0700628#ifdef CONFIG_NET
629
Joe Perches906d2012014-09-24 11:17:56 -0700630void __dynamic_netdev_dbg(struct _ddebug *descriptor,
631 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400632{
633 struct va_format vaf;
634 va_list args;
Jason Baronffa10cb2011-08-11 14:36:48 -0400635
636 BUG_ON(!descriptor);
637 BUG_ON(!fmt);
638
639 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700640
Jason Baronffa10cb2011-08-11 14:36:48 -0400641 vaf.fmt = fmt;
642 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700643
644 if (dev && dev->dev.parent) {
645 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700646
Joe Perchesa39d4a82014-12-10 15:50:15 -0800647 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
Joe Perches906d2012014-09-24 11:17:56 -0700648 "%s%s %s %s%s: %pV",
649 dynamic_emit_prefix(descriptor, buf),
650 dev_driver_string(dev->dev.parent),
651 dev_name(dev->dev.parent),
652 netdev_name(dev), netdev_reg_state(dev),
653 &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700654 } else if (dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700655 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
656 netdev_reg_state(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700657 } else {
Joe Perches906d2012014-09-24 11:17:56 -0700658 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700659 }
660
Jason Baronffa10cb2011-08-11 14:36:48 -0400661 va_end(args);
Jason Baronffa10cb2011-08-11 14:36:48 -0400662}
663EXPORT_SYMBOL(__dynamic_netdev_dbg);
664
Jason Baron0feefd92011-10-04 14:13:22 -0700665#endif
666
Gal Pressman923abb92019-05-01 13:48:13 +0300667#if IS_ENABLED(CONFIG_INFINIBAND)
668
669void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
670 const struct ib_device *ibdev, const char *fmt, ...)
671{
672 struct va_format vaf;
673 va_list args;
674
675 va_start(args, fmt);
676
677 vaf.fmt = fmt;
678 vaf.va = &args;
679
680 if (ibdev && ibdev->dev.parent) {
681 char buf[PREFIX_SIZE];
682
683 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
684 "%s%s %s %s: %pV",
685 dynamic_emit_prefix(descriptor, buf),
686 dev_driver_string(ibdev->dev.parent),
687 dev_name(ibdev->dev.parent),
688 dev_name(&ibdev->dev),
689 &vaf);
690 } else if (ibdev) {
691 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
692 } else {
693 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
694 }
695
696 va_end(args);
697}
698EXPORT_SYMBOL(__dynamic_ibdev_dbg);
699
700#endif
701
Jim Cromiebc757f62011-12-19 17:12:29 -0500702#define DDEBUG_STRING_SIZE 1024
703static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
704
Thomas Renningera648ec02010-08-06 16:11:02 +0200705static __init int ddebug_setup_query(char *str)
706{
Jim Cromiebc757f62011-12-19 17:12:29 -0500707 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400708 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200709 return 0;
710 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500711 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200712 return 1;
713}
714
715__setup("ddebug_query=", ddebug_setup_query);
716
Jason Barone9d376f2009-02-05 11:51:38 -0500717/*
Masatake YAMATO231821d2014-12-15 12:04:16 +0900718 * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
Jason Barone9d376f2009-02-05 11:51:38 -0500719 * command text from userspace, parses and executes it.
720 */
Jim Cromie72814912011-12-19 17:13:07 -0500721#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500722static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
723 size_t len, loff_t *offp)
724{
Jim Cromie72814912011-12-19 17:13:07 -0500725 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200726 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500727
728 if (len == 0)
729 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500730 if (len > USER_BUF_PAGE - 1) {
731 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500732 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500733 }
Al Viro16e5c1f2015-12-24 00:06:05 -0500734 tmpbuf = memdup_user_nul(ubuf, len);
735 if (IS_ERR(tmpbuf))
736 return PTR_ERR(tmpbuf);
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600737 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500738
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600739 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500740 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500741 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200742 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500743
744 *offp += len;
745 return len;
746}
747
748/*
749 * Set the iterator to point to the first _ddebug object
750 * and return a pointer to that first object. Returns
751 * NULL if there are no _ddebugs at all.
752 */
753static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
754{
755 if (list_empty(&ddebug_tables)) {
756 iter->table = NULL;
757 iter->idx = 0;
758 return NULL;
759 }
760 iter->table = list_entry(ddebug_tables.next,
761 struct ddebug_table, link);
762 iter->idx = 0;
763 return &iter->table->ddebugs[iter->idx];
764}
765
766/*
767 * Advance the iterator to point to the next _ddebug
768 * object from the one the iterator currently points at,
769 * and returns a pointer to the new _ddebug. Returns
770 * NULL if the iterator has seen all the _ddebugs.
771 */
772static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
773{
774 if (iter->table == NULL)
775 return NULL;
776 if (++iter->idx == iter->table->num_ddebugs) {
777 /* iterate to next table */
778 iter->idx = 0;
779 if (list_is_last(&iter->table->link, &ddebug_tables)) {
780 iter->table = NULL;
781 return NULL;
782 }
783 iter->table = list_entry(iter->table->link.next,
784 struct ddebug_table, link);
785 }
786 return &iter->table->ddebugs[iter->idx];
787}
788
789/*
790 * Seq_ops start method. Called at the start of every
791 * read() call from userspace. Takes the ddebug_lock and
792 * seeks the seq_file's iterator to the given position.
793 */
794static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
795{
796 struct ddebug_iter *iter = m->private;
797 struct _ddebug *dp;
798 int n = *pos;
799
Jason Barone9d376f2009-02-05 11:51:38 -0500800 mutex_lock(&ddebug_lock);
801
802 if (!n)
803 return SEQ_START_TOKEN;
804 if (n < 0)
805 return NULL;
806 dp = ddebug_iter_first(iter);
807 while (dp != NULL && --n > 0)
808 dp = ddebug_iter_next(iter);
809 return dp;
810}
811
812/*
813 * Seq_ops next method. Called several times within a read()
814 * call from userspace, with ddebug_lock held. Walks to the
815 * next _ddebug object with a special case for the header line.
816 */
817static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
818{
819 struct ddebug_iter *iter = m->private;
820 struct _ddebug *dp;
821
Jason Barone9d376f2009-02-05 11:51:38 -0500822 if (p == SEQ_START_TOKEN)
823 dp = ddebug_iter_first(iter);
824 else
825 dp = ddebug_iter_next(iter);
826 ++*pos;
827 return dp;
828}
829
830/*
831 * Seq_ops show method. Called several times within a read()
832 * call from userspace, with ddebug_lock held. Formats the
833 * current _ddebug as a single human-readable line, with a
834 * special case for the header line.
835 */
836static int ddebug_proc_show(struct seq_file *m, void *p)
837{
838 struct ddebug_iter *iter = m->private;
839 struct _ddebug *dp = p;
Jim Cromief678ce82020-07-19 17:10:47 -0600840 struct flagsbuf flags;
Jason Barone9d376f2009-02-05 11:51:38 -0500841
Jason Barone9d376f2009-02-05 11:51:38 -0500842 if (p == SEQ_START_TOKEN) {
843 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500844 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500845 return 0;
846 }
847
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500848 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500849 trim_prefix(dp->filename), dp->lineno,
850 iter->table->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600851 ddebug_describe_flags(dp->flags, &flags));
Jason Barone9d376f2009-02-05 11:51:38 -0500852 seq_escape(m, dp->format, "\t\r\n\"");
853 seq_puts(m, "\"\n");
854
855 return 0;
856}
857
858/*
859 * Seq_ops stop method. Called at the end of each read()
860 * call from userspace. Drops ddebug_lock.
861 */
862static void ddebug_proc_stop(struct seq_file *m, void *p)
863{
Jason Barone9d376f2009-02-05 11:51:38 -0500864 mutex_unlock(&ddebug_lock);
865}
866
867static const struct seq_operations ddebug_proc_seqops = {
868 .start = ddebug_proc_start,
869 .next = ddebug_proc_next,
870 .show = ddebug_proc_show,
871 .stop = ddebug_proc_stop
872};
873
Jason Barone9d376f2009-02-05 11:51:38 -0500874static int ddebug_proc_open(struct inode *inode, struct file *file)
875{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600876 vpr_info("called\n");
Rob Jones4bad78c2014-10-13 15:51:32 -0700877 return seq_open_private(file, &ddebug_proc_seqops,
878 sizeof(struct ddebug_iter));
Jason Barone9d376f2009-02-05 11:51:38 -0500879}
880
881static const struct file_operations ddebug_proc_fops = {
882 .owner = THIS_MODULE,
883 .open = ddebug_proc_open,
884 .read = seq_read,
885 .llseek = seq_lseek,
886 .release = seq_release_private,
887 .write = ddebug_proc_write
888};
889
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800890static const struct proc_ops proc_fops = {
891 .proc_open = ddebug_proc_open,
892 .proc_read = seq_read,
893 .proc_lseek = seq_lseek,
894 .proc_release = seq_release_private,
895 .proc_write = ddebug_proc_write
896};
897
Jason Barone9d376f2009-02-05 11:51:38 -0500898/*
899 * Allocate a new ddebug_table for the given module
900 * and add it to the global list.
901 */
902int ddebug_add_module(struct _ddebug *tab, unsigned int n,
903 const char *name)
904{
905 struct ddebug_table *dt;
Jason Barone9d376f2009-02-05 11:51:38 -0500906
907 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800908 if (dt == NULL) {
909 pr_err("error adding module: %s\n", name);
Jason Barone9d376f2009-02-05 11:51:38 -0500910 return -ENOMEM;
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800911 }
Rasmus Villemoescdf6d002019-03-07 16:27:37 -0800912 /*
913 * For built-in modules, name lives in .rodata and is
914 * immortal. For loaded modules, name points at the name[]
915 * member of struct module, which lives at least as long as
916 * this struct ddebug_table.
917 */
918 dt->mod_name = name;
Jason Barone9d376f2009-02-05 11:51:38 -0500919 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500920 dt->ddebugs = tab;
921
922 mutex_lock(&ddebug_lock);
Jim Cromie47e9f5a2020-07-19 17:10:50 -0600923 list_add(&dt->link, &ddebug_tables);
Jason Barone9d376f2009-02-05 11:51:38 -0500924 mutex_unlock(&ddebug_lock);
925
Jim Cromie481c0e32020-07-19 17:10:44 -0600926 v2pr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500927 return 0;
928}
Jason Barone9d376f2009-02-05 11:51:38 -0500929
Jim Cromie6ab676e2012-04-27 14:30:37 -0600930/* helper for ddebug_dyndbg_(boot|module)_param_cb */
931static int ddebug_dyndbg_param_cb(char *param, char *val,
932 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600933{
Jim Cromieb48420c2012-04-27 14:30:35 -0600934 char *sep;
935
936 sep = strchr(param, '.');
937 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600938 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600939 *sep = '\0';
940 modname = param;
941 param = sep + 1;
942 }
943 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600944 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600945
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600946 ddebug_exec_queries((val ? val : "+p"), modname);
947
Jim Cromieb48420c2012-04-27 14:30:35 -0600948 return 0; /* query failure shouldnt stop module load */
949}
950
Jim Cromie6ab676e2012-04-27 14:30:37 -0600951/* handle both dyndbg and $module.dyndbg params at boot */
952static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -0700953 const char *unused, void *arg)
Jim Cromieb48420c2012-04-27 14:30:35 -0600954{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600955 vpr_info("%s=\"%s\"\n", param, val);
956 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
957}
Jim Cromieb48420c2012-04-27 14:30:35 -0600958
Jim Cromie6ab676e2012-04-27 14:30:37 -0600959/*
960 * modprobe foo finds foo.params in boot-args, strips "foo.", and
961 * passes them to load_module(). This callback gets unknown params,
962 * processes dyndbg params, rejects others.
963 */
964int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
965{
966 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
967 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600968}
969
Jason Barone9d376f2009-02-05 11:51:38 -0500970static void ddebug_table_free(struct ddebug_table *dt)
971{
972 list_del_init(&dt->link);
Jason Barone9d376f2009-02-05 11:51:38 -0500973 kfree(dt);
974}
975
976/*
977 * Called in response to a module being unloaded. Removes
978 * any ddebug_table's which point at the module.
979 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000980int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500981{
982 struct ddebug_table *dt, *nextdt;
983 int ret = -ENOENT;
984
Jim Cromie481c0e32020-07-19 17:10:44 -0600985 v2pr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500986
987 mutex_lock(&ddebug_lock);
988 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800989 if (dt->mod_name == mod_name) {
Jason Barone9d376f2009-02-05 11:51:38 -0500990 ddebug_table_free(dt);
991 ret = 0;
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800992 break;
Jason Barone9d376f2009-02-05 11:51:38 -0500993 }
994 }
995 mutex_unlock(&ddebug_lock);
996 return ret;
997}
Jason Barone9d376f2009-02-05 11:51:38 -0500998
999static void ddebug_remove_all_tables(void)
1000{
1001 mutex_lock(&ddebug_lock);
1002 while (!list_empty(&ddebug_tables)) {
1003 struct ddebug_table *dt = list_entry(ddebug_tables.next,
1004 struct ddebug_table,
1005 link);
1006 ddebug_table_free(dt);
1007 }
1008 mutex_unlock(&ddebug_lock);
1009}
1010
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001011static __initdata int ddebug_init_success;
1012
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001013static int __init dynamic_debug_init_control(void)
Jason Barone9d376f2009-02-05 11:51:38 -05001014{
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001015 struct proc_dir_entry *procfs_dir;
1016 struct dentry *debugfs_dir;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001017
1018 if (!ddebug_init_success)
1019 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -05001020
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001021 /* Create the control file in debugfs if it is enabled */
1022 if (debugfs_initialized()) {
1023 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
1024 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1025 &ddebug_proc_fops);
1026 }
1027
1028 /* Also create the control file in procfs */
1029 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1030 if (procfs_dir)
1031 proc_create("control", 0644, procfs_dir, &proc_fops);
Greg Kroah-Hartman9fd714c2019-06-12 17:35:34 +02001032
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001033 return 0;
1034}
1035
1036static int __init dynamic_debug_init(void)
1037{
1038 struct _ddebug *iter, *iter_start;
1039 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001040 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001041 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001042 int n = 0, entries = 0, modct = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001043
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001044 if (&__start___dyndbg == &__stop___dyndbg) {
Orson Zhaiceabef72020-06-07 21:40:14 -07001045 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1046 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1047 return 1;
1048 }
1049 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1050 ddebug_init_success = 1;
1051 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -05001052 }
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001053 iter = __start___dyndbg;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001054 modname = iter->modname;
1055 iter_start = iter;
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001056 for (; iter < __stop___dyndbg; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001057 entries++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001058 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001059 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001060 ret = ddebug_add_module(iter_start, n, modname);
1061 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001062 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001063 n = 0;
1064 modname = iter->modname;
1065 iter_start = iter;
1066 }
1067 n++;
1068 }
1069 ret = ddebug_add_module(iter_start, n, modname);
1070 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001071 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001072
Jim Cromieaf442392012-04-27 14:30:38 -06001073 ddebug_init_success = 1;
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001074 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 -05001075 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001076 (int)(entries * sizeof(struct _ddebug)));
Jim Cromieaf442392012-04-27 14:30:38 -06001077
1078 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001079 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001080 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001081 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001082 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001083 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001084 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001085 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001086 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001087 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001088 /* now that ddebug tables are loaded, process all boot args
1089 * again to find and activate queries given in dyndbg params.
1090 * While this has already been done for known boot params, it
1091 * ignored the unknown ones (dyndbg in particular). Reusing
1092 * parse_args avoids ad-hoc parsing. This will also attempt
1093 * to activate queries for not-yet-loaded modules, which is
1094 * slightly noisy if verbose, but harmless.
1095 */
1096 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1097 parse_args("dyndbg params", cmdline, NULL,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -07001098 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
Jim Cromieb48420c2012-04-27 14:30:35 -06001099 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001100 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001101
Jim Cromieaf442392012-04-27 14:30:38 -06001102out_err:
1103 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001104 return 0;
1105}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001106/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001107early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001108
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001109/* Debugfs setup must be done later */
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001110fs_initcall(dynamic_debug_init_control);