blob: c97872cffc8e125a63cc4c5f2363b4806d5f7bef [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
Jason Barone9d376f2009-02-05 11:51:38 -050042extern struct _ddebug __start___verbose[];
43extern struct _ddebug __stop___verbose[];
44
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
Jason Barone9d376f2009-02-05 11:51:38 -050090/* format a string into buf[] which describes the _ddebug's flags */
91static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
92 size_t maxlen)
93{
94 char *p = buf;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010095 int i;
Jason Barone9d376f2009-02-05 11:51:38 -050096
Jim Cromie5ca7d2a2011-12-19 17:12:44 -050097 BUG_ON(maxlen < 6);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +010098 for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
99 if (dp->flags & opt_array[i].flag)
100 *p++ = opt_array[i].opt_char;
Jason Barone9d376f2009-02-05 11:51:38 -0500101 if (p == buf)
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500102 *p++ = '_';
Jason Barone9d376f2009-02-05 11:51:38 -0500103 *p = '\0';
104
105 return buf;
106}
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,
130 query->function ? query->function : "",
131 query->filename ? query->filename : "",
132 query->module ? query->module : "",
133 fmtlen, query->format ? query->format : "",
134 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 Cromie5ca7d2a2011-12-19 17:12:44 -0500150 char flagbuf[10];
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,
207 ddebug_describe_flags(dp, flagbuf,
208 sizeof(flagbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500209 }
210 }
211 mutex_unlock(&ddebug_lock);
212
213 if (!nfound && verbose)
Joe Perches4ad275e2011-08-11 14:36:33 -0400214 pr_info("no matches for query\n");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500215
216 return nfound;
Jason Barone9d376f2009-02-05 11:51:38 -0500217}
218
219/*
Jason Barone9d376f2009-02-05 11:51:38 -0500220 * Split the buffer `buf' into space-separated words.
Greg Banks9898abb2009-02-06 12:54:26 +1100221 * Handles simple " and ' quoting, i.e. without nested,
222 * embedded or escaped \". Return the number of words
223 * or <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500224 */
225static int ddebug_tokenize(char *buf, char *words[], int maxwords)
226{
227 int nwords = 0;
228
Greg Banks9898abb2009-02-06 12:54:26 +1100229 while (*buf) {
230 char *end;
231
232 /* Skip leading whitespace */
André Goddard Rosae7d28602009-12-14 18:01:06 -0800233 buf = skip_spaces(buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100234 if (!*buf)
235 break; /* oh, it was trailing whitespace */
Jim Cromie8bd60262011-12-19 17:13:03 -0500236 if (*buf == '#')
237 break; /* token starts comment, skip rest of line */
Greg Banks9898abb2009-02-06 12:54:26 +1100238
Jim Cromie07100be2011-12-19 17:11:09 -0500239 /* find `end' of word, whitespace separated or quoted */
Greg Banks9898abb2009-02-06 12:54:26 +1100240 if (*buf == '"' || *buf == '\'') {
241 int quote = *buf++;
Joe Perchesf657fd22012-12-05 16:48:26 -0500242 for (end = buf; *end && *end != quote; end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100243 ;
Jim Cromie18c216c2012-12-05 16:48:27 -0500244 if (!*end) {
245 pr_err("unclosed quote: %s\n", buf);
Greg Banks9898abb2009-02-06 12:54:26 +1100246 return -EINVAL; /* unclosed quote */
Jim Cromie18c216c2012-12-05 16:48:27 -0500247 }
Greg Banks9898abb2009-02-06 12:54:26 +1100248 } else {
Joe Perchesf657fd22012-12-05 16:48:26 -0500249 for (end = buf; *end && !isspace(*end); end++)
Greg Banks9898abb2009-02-06 12:54:26 +1100250 ;
251 BUG_ON(end == buf);
252 }
Greg Banks9898abb2009-02-06 12:54:26 +1100253
Jim Cromie07100be2011-12-19 17:11:09 -0500254 /* `buf' is start of word, `end' is one past its end */
Jim Cromie18c216c2012-12-05 16:48:27 -0500255 if (nwords == maxwords) {
256 pr_err("too many words, legal max <=%d\n", maxwords);
Greg Banks9898abb2009-02-06 12:54:26 +1100257 return -EINVAL; /* ran out of words[] before bytes */
Jim Cromie18c216c2012-12-05 16:48:27 -0500258 }
Greg Banks9898abb2009-02-06 12:54:26 +1100259 if (*end)
260 *end++ = '\0'; /* terminate the word */
261 words[nwords++] = buf;
262 buf = end;
263 }
Jason Barone9d376f2009-02-05 11:51:38 -0500264
265 if (verbose) {
266 int i;
Joe Perches4ad275e2011-08-11 14:36:33 -0400267 pr_info("split into words:");
Joe Perchesf657fd22012-12-05 16:48:26 -0500268 for (i = 0; i < nwords; i++)
Joe Perches4ad275e2011-08-11 14:36:33 -0400269 pr_cont(" \"%s\"", words[i]);
270 pr_cont("\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500271 }
272
273 return nwords;
274}
275
276/*
277 * Parse a single line number. Note that the empty string ""
278 * is treated as a special case and converted to zero, which
279 * is later treated as a "don't care" value.
280 */
281static inline int parse_lineno(const char *str, unsigned int *val)
282{
Jason Barone9d376f2009-02-05 11:51:38 -0500283 BUG_ON(str == NULL);
284 if (*str == '\0') {
285 *val = 0;
286 return 0;
287 }
Andrey Ryabinin45925992014-01-27 17:06:59 -0800288 if (kstrtouint(str, 10, val) < 0) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500289 pr_err("bad line-number: %s\n", str);
290 return -EINVAL;
291 }
292 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500293}
294
Jim Cromie820874c2011-12-19 17:12:49 -0500295static int check_set(const char **dest, char *src, char *name)
296{
297 int rc = 0;
298
299 if (*dest) {
300 rc = -EINVAL;
Joe Perchesf657fd22012-12-05 16:48:26 -0500301 pr_err("match-spec:%s val:%s overridden by %s\n",
302 name, *dest, src);
Jim Cromie820874c2011-12-19 17:12:49 -0500303 }
304 *dest = src;
305 return rc;
306}
307
Jason Barone9d376f2009-02-05 11:51:38 -0500308/*
309 * Parse words[] as a ddebug query specification, which is a series
310 * of (keyword, value) pairs chosen from these possibilities:
311 *
312 * func <function-name>
313 * file <full-pathname>
314 * file <base-filename>
315 * module <module-name>
316 * format <escaped-string-to-find-in-format>
317 * line <lineno>
318 * line <first-lineno>-<last-lineno> // where either may be empty
Jim Cromie820874c2011-12-19 17:12:49 -0500319 *
320 * Only 1 of each type is allowed.
321 * Returns 0 on success, <0 on error.
Jason Barone9d376f2009-02-05 11:51:38 -0500322 */
323static int ddebug_parse_query(char *words[], int nwords,
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600324 struct ddebug_query *query, const char *modname)
Jason Barone9d376f2009-02-05 11:51:38 -0500325{
326 unsigned int i;
jbaron@akamai.combd8c154a2013-08-27 16:50:03 +0000327 int rc = 0;
Jason Barone9d376f2009-02-05 11:51:38 -0500328
329 /* check we have an even number of words */
Jim Cromie18c216c2012-12-05 16:48:27 -0500330 if (nwords % 2 != 0) {
331 pr_err("expecting pairs of match-spec <value>\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500332 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500333 }
Jason Barone9d376f2009-02-05 11:51:38 -0500334 memset(query, 0, sizeof(*query));
335
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600336 if (modname)
337 /* support $modname.dyndbg=<multiple queries> */
338 query->module = modname;
339
Joe Perchesf657fd22012-12-05 16:48:26 -0500340 for (i = 0; i < nwords; i += 2) {
341 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500342 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500343 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500344 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500345 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500346 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500347 } else if (!strcmp(words[i], "format")) {
Andy Shevchenkod338b132013-04-30 15:27:32 -0700348 string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
349 UNESCAPE_OCTAL |
350 UNESCAPE_SPECIAL);
351 rc = check_set(&query->format, words[i+1], "format");
Joe Perchesf657fd22012-12-05 16:48:26 -0500352 } else if (!strcmp(words[i], "line")) {
Jason Barone9d376f2009-02-05 11:51:38 -0500353 char *first = words[i+1];
354 char *last = strchr(first, '-');
Jim Cromie820874c2011-12-19 17:12:49 -0500355 if (query->first_lineno || query->last_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500356 pr_err("match-spec: line used 2x\n");
Jim Cromie820874c2011-12-19 17:12:49 -0500357 return -EINVAL;
358 }
Jason Barone9d376f2009-02-05 11:51:38 -0500359 if (last)
360 *last++ = '\0';
Andrey Ryabinind9e133e2014-01-27 17:06:57 -0800361 if (parse_lineno(first, &query->first_lineno) < 0)
Jason Barone9d376f2009-02-05 11:51:38 -0500362 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500363 if (last) {
Jason Barone9d376f2009-02-05 11:51:38 -0500364 /* range <first>-<last> */
Andrey Ryabinin3ace6782014-01-27 17:06:58 -0800365 if (parse_lineno(last, &query->last_lineno) < 0)
366 return -EINVAL;
367
Randy Dunlap1f3c7902017-11-17 15:27:35 -0800368 /* special case for last lineno not specified */
369 if (query->last_lineno == 0)
370 query->last_lineno = UINT_MAX;
371
Andrey Ryabinin3ace6782014-01-27 17:06:58 -0800372 if (query->last_lineno < query->first_lineno) {
Jim Cromie18c216c2012-12-05 16:48:27 -0500373 pr_err("last-line:%d < 1st-line:%d\n",
374 query->last_lineno,
375 query->first_lineno);
Jason Barone9d376f2009-02-05 11:51:38 -0500376 return -EINVAL;
Jim Cromie820874c2011-12-19 17:12:49 -0500377 }
Jason Barone9d376f2009-02-05 11:51:38 -0500378 } else {
379 query->last_lineno = query->first_lineno;
380 }
381 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500382 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500383 return -EINVAL;
384 }
Jim Cromie820874c2011-12-19 17:12:49 -0500385 if (rc)
386 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500387 }
Jim Cromie574b3722011-12-19 17:13:16 -0500388 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500389 return 0;
390}
391
392/*
393 * Parse `str' as a flags specification, format [-+=][p]+.
394 * Sets up *maskp and *flagsp to be used when changing the
395 * flags fields of matched _ddebug's. Returns 0 on success
396 * or <0 on error.
397 */
398static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
399 unsigned int *maskp)
400{
401 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100402 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500403
404 switch (*str) {
405 case '+':
406 case '-':
407 case '=':
408 op = *str++;
409 break;
410 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500411 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500412 return -EINVAL;
413 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600414 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500415
Joe Perchesf657fd22012-12-05 16:48:26 -0500416 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100417 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
418 if (*str == opt_array[i].opt_char) {
419 flags |= opt_array[i].flag;
420 break;
421 }
Jason Barone9d376f2009-02-05 11:51:38 -0500422 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500423 if (i < 0) {
424 pr_err("unknown flag '%c' in \"%s\"\n", *str, str);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100425 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500426 }
Jason Barone9d376f2009-02-05 11:51:38 -0500427 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600428 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500429
430 /* calculate final *flagsp, *maskp according to mask and op */
431 switch (op) {
432 case '=':
433 *maskp = 0;
434 *flagsp = flags;
435 break;
436 case '+':
437 *maskp = ~0U;
438 *flagsp = flags;
439 break;
440 case '-':
441 *maskp = ~flags;
442 *flagsp = 0;
443 break;
444 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600445 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500446 return 0;
447}
448
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600449static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200450{
451 unsigned int flags = 0, mask = 0;
452 struct ddebug_query query;
453#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500454 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200455 char *words[MAXWORDS];
456
457 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500458 if (nwords <= 0) {
459 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200460 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500461 }
462 /* check flags 1st (last arg) so query is pairs of spec,val */
463 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
464 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200465 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500466 }
467 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
468 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200469 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500470 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200471 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500472 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500473 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500474
475 return nfound;
476}
477
478/* handle multiple queries in query string, continue on error, return
479 last error or number of matching callsites. Module name is either
480 in param (for boot arg) or perhaps in query string.
481*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600482static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500483{
484 char *split;
485 int i, errs = 0, exitcode = 0, rc, nfound = 0;
486
487 for (i = 0; query; query = split) {
488 split = strpbrk(query, ";\n");
489 if (split)
490 *split++ = '\0';
491
492 query = skip_spaces(query);
493 if (!query || !*query || *query == '#')
494 continue;
495
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600496 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500497
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600498 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500499 if (rc < 0) {
500 errs++;
501 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500502 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500503 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500504 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500505 i++;
506 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600507 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500508 i, nfound, errs);
509
510 if (exitcode)
511 return exitcode;
512 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200513}
514
Jason Baron431625d2011-10-04 14:13:19 -0700515#define PREFIX_SIZE 64
516
517static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100518{
Jason Baron431625d2011-10-04 14:13:19 -0700519 if (PREFIX_SIZE - wrote > 0)
520 return PREFIX_SIZE - wrote;
521 return 0;
522}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100523
Jason Baron431625d2011-10-04 14:13:19 -0700524static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
525{
526 int pos_after_tid;
527 int pos = 0;
528
Joe Perches798efc62012-09-12 20:11:29 -0700529 *buf = '\0';
530
Jason Baron431625d2011-10-04 14:13:19 -0700531 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100532 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700533 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100534 else
Jason Baron431625d2011-10-04 14:13:19 -0700535 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700536 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100537 }
Jason Baron431625d2011-10-04 14:13:19 -0700538 pos_after_tid = pos;
539 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
540 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700541 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700542 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
543 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700544 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700545 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500546 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700547 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700548 if (pos - pos_after_tid)
549 pos += snprintf(buf + pos, remaining(pos), " ");
550 if (pos >= PREFIX_SIZE)
551 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400552
Jason Baron431625d2011-10-04 14:13:19 -0700553 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400554}
555
Joe Perches906d2012014-09-24 11:17:56 -0700556void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100557{
558 va_list args;
Jason Baron431625d2011-10-04 14:13:19 -0700559 struct va_format vaf;
560 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100561
562 BUG_ON(!descriptor);
563 BUG_ON(!fmt);
564
565 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700566
Jason Baron431625d2011-10-04 14:13:19 -0700567 vaf.fmt = fmt;
568 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700569
Joe Perches906d2012014-09-24 11:17:56 -0700570 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700571
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100572 va_end(args);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100573}
574EXPORT_SYMBOL(__dynamic_pr_debug);
575
Joe Perches906d2012014-09-24 11:17:56 -0700576void __dynamic_dev_dbg(struct _ddebug *descriptor,
Joe Perchescbc46632011-08-11 14:36:21 -0400577 const struct device *dev, const char *fmt, ...)
578{
579 struct va_format vaf;
580 va_list args;
Joe Perchescbc46632011-08-11 14:36:21 -0400581
582 BUG_ON(!descriptor);
583 BUG_ON(!fmt);
584
585 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700586
Joe Perchescbc46632011-08-11 14:36:21 -0400587 vaf.fmt = fmt;
588 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700589
590 if (!dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700591 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700592 } else {
593 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700594
Joe Perchesa39d4a82014-12-10 15:50:15 -0800595 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
Joe Perches906d2012014-09-24 11:17:56 -0700596 dynamic_emit_prefix(descriptor, buf),
597 dev_driver_string(dev), dev_name(dev),
598 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700599 }
600
Joe Perchescbc46632011-08-11 14:36:21 -0400601 va_end(args);
Joe Perchescbc46632011-08-11 14:36:21 -0400602}
603EXPORT_SYMBOL(__dynamic_dev_dbg);
604
Jason Baron0feefd92011-10-04 14:13:22 -0700605#ifdef CONFIG_NET
606
Joe Perches906d2012014-09-24 11:17:56 -0700607void __dynamic_netdev_dbg(struct _ddebug *descriptor,
608 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400609{
610 struct va_format vaf;
611 va_list args;
Jason Baronffa10cb2011-08-11 14:36:48 -0400612
613 BUG_ON(!descriptor);
614 BUG_ON(!fmt);
615
616 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700617
Jason Baronffa10cb2011-08-11 14:36:48 -0400618 vaf.fmt = fmt;
619 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700620
621 if (dev && dev->dev.parent) {
622 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700623
Joe Perchesa39d4a82014-12-10 15:50:15 -0800624 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
Joe Perches906d2012014-09-24 11:17:56 -0700625 "%s%s %s %s%s: %pV",
626 dynamic_emit_prefix(descriptor, buf),
627 dev_driver_string(dev->dev.parent),
628 dev_name(dev->dev.parent),
629 netdev_name(dev), netdev_reg_state(dev),
630 &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700631 } else if (dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700632 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
633 netdev_reg_state(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700634 } else {
Joe Perches906d2012014-09-24 11:17:56 -0700635 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700636 }
637
Jason Baronffa10cb2011-08-11 14:36:48 -0400638 va_end(args);
Jason Baronffa10cb2011-08-11 14:36:48 -0400639}
640EXPORT_SYMBOL(__dynamic_netdev_dbg);
641
Jason Baron0feefd92011-10-04 14:13:22 -0700642#endif
643
Gal Pressman923abb92019-05-01 13:48:13 +0300644#if IS_ENABLED(CONFIG_INFINIBAND)
645
646void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
647 const struct ib_device *ibdev, const char *fmt, ...)
648{
649 struct va_format vaf;
650 va_list args;
651
652 va_start(args, fmt);
653
654 vaf.fmt = fmt;
655 vaf.va = &args;
656
657 if (ibdev && ibdev->dev.parent) {
658 char buf[PREFIX_SIZE];
659
660 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
661 "%s%s %s %s: %pV",
662 dynamic_emit_prefix(descriptor, buf),
663 dev_driver_string(ibdev->dev.parent),
664 dev_name(ibdev->dev.parent),
665 dev_name(&ibdev->dev),
666 &vaf);
667 } else if (ibdev) {
668 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
669 } else {
670 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
671 }
672
673 va_end(args);
674}
675EXPORT_SYMBOL(__dynamic_ibdev_dbg);
676
677#endif
678
Jim Cromiebc757f62011-12-19 17:12:29 -0500679#define DDEBUG_STRING_SIZE 1024
680static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
681
Thomas Renningera648ec02010-08-06 16:11:02 +0200682static __init int ddebug_setup_query(char *str)
683{
Jim Cromiebc757f62011-12-19 17:12:29 -0500684 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400685 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200686 return 0;
687 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500688 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200689 return 1;
690}
691
692__setup("ddebug_query=", ddebug_setup_query);
693
Jason Barone9d376f2009-02-05 11:51:38 -0500694/*
Masatake YAMATO231821d2014-12-15 12:04:16 +0900695 * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
Jason Barone9d376f2009-02-05 11:51:38 -0500696 * command text from userspace, parses and executes it.
697 */
Jim Cromie72814912011-12-19 17:13:07 -0500698#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500699static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
700 size_t len, loff_t *offp)
701{
Jim Cromie72814912011-12-19 17:13:07 -0500702 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200703 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500704
705 if (len == 0)
706 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500707 if (len > USER_BUF_PAGE - 1) {
708 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500709 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500710 }
Al Viro16e5c1f2015-12-24 00:06:05 -0500711 tmpbuf = memdup_user_nul(ubuf, len);
712 if (IS_ERR(tmpbuf))
713 return PTR_ERR(tmpbuf);
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600714 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500715
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600716 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500717 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500718 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200719 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500720
721 *offp += len;
722 return len;
723}
724
725/*
726 * Set the iterator to point to the first _ddebug object
727 * and return a pointer to that first object. Returns
728 * NULL if there are no _ddebugs at all.
729 */
730static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
731{
732 if (list_empty(&ddebug_tables)) {
733 iter->table = NULL;
734 iter->idx = 0;
735 return NULL;
736 }
737 iter->table = list_entry(ddebug_tables.next,
738 struct ddebug_table, link);
739 iter->idx = 0;
740 return &iter->table->ddebugs[iter->idx];
741}
742
743/*
744 * Advance the iterator to point to the next _ddebug
745 * object from the one the iterator currently points at,
746 * and returns a pointer to the new _ddebug. Returns
747 * NULL if the iterator has seen all the _ddebugs.
748 */
749static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
750{
751 if (iter->table == NULL)
752 return NULL;
753 if (++iter->idx == iter->table->num_ddebugs) {
754 /* iterate to next table */
755 iter->idx = 0;
756 if (list_is_last(&iter->table->link, &ddebug_tables)) {
757 iter->table = NULL;
758 return NULL;
759 }
760 iter->table = list_entry(iter->table->link.next,
761 struct ddebug_table, link);
762 }
763 return &iter->table->ddebugs[iter->idx];
764}
765
766/*
767 * Seq_ops start method. Called at the start of every
768 * read() call from userspace. Takes the ddebug_lock and
769 * seeks the seq_file's iterator to the given position.
770 */
771static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
772{
773 struct ddebug_iter *iter = m->private;
774 struct _ddebug *dp;
775 int n = *pos;
776
Jason Barone9d376f2009-02-05 11:51:38 -0500777 mutex_lock(&ddebug_lock);
778
779 if (!n)
780 return SEQ_START_TOKEN;
781 if (n < 0)
782 return NULL;
783 dp = ddebug_iter_first(iter);
784 while (dp != NULL && --n > 0)
785 dp = ddebug_iter_next(iter);
786 return dp;
787}
788
789/*
790 * Seq_ops next method. Called several times within a read()
791 * call from userspace, with ddebug_lock held. Walks to the
792 * next _ddebug object with a special case for the header line.
793 */
794static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
795{
796 struct ddebug_iter *iter = m->private;
797 struct _ddebug *dp;
798
Jason Barone9d376f2009-02-05 11:51:38 -0500799 if (p == SEQ_START_TOKEN)
800 dp = ddebug_iter_first(iter);
801 else
802 dp = ddebug_iter_next(iter);
803 ++*pos;
804 return dp;
805}
806
807/*
808 * Seq_ops show method. Called several times within a read()
809 * call from userspace, with ddebug_lock held. Formats the
810 * current _ddebug as a single human-readable line, with a
811 * special case for the header line.
812 */
813static int ddebug_proc_show(struct seq_file *m, void *p)
814{
815 struct ddebug_iter *iter = m->private;
816 struct _ddebug *dp = p;
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500817 char flagsbuf[10];
Jason Barone9d376f2009-02-05 11:51:38 -0500818
Jason Barone9d376f2009-02-05 11:51:38 -0500819 if (p == SEQ_START_TOKEN) {
820 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500821 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500822 return 0;
823 }
824
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500825 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500826 trim_prefix(dp->filename), dp->lineno,
827 iter->table->mod_name, dp->function,
828 ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
Jason Barone9d376f2009-02-05 11:51:38 -0500829 seq_escape(m, dp->format, "\t\r\n\"");
830 seq_puts(m, "\"\n");
831
832 return 0;
833}
834
835/*
836 * Seq_ops stop method. Called at the end of each read()
837 * call from userspace. Drops ddebug_lock.
838 */
839static void ddebug_proc_stop(struct seq_file *m, void *p)
840{
Jason Barone9d376f2009-02-05 11:51:38 -0500841 mutex_unlock(&ddebug_lock);
842}
843
844static const struct seq_operations ddebug_proc_seqops = {
845 .start = ddebug_proc_start,
846 .next = ddebug_proc_next,
847 .show = ddebug_proc_show,
848 .stop = ddebug_proc_stop
849};
850
Jason Barone9d376f2009-02-05 11:51:38 -0500851static int ddebug_proc_open(struct inode *inode, struct file *file)
852{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600853 vpr_info("called\n");
Rob Jones4bad78c2014-10-13 15:51:32 -0700854 return seq_open_private(file, &ddebug_proc_seqops,
855 sizeof(struct ddebug_iter));
Jason Barone9d376f2009-02-05 11:51:38 -0500856}
857
858static const struct file_operations ddebug_proc_fops = {
859 .owner = THIS_MODULE,
860 .open = ddebug_proc_open,
861 .read = seq_read,
862 .llseek = seq_lseek,
863 .release = seq_release_private,
864 .write = ddebug_proc_write
865};
866
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800867static const struct proc_ops proc_fops = {
868 .proc_open = ddebug_proc_open,
869 .proc_read = seq_read,
870 .proc_lseek = seq_lseek,
871 .proc_release = seq_release_private,
872 .proc_write = ddebug_proc_write
873};
874
Jason Barone9d376f2009-02-05 11:51:38 -0500875/*
876 * Allocate a new ddebug_table for the given module
877 * and add it to the global list.
878 */
879int ddebug_add_module(struct _ddebug *tab, unsigned int n,
880 const char *name)
881{
882 struct ddebug_table *dt;
Jason Barone9d376f2009-02-05 11:51:38 -0500883
884 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800885 if (dt == NULL) {
886 pr_err("error adding module: %s\n", name);
Jason Barone9d376f2009-02-05 11:51:38 -0500887 return -ENOMEM;
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800888 }
Rasmus Villemoescdf6d002019-03-07 16:27:37 -0800889 /*
890 * For built-in modules, name lives in .rodata and is
891 * immortal. For loaded modules, name points at the name[]
892 * member of struct module, which lives at least as long as
893 * this struct ddebug_table.
894 */
895 dt->mod_name = name;
Jason Barone9d376f2009-02-05 11:51:38 -0500896 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500897 dt->ddebugs = tab;
898
899 mutex_lock(&ddebug_lock);
900 list_add_tail(&dt->link, &ddebug_tables);
901 mutex_unlock(&ddebug_lock);
902
Jim Cromie481c0e32020-07-19 17:10:44 -0600903 v2pr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500904 return 0;
905}
Jason Barone9d376f2009-02-05 11:51:38 -0500906
Jim Cromie6ab676e2012-04-27 14:30:37 -0600907/* helper for ddebug_dyndbg_(boot|module)_param_cb */
908static int ddebug_dyndbg_param_cb(char *param, char *val,
909 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600910{
Jim Cromieb48420c2012-04-27 14:30:35 -0600911 char *sep;
912
913 sep = strchr(param, '.');
914 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600915 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600916 *sep = '\0';
917 modname = param;
918 param = sep + 1;
919 }
920 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600921 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600922
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600923 ddebug_exec_queries((val ? val : "+p"), modname);
924
Jim Cromieb48420c2012-04-27 14:30:35 -0600925 return 0; /* query failure shouldnt stop module load */
926}
927
Jim Cromie6ab676e2012-04-27 14:30:37 -0600928/* handle both dyndbg and $module.dyndbg params at boot */
929static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -0700930 const char *unused, void *arg)
Jim Cromieb48420c2012-04-27 14:30:35 -0600931{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600932 vpr_info("%s=\"%s\"\n", param, val);
933 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
934}
Jim Cromieb48420c2012-04-27 14:30:35 -0600935
Jim Cromie6ab676e2012-04-27 14:30:37 -0600936/*
937 * modprobe foo finds foo.params in boot-args, strips "foo.", and
938 * passes them to load_module(). This callback gets unknown params,
939 * processes dyndbg params, rejects others.
940 */
941int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
942{
943 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
944 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600945}
946
Jason Barone9d376f2009-02-05 11:51:38 -0500947static void ddebug_table_free(struct ddebug_table *dt)
948{
949 list_del_init(&dt->link);
Jason Barone9d376f2009-02-05 11:51:38 -0500950 kfree(dt);
951}
952
953/*
954 * Called in response to a module being unloaded. Removes
955 * any ddebug_table's which point at the module.
956 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000957int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500958{
959 struct ddebug_table *dt, *nextdt;
960 int ret = -ENOENT;
961
Jim Cromie481c0e32020-07-19 17:10:44 -0600962 v2pr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500963
964 mutex_lock(&ddebug_lock);
965 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800966 if (dt->mod_name == mod_name) {
Jason Barone9d376f2009-02-05 11:51:38 -0500967 ddebug_table_free(dt);
968 ret = 0;
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800969 break;
Jason Barone9d376f2009-02-05 11:51:38 -0500970 }
971 }
972 mutex_unlock(&ddebug_lock);
973 return ret;
974}
Jason Barone9d376f2009-02-05 11:51:38 -0500975
976static void ddebug_remove_all_tables(void)
977{
978 mutex_lock(&ddebug_lock);
979 while (!list_empty(&ddebug_tables)) {
980 struct ddebug_table *dt = list_entry(ddebug_tables.next,
981 struct ddebug_table,
982 link);
983 ddebug_table_free(dt);
984 }
985 mutex_unlock(&ddebug_lock);
986}
987
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200988static __initdata int ddebug_init_success;
989
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800990static int __init dynamic_debug_init_control(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500991{
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800992 struct proc_dir_entry *procfs_dir;
993 struct dentry *debugfs_dir;
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200994
995 if (!ddebug_init_success)
996 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -0500997
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800998 /* Create the control file in debugfs if it is enabled */
999 if (debugfs_initialized()) {
1000 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
1001 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1002 &ddebug_proc_fops);
1003 }
1004
1005 /* Also create the control file in procfs */
1006 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1007 if (procfs_dir)
1008 proc_create("control", 0644, procfs_dir, &proc_fops);
Greg Kroah-Hartman9fd714c2019-06-12 17:35:34 +02001009
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001010 return 0;
1011}
1012
1013static int __init dynamic_debug_init(void)
1014{
1015 struct _ddebug *iter, *iter_start;
1016 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001017 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001018 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001019 int n = 0, entries = 0, modct = 0;
1020 int verbose_bytes = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001021
Nathan Chancellor8306b052020-04-06 20:10:45 -07001022 if (&__start___verbose == &__stop___verbose) {
Orson Zhaiceabef72020-06-07 21:40:14 -07001023 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1024 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1025 return 1;
1026 }
1027 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1028 ddebug_init_success = 1;
1029 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -05001030 }
Jim Cromieb5b78f82011-12-19 17:12:54 -05001031 iter = __start___verbose;
1032 modname = iter->modname;
1033 iter_start = iter;
1034 for (; iter < __stop___verbose; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001035 entries++;
1036 verbose_bytes += strlen(iter->modname) + strlen(iter->function)
1037 + strlen(iter->filename) + strlen(iter->format);
1038
Jim Cromieb5b78f82011-12-19 17:12:54 -05001039 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001040 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001041 ret = ddebug_add_module(iter_start, n, modname);
1042 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001043 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001044 n = 0;
1045 modname = iter->modname;
1046 iter_start = iter;
1047 }
1048 n++;
1049 }
1050 ret = ddebug_add_module(iter_start, n, modname);
1051 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001052 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001053
Jim Cromieaf442392012-04-27 14:30:38 -06001054 ddebug_init_success = 1;
Joe Perchesf657fd22012-12-05 16:48:26 -05001055 vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n",
1056 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
1057 verbose_bytes + (int)(__stop___verbose - __start___verbose));
Jim Cromieaf442392012-04-27 14:30:38 -06001058
1059 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001060 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001061 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001062 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001063 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001064 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001065 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001066 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001067 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001068 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001069 /* now that ddebug tables are loaded, process all boot args
1070 * again to find and activate queries given in dyndbg params.
1071 * While this has already been done for known boot params, it
1072 * ignored the unknown ones (dyndbg in particular). Reusing
1073 * parse_args avoids ad-hoc parsing. This will also attempt
1074 * to activate queries for not-yet-loaded modules, which is
1075 * slightly noisy if verbose, but harmless.
1076 */
1077 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1078 parse_args("dyndbg params", cmdline, NULL,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -07001079 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
Jim Cromieb48420c2012-04-27 14:30:35 -06001080 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001081 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001082
Jim Cromieaf442392012-04-27 14:30:38 -06001083out_err:
1084 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001085 return 0;
1086}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001087/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001088early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001089
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001090/* Debugfs setup must be done later */
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001091fs_initcall(dynamic_debug_init_control);