blob: 7a66d5e07f41e21e14886749c1ec5681a9dc3cf3 [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;
Jason Barone9d376f2009-02-05 11:51:38 -0500362
363 /* check we have an even number of words */
Jim Cromie18c216c2012-12-05 16:48:27 -0500364 if (nwords % 2 != 0) {
365 pr_err("expecting pairs of match-spec <value>\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500366 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500367 }
Jason Barone9d376f2009-02-05 11:51:38 -0500368
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600369 if (modname)
370 /* support $modname.dyndbg=<multiple queries> */
371 query->module = modname;
372
Joe Perchesf657fd22012-12-05 16:48:26 -0500373 for (i = 0; i < nwords; i += 2) {
374 if (!strcmp(words[i], "func")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500375 rc = check_set(&query->function, words[i+1], "func");
Joe Perchesf657fd22012-12-05 16:48:26 -0500376 } else if (!strcmp(words[i], "file")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500377 rc = check_set(&query->filename, words[i+1], "file");
Joe Perchesf657fd22012-12-05 16:48:26 -0500378 } else if (!strcmp(words[i], "module")) {
Jim Cromie820874c2011-12-19 17:12:49 -0500379 rc = check_set(&query->module, words[i+1], "module");
Joe Perchesf657fd22012-12-05 16:48:26 -0500380 } else if (!strcmp(words[i], "format")) {
Andy Shevchenkod338b132013-04-30 15:27:32 -0700381 string_unescape_inplace(words[i+1], UNESCAPE_SPACE |
382 UNESCAPE_OCTAL |
383 UNESCAPE_SPECIAL);
384 rc = check_set(&query->format, words[i+1], "format");
Joe Perchesf657fd22012-12-05 16:48:26 -0500385 } else if (!strcmp(words[i], "line")) {
Jim Cromie80370722020-07-19 17:10:52 -0600386 if (parse_linerange(query, words[i+1]))
Jim Cromie820874c2011-12-19 17:12:49 -0500387 return -EINVAL;
Jason Barone9d376f2009-02-05 11:51:38 -0500388 } else {
Jim Cromieae27f862011-12-19 17:12:34 -0500389 pr_err("unknown keyword \"%s\"\n", words[i]);
Jason Barone9d376f2009-02-05 11:51:38 -0500390 return -EINVAL;
391 }
Jim Cromie820874c2011-12-19 17:12:49 -0500392 if (rc)
393 return rc;
Jason Barone9d376f2009-02-05 11:51:38 -0500394 }
Jim Cromie574b3722011-12-19 17:13:16 -0500395 vpr_info_dq(query, "parsed");
Jason Barone9d376f2009-02-05 11:51:38 -0500396 return 0;
397}
398
399/*
400 * Parse `str' as a flags specification, format [-+=][p]+.
401 * Sets up *maskp and *flagsp to be used when changing the
402 * flags fields of matched _ddebug's. Returns 0 on success
403 * or <0 on error.
404 */
405static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
406 unsigned int *maskp)
407{
408 unsigned flags = 0;
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100409 int op = '=', i;
Jason Barone9d376f2009-02-05 11:51:38 -0500410
411 switch (*str) {
412 case '+':
413 case '-':
414 case '=':
415 op = *str++;
416 break;
417 default:
Jim Cromie18c216c2012-12-05 16:48:27 -0500418 pr_err("bad flag-op %c, at start of %s\n", *str, str);
Jason Barone9d376f2009-02-05 11:51:38 -0500419 return -EINVAL;
420 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600421 vpr_info("op='%c'\n", op);
Jason Barone9d376f2009-02-05 11:51:38 -0500422
Joe Perchesf657fd22012-12-05 16:48:26 -0500423 for (; *str ; ++str) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100424 for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
425 if (*str == opt_array[i].opt_char) {
426 flags |= opt_array[i].flag;
427 break;
428 }
Jason Barone9d376f2009-02-05 11:51:38 -0500429 }
Jim Cromie18c216c2012-12-05 16:48:27 -0500430 if (i < 0) {
Jim Cromie0b8f96b2020-07-19 17:10:48 -0600431 pr_err("unknown flag '%c'\n", *str);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100432 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500433 }
Jason Barone9d376f2009-02-05 11:51:38 -0500434 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600435 vpr_info("flags=0x%x\n", flags);
Jason Barone9d376f2009-02-05 11:51:38 -0500436
437 /* calculate final *flagsp, *maskp according to mask and op */
438 switch (op) {
439 case '=':
440 *maskp = 0;
441 *flagsp = flags;
442 break;
443 case '+':
444 *maskp = ~0U;
445 *flagsp = flags;
446 break;
447 case '-':
448 *maskp = ~flags;
449 *flagsp = 0;
450 break;
451 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600452 vpr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp);
Jason Barone9d376f2009-02-05 11:51:38 -0500453 return 0;
454}
455
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600456static int ddebug_exec_query(char *query_string, const char *modname)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200457{
458 unsigned int flags = 0, mask = 0;
Jim Cromie9c9d0ac2020-07-19 17:10:49 -0600459 struct ddebug_query query = {};
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200460#define MAXWORDS 9
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500461 int nwords, nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200462 char *words[MAXWORDS];
463
464 nwords = ddebug_tokenize(query_string, words, MAXWORDS);
Jim Cromie18c216c2012-12-05 16:48:27 -0500465 if (nwords <= 0) {
466 pr_err("tokenize failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200467 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500468 }
469 /* check flags 1st (last arg) so query is pairs of spec,val */
470 if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) {
471 pr_err("flags parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200472 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500473 }
474 if (ddebug_parse_query(words, nwords-1, &query, modname)) {
475 pr_err("query parse failed\n");
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200476 return -EINVAL;
Jim Cromie18c216c2012-12-05 16:48:27 -0500477 }
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200478 /* actually go and implement the change */
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500479 nfound = ddebug_change(&query, flags, mask);
Joe Perchesf657fd22012-12-05 16:48:26 -0500480 vpr_info_dq(&query, nfound ? "applied" : "no-match");
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500481
482 return nfound;
483}
484
485/* handle multiple queries in query string, continue on error, return
486 last error or number of matching callsites. Module name is either
487 in param (for boot arg) or perhaps in query string.
488*/
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600489static int ddebug_exec_queries(char *query, const char *modname)
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500490{
491 char *split;
492 int i, errs = 0, exitcode = 0, rc, nfound = 0;
493
494 for (i = 0; query; query = split) {
495 split = strpbrk(query, ";\n");
496 if (split)
497 *split++ = '\0';
498
499 query = skip_spaces(query);
500 if (!query || !*query || *query == '#')
501 continue;
502
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600503 vpr_info("query %d: \"%s\"\n", i, query);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500504
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600505 rc = ddebug_exec_query(query, modname);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500506 if (rc < 0) {
507 errs++;
508 exitcode = rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500509 } else {
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500510 nfound += rc;
Joe Perchesf657fd22012-12-05 16:48:26 -0500511 }
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500512 i++;
513 }
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600514 vpr_info("processed %d queries, with %d matches, %d errs\n",
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500515 i, nfound, errs);
516
517 if (exitcode)
518 return exitcode;
519 return nfound;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200520}
521
Jason Baron431625d2011-10-04 14:13:19 -0700522#define PREFIX_SIZE 64
523
524static int remaining(int wrote)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100525{
Jason Baron431625d2011-10-04 14:13:19 -0700526 if (PREFIX_SIZE - wrote > 0)
527 return PREFIX_SIZE - wrote;
528 return 0;
529}
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100530
Jason Baron431625d2011-10-04 14:13:19 -0700531static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
532{
533 int pos_after_tid;
534 int pos = 0;
535
Joe Perches798efc62012-09-12 20:11:29 -0700536 *buf = '\0';
537
Jason Baron431625d2011-10-04 14:13:19 -0700538 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100539 if (in_interrupt())
Joe Perches798efc62012-09-12 20:11:29 -0700540 pos += snprintf(buf + pos, remaining(pos), "<intr> ");
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100541 else
Jason Baron431625d2011-10-04 14:13:19 -0700542 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
Joe Perches798efc62012-09-12 20:11:29 -0700543 task_pid_vnr(current));
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100544 }
Jason Baron431625d2011-10-04 14:13:19 -0700545 pos_after_tid = pos;
546 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
547 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700548 desc->modname);
Jason Baron431625d2011-10-04 14:13:19 -0700549 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
550 pos += snprintf(buf + pos, remaining(pos), "%s:",
Joe Perches798efc62012-09-12 20:11:29 -0700551 desc->function);
Jason Baron431625d2011-10-04 14:13:19 -0700552 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
Jim Cromie07100be2011-12-19 17:11:09 -0500553 pos += snprintf(buf + pos, remaining(pos), "%d:",
Joe Perches798efc62012-09-12 20:11:29 -0700554 desc->lineno);
Jason Baron431625d2011-10-04 14:13:19 -0700555 if (pos - pos_after_tid)
556 pos += snprintf(buf + pos, remaining(pos), " ");
557 if (pos >= PREFIX_SIZE)
558 buf[PREFIX_SIZE - 1] = '\0';
Joe Perches6c2140e2011-08-11 14:36:25 -0400559
Jason Baron431625d2011-10-04 14:13:19 -0700560 return buf;
Joe Perches6c2140e2011-08-11 14:36:25 -0400561}
562
Joe Perches906d2012014-09-24 11:17:56 -0700563void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100564{
565 va_list args;
Jason Baron431625d2011-10-04 14:13:19 -0700566 struct va_format vaf;
567 char buf[PREFIX_SIZE];
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100568
569 BUG_ON(!descriptor);
570 BUG_ON(!fmt);
571
572 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700573
Jason Baron431625d2011-10-04 14:13:19 -0700574 vaf.fmt = fmt;
575 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700576
Joe Perches906d2012014-09-24 11:17:56 -0700577 printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700578
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100579 va_end(args);
Bart Van Assche8ba6ebf52011-01-23 17:17:24 +0100580}
581EXPORT_SYMBOL(__dynamic_pr_debug);
582
Joe Perches906d2012014-09-24 11:17:56 -0700583void __dynamic_dev_dbg(struct _ddebug *descriptor,
Joe Perchescbc46632011-08-11 14:36:21 -0400584 const struct device *dev, const char *fmt, ...)
585{
586 struct va_format vaf;
587 va_list args;
Joe Perchescbc46632011-08-11 14:36:21 -0400588
589 BUG_ON(!descriptor);
590 BUG_ON(!fmt);
591
592 va_start(args, fmt);
Joe Perches798efc62012-09-12 20:11:29 -0700593
Joe Perchescbc46632011-08-11 14:36:21 -0400594 vaf.fmt = fmt;
595 vaf.va = &args;
Joe Perches798efc62012-09-12 20:11:29 -0700596
597 if (!dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700598 printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700599 } else {
600 char buf[PREFIX_SIZE];
Joe Perches798efc62012-09-12 20:11:29 -0700601
Joe Perchesa39d4a82014-12-10 15:50:15 -0800602 dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
Joe Perches906d2012014-09-24 11:17:56 -0700603 dynamic_emit_prefix(descriptor, buf),
604 dev_driver_string(dev), dev_name(dev),
605 &vaf);
Joe Perches798efc62012-09-12 20:11:29 -0700606 }
607
Joe Perchescbc46632011-08-11 14:36:21 -0400608 va_end(args);
Joe Perchescbc46632011-08-11 14:36:21 -0400609}
610EXPORT_SYMBOL(__dynamic_dev_dbg);
611
Jason Baron0feefd92011-10-04 14:13:22 -0700612#ifdef CONFIG_NET
613
Joe Perches906d2012014-09-24 11:17:56 -0700614void __dynamic_netdev_dbg(struct _ddebug *descriptor,
615 const struct net_device *dev, const char *fmt, ...)
Jason Baronffa10cb2011-08-11 14:36:48 -0400616{
617 struct va_format vaf;
618 va_list args;
Jason Baronffa10cb2011-08-11 14:36:48 -0400619
620 BUG_ON(!descriptor);
621 BUG_ON(!fmt);
622
623 va_start(args, fmt);
Joe Perchesb004ff42012-09-12 20:12:19 -0700624
Jason Baronffa10cb2011-08-11 14:36:48 -0400625 vaf.fmt = fmt;
626 vaf.va = &args;
Joe Perchesb004ff42012-09-12 20:12:19 -0700627
628 if (dev && dev->dev.parent) {
629 char buf[PREFIX_SIZE];
Joe Perchesb004ff42012-09-12 20:12:19 -0700630
Joe Perchesa39d4a82014-12-10 15:50:15 -0800631 dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
Joe Perches906d2012014-09-24 11:17:56 -0700632 "%s%s %s %s%s: %pV",
633 dynamic_emit_prefix(descriptor, buf),
634 dev_driver_string(dev->dev.parent),
635 dev_name(dev->dev.parent),
636 netdev_name(dev), netdev_reg_state(dev),
637 &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700638 } else if (dev) {
Joe Perches906d2012014-09-24 11:17:56 -0700639 printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
640 netdev_reg_state(dev), &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700641 } else {
Joe Perches906d2012014-09-24 11:17:56 -0700642 printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
Joe Perchesb004ff42012-09-12 20:12:19 -0700643 }
644
Jason Baronffa10cb2011-08-11 14:36:48 -0400645 va_end(args);
Jason Baronffa10cb2011-08-11 14:36:48 -0400646}
647EXPORT_SYMBOL(__dynamic_netdev_dbg);
648
Jason Baron0feefd92011-10-04 14:13:22 -0700649#endif
650
Gal Pressman923abb92019-05-01 13:48:13 +0300651#if IS_ENABLED(CONFIG_INFINIBAND)
652
653void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
654 const struct ib_device *ibdev, const char *fmt, ...)
655{
656 struct va_format vaf;
657 va_list args;
658
659 va_start(args, fmt);
660
661 vaf.fmt = fmt;
662 vaf.va = &args;
663
664 if (ibdev && ibdev->dev.parent) {
665 char buf[PREFIX_SIZE];
666
667 dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
668 "%s%s %s %s: %pV",
669 dynamic_emit_prefix(descriptor, buf),
670 dev_driver_string(ibdev->dev.parent),
671 dev_name(ibdev->dev.parent),
672 dev_name(&ibdev->dev),
673 &vaf);
674 } else if (ibdev) {
675 printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
676 } else {
677 printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
678 }
679
680 va_end(args);
681}
682EXPORT_SYMBOL(__dynamic_ibdev_dbg);
683
684#endif
685
Jim Cromiebc757f62011-12-19 17:12:29 -0500686#define DDEBUG_STRING_SIZE 1024
687static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
688
Thomas Renningera648ec02010-08-06 16:11:02 +0200689static __init int ddebug_setup_query(char *str)
690{
Jim Cromiebc757f62011-12-19 17:12:29 -0500691 if (strlen(str) >= DDEBUG_STRING_SIZE) {
Joe Perches4ad275e2011-08-11 14:36:33 -0400692 pr_warn("ddebug boot param string too large\n");
Thomas Renningera648ec02010-08-06 16:11:02 +0200693 return 0;
694 }
Jim Cromiebc757f62011-12-19 17:12:29 -0500695 strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
Thomas Renningera648ec02010-08-06 16:11:02 +0200696 return 1;
697}
698
699__setup("ddebug_query=", ddebug_setup_query);
700
Jason Barone9d376f2009-02-05 11:51:38 -0500701/*
Masatake YAMATO231821d2014-12-15 12:04:16 +0900702 * File_ops->write method for <debugfs>/dynamic_debug/control. Gathers the
Jason Barone9d376f2009-02-05 11:51:38 -0500703 * command text from userspace, parses and executes it.
704 */
Jim Cromie72814912011-12-19 17:13:07 -0500705#define USER_BUF_PAGE 4096
Jason Barone9d376f2009-02-05 11:51:38 -0500706static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
707 size_t len, loff_t *offp)
708{
Jim Cromie72814912011-12-19 17:13:07 -0500709 char *tmpbuf;
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200710 int ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500711
712 if (len == 0)
713 return 0;
Jim Cromie72814912011-12-19 17:13:07 -0500714 if (len > USER_BUF_PAGE - 1) {
715 pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
Jason Barone9d376f2009-02-05 11:51:38 -0500716 return -E2BIG;
Jim Cromie72814912011-12-19 17:13:07 -0500717 }
Al Viro16e5c1f2015-12-24 00:06:05 -0500718 tmpbuf = memdup_user_nul(ubuf, len);
719 if (IS_ERR(tmpbuf))
720 return PTR_ERR(tmpbuf);
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600721 vpr_info("read %d bytes from userspace\n", (int)len);
Jason Barone9d376f2009-02-05 11:51:38 -0500722
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600723 ret = ddebug_exec_queries(tmpbuf, NULL);
Jim Cromie72814912011-12-19 17:13:07 -0500724 kfree(tmpbuf);
Jim Cromie85f7f6c2011-12-19 17:13:21 -0500725 if (ret < 0)
Thomas Renningerfd89cfb2010-08-06 16:11:01 +0200726 return ret;
Jason Barone9d376f2009-02-05 11:51:38 -0500727
728 *offp += len;
729 return len;
730}
731
732/*
733 * Set the iterator to point to the first _ddebug object
734 * and return a pointer to that first object. Returns
735 * NULL if there are no _ddebugs at all.
736 */
737static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
738{
739 if (list_empty(&ddebug_tables)) {
740 iter->table = NULL;
741 iter->idx = 0;
742 return NULL;
743 }
744 iter->table = list_entry(ddebug_tables.next,
745 struct ddebug_table, link);
746 iter->idx = 0;
747 return &iter->table->ddebugs[iter->idx];
748}
749
750/*
751 * Advance the iterator to point to the next _ddebug
752 * object from the one the iterator currently points at,
753 * and returns a pointer to the new _ddebug. Returns
754 * NULL if the iterator has seen all the _ddebugs.
755 */
756static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
757{
758 if (iter->table == NULL)
759 return NULL;
760 if (++iter->idx == iter->table->num_ddebugs) {
761 /* iterate to next table */
762 iter->idx = 0;
763 if (list_is_last(&iter->table->link, &ddebug_tables)) {
764 iter->table = NULL;
765 return NULL;
766 }
767 iter->table = list_entry(iter->table->link.next,
768 struct ddebug_table, link);
769 }
770 return &iter->table->ddebugs[iter->idx];
771}
772
773/*
774 * Seq_ops start method. Called at the start of every
775 * read() call from userspace. Takes the ddebug_lock and
776 * seeks the seq_file's iterator to the given position.
777 */
778static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
779{
780 struct ddebug_iter *iter = m->private;
781 struct _ddebug *dp;
782 int n = *pos;
783
Jason Barone9d376f2009-02-05 11:51:38 -0500784 mutex_lock(&ddebug_lock);
785
786 if (!n)
787 return SEQ_START_TOKEN;
788 if (n < 0)
789 return NULL;
790 dp = ddebug_iter_first(iter);
791 while (dp != NULL && --n > 0)
792 dp = ddebug_iter_next(iter);
793 return dp;
794}
795
796/*
797 * Seq_ops next method. Called several times within a read()
798 * call from userspace, with ddebug_lock held. Walks to the
799 * next _ddebug object with a special case for the header line.
800 */
801static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
802{
803 struct ddebug_iter *iter = m->private;
804 struct _ddebug *dp;
805
Jason Barone9d376f2009-02-05 11:51:38 -0500806 if (p == SEQ_START_TOKEN)
807 dp = ddebug_iter_first(iter);
808 else
809 dp = ddebug_iter_next(iter);
810 ++*pos;
811 return dp;
812}
813
814/*
815 * Seq_ops show method. Called several times within a read()
816 * call from userspace, with ddebug_lock held. Formats the
817 * current _ddebug as a single human-readable line, with a
818 * special case for the header line.
819 */
820static int ddebug_proc_show(struct seq_file *m, void *p)
821{
822 struct ddebug_iter *iter = m->private;
823 struct _ddebug *dp = p;
Jim Cromief678ce82020-07-19 17:10:47 -0600824 struct flagsbuf flags;
Jason Barone9d376f2009-02-05 11:51:38 -0500825
Jason Barone9d376f2009-02-05 11:51:38 -0500826 if (p == SEQ_START_TOKEN) {
827 seq_puts(m,
Joe Perchesf657fd22012-12-05 16:48:26 -0500828 "# filename:lineno [module]function flags format\n");
Jason Barone9d376f2009-02-05 11:51:38 -0500829 return 0;
830 }
831
Jim Cromie5ca7d2a2011-12-19 17:12:44 -0500832 seq_printf(m, "%s:%u [%s]%s =%s \"",
Joe Perchesf657fd22012-12-05 16:48:26 -0500833 trim_prefix(dp->filename), dp->lineno,
834 iter->table->mod_name, dp->function,
Jim Cromief678ce82020-07-19 17:10:47 -0600835 ddebug_describe_flags(dp->flags, &flags));
Jason Barone9d376f2009-02-05 11:51:38 -0500836 seq_escape(m, dp->format, "\t\r\n\"");
837 seq_puts(m, "\"\n");
838
839 return 0;
840}
841
842/*
843 * Seq_ops stop method. Called at the end of each read()
844 * call from userspace. Drops ddebug_lock.
845 */
846static void ddebug_proc_stop(struct seq_file *m, void *p)
847{
Jason Barone9d376f2009-02-05 11:51:38 -0500848 mutex_unlock(&ddebug_lock);
849}
850
851static const struct seq_operations ddebug_proc_seqops = {
852 .start = ddebug_proc_start,
853 .next = ddebug_proc_next,
854 .show = ddebug_proc_show,
855 .stop = ddebug_proc_stop
856};
857
Jason Barone9d376f2009-02-05 11:51:38 -0500858static int ddebug_proc_open(struct inode *inode, struct file *file)
859{
Jim Cromieb8ccd5d2012-04-27 14:30:32 -0600860 vpr_info("called\n");
Rob Jones4bad78c2014-10-13 15:51:32 -0700861 return seq_open_private(file, &ddebug_proc_seqops,
862 sizeof(struct ddebug_iter));
Jason Barone9d376f2009-02-05 11:51:38 -0500863}
864
865static const struct file_operations ddebug_proc_fops = {
866 .owner = THIS_MODULE,
867 .open = ddebug_proc_open,
868 .read = seq_read,
869 .llseek = seq_lseek,
870 .release = seq_release_private,
871 .write = ddebug_proc_write
872};
873
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800874static const struct proc_ops proc_fops = {
875 .proc_open = ddebug_proc_open,
876 .proc_read = seq_read,
877 .proc_lseek = seq_lseek,
878 .proc_release = seq_release_private,
879 .proc_write = ddebug_proc_write
880};
881
Jason Barone9d376f2009-02-05 11:51:38 -0500882/*
883 * Allocate a new ddebug_table for the given module
884 * and add it to the global list.
885 */
886int ddebug_add_module(struct _ddebug *tab, unsigned int n,
887 const char *name)
888{
889 struct ddebug_table *dt;
Jason Barone9d376f2009-02-05 11:51:38 -0500890
891 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800892 if (dt == NULL) {
893 pr_err("error adding module: %s\n", name);
Jason Barone9d376f2009-02-05 11:51:38 -0500894 return -ENOMEM;
Rasmus Villemoes513770f2019-03-07 16:27:48 -0800895 }
Rasmus Villemoescdf6d002019-03-07 16:27:37 -0800896 /*
897 * For built-in modules, name lives in .rodata and is
898 * immortal. For loaded modules, name points at the name[]
899 * member of struct module, which lives at least as long as
900 * this struct ddebug_table.
901 */
902 dt->mod_name = name;
Jason Barone9d376f2009-02-05 11:51:38 -0500903 dt->num_ddebugs = n;
Jason Barone9d376f2009-02-05 11:51:38 -0500904 dt->ddebugs = tab;
905
906 mutex_lock(&ddebug_lock);
Jim Cromie47e9f5a2020-07-19 17:10:50 -0600907 list_add(&dt->link, &ddebug_tables);
Jason Barone9d376f2009-02-05 11:51:38 -0500908 mutex_unlock(&ddebug_lock);
909
Jim Cromie481c0e32020-07-19 17:10:44 -0600910 v2pr_info("%u debug prints in module %s\n", n, dt->mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500911 return 0;
912}
Jason Barone9d376f2009-02-05 11:51:38 -0500913
Jim Cromie6ab676e2012-04-27 14:30:37 -0600914/* helper for ddebug_dyndbg_(boot|module)_param_cb */
915static int ddebug_dyndbg_param_cb(char *param, char *val,
916 const char *modname, int on_err)
Jim Cromieb48420c2012-04-27 14:30:35 -0600917{
Jim Cromieb48420c2012-04-27 14:30:35 -0600918 char *sep;
919
920 sep = strchr(param, '.');
921 if (sep) {
Jim Cromie6ab676e2012-04-27 14:30:37 -0600922 /* needed only for ddebug_dyndbg_boot_param_cb */
Jim Cromieb48420c2012-04-27 14:30:35 -0600923 *sep = '\0';
924 modname = param;
925 param = sep + 1;
926 }
927 if (strcmp(param, "dyndbg"))
Jim Cromie6ab676e2012-04-27 14:30:37 -0600928 return on_err; /* determined by caller */
Jim Cromieb48420c2012-04-27 14:30:35 -0600929
Jim Cromie8e59b5cf2012-04-27 14:30:40 -0600930 ddebug_exec_queries((val ? val : "+p"), modname);
931
Jim Cromieb48420c2012-04-27 14:30:35 -0600932 return 0; /* query failure shouldnt stop module load */
933}
934
Jim Cromie6ab676e2012-04-27 14:30:37 -0600935/* handle both dyndbg and $module.dyndbg params at boot */
936static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -0700937 const char *unused, void *arg)
Jim Cromieb48420c2012-04-27 14:30:35 -0600938{
Jim Cromie6ab676e2012-04-27 14:30:37 -0600939 vpr_info("%s=\"%s\"\n", param, val);
940 return ddebug_dyndbg_param_cb(param, val, NULL, 0);
941}
Jim Cromieb48420c2012-04-27 14:30:35 -0600942
Jim Cromie6ab676e2012-04-27 14:30:37 -0600943/*
944 * modprobe foo finds foo.params in boot-args, strips "foo.", and
945 * passes them to load_module(). This callback gets unknown params,
946 * processes dyndbg params, rejects others.
947 */
948int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
949{
950 vpr_info("module: %s %s=\"%s\"\n", module, param, val);
951 return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
Jim Cromieb48420c2012-04-27 14:30:35 -0600952}
953
Jason Barone9d376f2009-02-05 11:51:38 -0500954static void ddebug_table_free(struct ddebug_table *dt)
955{
956 list_del_init(&dt->link);
Jason Barone9d376f2009-02-05 11:51:38 -0500957 kfree(dt);
958}
959
960/*
961 * Called in response to a module being unloaded. Removes
962 * any ddebug_table's which point at the module.
963 */
Yehuda Sadehff49d742010-07-03 13:07:35 +1000964int ddebug_remove_module(const char *mod_name)
Jason Barone9d376f2009-02-05 11:51:38 -0500965{
966 struct ddebug_table *dt, *nextdt;
967 int ret = -ENOENT;
968
Jim Cromie481c0e32020-07-19 17:10:44 -0600969 v2pr_info("removing module \"%s\"\n", mod_name);
Jason Barone9d376f2009-02-05 11:51:38 -0500970
971 mutex_lock(&ddebug_lock);
972 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800973 if (dt->mod_name == mod_name) {
Jason Barone9d376f2009-02-05 11:51:38 -0500974 ddebug_table_free(dt);
975 ret = 0;
Rasmus Villemoes4573fe12019-03-07 16:27:41 -0800976 break;
Jason Barone9d376f2009-02-05 11:51:38 -0500977 }
978 }
979 mutex_unlock(&ddebug_lock);
980 return ret;
981}
Jason Barone9d376f2009-02-05 11:51:38 -0500982
983static void ddebug_remove_all_tables(void)
984{
985 mutex_lock(&ddebug_lock);
986 while (!list_empty(&ddebug_tables)) {
987 struct ddebug_table *dt = list_entry(ddebug_tables.next,
988 struct ddebug_table,
989 link);
990 ddebug_table_free(dt);
991 }
992 mutex_unlock(&ddebug_lock);
993}
994
Thomas Renninger6a5c0832010-08-06 16:11:03 +0200995static __initdata int ddebug_init_success;
996
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800997static int __init dynamic_debug_init_control(void)
Jason Barone9d376f2009-02-05 11:51:38 -0500998{
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -0800999 struct proc_dir_entry *procfs_dir;
1000 struct dentry *debugfs_dir;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001001
1002 if (!ddebug_init_success)
1003 return -ENODEV;
Jason Barone9d376f2009-02-05 11:51:38 -05001004
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001005 /* Create the control file in debugfs if it is enabled */
1006 if (debugfs_initialized()) {
1007 debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
1008 debugfs_create_file("control", 0644, debugfs_dir, NULL,
1009 &ddebug_proc_fops);
1010 }
1011
1012 /* Also create the control file in procfs */
1013 procfs_dir = proc_mkdir("dynamic_debug", NULL);
1014 if (procfs_dir)
1015 proc_create("control", 0644, procfs_dir, &proc_fops);
Greg Kroah-Hartman9fd714c2019-06-12 17:35:34 +02001016
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001017 return 0;
1018}
1019
1020static int __init dynamic_debug_init(void)
1021{
1022 struct _ddebug *iter, *iter_start;
1023 const char *modname = NULL;
Jim Cromieb48420c2012-04-27 14:30:35 -06001024 char *cmdline;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001025 int ret = 0;
Jim Cromie41076922012-04-27 14:30:39 -06001026 int n = 0, entries = 0, modct = 0;
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001027
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001028 if (&__start___dyndbg == &__stop___dyndbg) {
Orson Zhaiceabef72020-06-07 21:40:14 -07001029 if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
1030 pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
1031 return 1;
1032 }
1033 pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
1034 ddebug_init_success = 1;
1035 return 0;
Jason Barone9d376f2009-02-05 11:51:38 -05001036 }
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001037 iter = __start___dyndbg;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001038 modname = iter->modname;
1039 iter_start = iter;
Jim Cromiee5ebffe2020-07-19 17:10:45 -06001040 for (; iter < __stop___dyndbg; iter++) {
Jim Cromie41076922012-04-27 14:30:39 -06001041 entries++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001042 if (strcmp(modname, iter->modname)) {
Jim Cromie41076922012-04-27 14:30:39 -06001043 modct++;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001044 ret = ddebug_add_module(iter_start, n, modname);
1045 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001046 goto out_err;
Jim Cromieb5b78f82011-12-19 17:12:54 -05001047 n = 0;
1048 modname = iter->modname;
1049 iter_start = iter;
1050 }
1051 n++;
1052 }
1053 ret = ddebug_add_module(iter_start, n, modname);
1054 if (ret)
Jim Cromieaf442392012-04-27 14:30:38 -06001055 goto out_err;
Thomas Renningera648ec02010-08-06 16:11:02 +02001056
Jim Cromieaf442392012-04-27 14:30:38 -06001057 ddebug_init_success = 1;
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001058 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 -05001059 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
Jim Cromie81d0c2c2020-07-19 17:10:46 -06001060 (int)(entries * sizeof(struct _ddebug)));
Jim Cromieaf442392012-04-27 14:30:38 -06001061
1062 /* apply ddebug_query boot param, dont unload tables on err */
Thomas Renningera648ec02010-08-06 16:11:02 +02001063 if (ddebug_setup_string[0] != '\0') {
Joe Perchesf657fd22012-12-05 16:48:26 -05001064 pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
Jim Cromie8e59b5cf2012-04-27 14:30:40 -06001065 ret = ddebug_exec_queries(ddebug_setup_string, NULL);
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001066 if (ret < 0)
Joe Perchesf657fd22012-12-05 16:48:26 -05001067 pr_warn("Invalid ddebug boot param %s\n",
Joe Perches4ad275e2011-08-11 14:36:33 -04001068 ddebug_setup_string);
Thomas Renningera648ec02010-08-06 16:11:02 +02001069 else
Jim Cromie85f7f6c2011-12-19 17:13:21 -05001070 pr_info("%d changes by ddebug_query\n", ret);
Jason Barone9d376f2009-02-05 11:51:38 -05001071 }
Jim Cromieb48420c2012-04-27 14:30:35 -06001072 /* now that ddebug tables are loaded, process all boot args
1073 * again to find and activate queries given in dyndbg params.
1074 * While this has already been done for known boot params, it
1075 * ignored the unknown ones (dyndbg in particular). Reusing
1076 * parse_args avoids ad-hoc parsing. This will also attempt
1077 * to activate queries for not-yet-loaded modules, which is
1078 * slightly noisy if verbose, but harmless.
1079 */
1080 cmdline = kstrdup(saved_command_line, GFP_KERNEL);
1081 parse_args("dyndbg params", cmdline, NULL,
Luis R. Rodriguezecc86172015-03-30 16:20:03 -07001082 0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
Jim Cromieb48420c2012-04-27 14:30:35 -06001083 kfree(cmdline);
Jim Cromieaf442392012-04-27 14:30:38 -06001084 return 0;
Thomas Renningera648ec02010-08-06 16:11:02 +02001085
Jim Cromieaf442392012-04-27 14:30:38 -06001086out_err:
1087 ddebug_remove_all_tables();
Jason Barone9d376f2009-02-05 11:51:38 -05001088 return 0;
1089}
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001090/* Allow early initialization for boot messages via boot param */
Jim Cromie3ec56522012-04-27 14:30:42 -06001091early_initcall(dynamic_debug_init);
Jim Cromieb48420c2012-04-27 14:30:35 -06001092
Thomas Renninger6a5c0832010-08-06 16:11:03 +02001093/* Debugfs setup must be done later */
Greg Kroah-Hartman239a5792020-02-10 13:11:42 -08001094fs_initcall(dynamic_debug_init_control);