VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   33 Branches   55 Tags
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    1) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    2)  * lib/dynamic_debug.c
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    3)  *
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    4)  * make pr_debug()/dev_dbg() calls runtime configurable based upon their
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    5)  * source module.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    6)  *
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    7)  * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    8)  * By Greg Banks <gnb@melbourne.sgi.com>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500    9)  * Copyright (c) 2008 Silicon Graphics Inc.  All Rights Reserved.
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   10)  * Copyright (C) 2011 Bart Van Assche.  All Rights Reserved.
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800   11)  * Copyright (C) 2013 Du, Changbin <changbin.du@gmail.com>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   12)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   13) 
5aa9ffbbaeb3a (Jim Cromie         2020-07-19 17:10:57 -0600   14) #define pr_fmt(fmt) "dyndbg: " fmt
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400   15) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   16) #include <linux/kernel.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   17) #include <linux/module.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   18) #include <linux/moduleparam.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   19) #include <linux/kallsyms.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   20) #include <linux/types.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   21) #include <linux/mutex.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   22) #include <linux/proc_fs.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   23) #include <linux/seq_file.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   24) #include <linux/list.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   25) #include <linux/sysctl.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   26) #include <linux/ctype.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   27) #include <linux/string.h>
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800   28) #include <linux/parser.h>
d338b1379f96b (Andy Shevchenko    2013-04-30 15:27:32 -0700   29) #include <linux/string_helpers.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   30) #include <linux/uaccess.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   31) #include <linux/dynamic_debug.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   32) #include <linux/debugfs.h>
5a0e3ad6af866 (Tejun Heo          2010-03-24 17:04:11 +0900   33) #include <linux/slab.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   34) #include <linux/jump_label.h>
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   35) #include <linux/hardirq.h>
e8d9792aa514e (Greg Kroah-Hartman 2011-02-03 15:59:58 -0800   36) #include <linux/sched.h>
fef15d2f3d97c (Greg Kroah-Hartman 2012-05-07 16:47:32 -0700   37) #include <linux/device.h>
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400   38) #include <linux/netdevice.h>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   39) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300   40) #include <rdma/ib_verbs.h>
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300   41) 
e5ebffe18e5ad (Jim Cromie         2020-07-19 17:10:45 -0600   42) extern struct _ddebug __start___dyndbg[];
e5ebffe18e5ad (Jim Cromie         2020-07-19 17:10:45 -0600   43) extern struct _ddebug __stop___dyndbg[];
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   44) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   45) struct ddebug_table {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   46) 	struct list_head link;
3e406b1d7c1e5 (Rasmus Villemoes   2015-11-06 16:30:15 -0800   47) 	const char *mod_name;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   48) 	unsigned int num_ddebugs;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   49) 	struct _ddebug *ddebugs;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   50) };
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   51) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   52) struct ddebug_query {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   53) 	const char *filename;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   54) 	const char *module;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   55) 	const char *function;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   56) 	const char *format;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   57) 	unsigned int first_lineno, last_lineno;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   58) };
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   59) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   60) struct ddebug_iter {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   61) 	struct ddebug_table *table;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   62) 	unsigned int idx;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   63) };
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   64) 
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600   65) struct flag_settings {
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600   66) 	unsigned int flags;
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600   67) 	unsigned int mask;
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600   68) };
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600   69) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   70) static DEFINE_MUTEX(ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   71) static LIST_HEAD(ddebug_tables);
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500   72) static int verbose;
74df138d508eb (Jim Cromie         2011-12-19 17:12:24 -0500   73) module_param(verbose, int, 0644);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   74) 
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   75) /* Return the path relative to source root */
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   76) static inline const char *trim_prefix(const char *path)
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   77) {
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   78) 	int skip = strlen(__FILE__) - strlen("lib/dynamic_debug.c");
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   79) 
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   80) 	if (strncmp(path, __FILE__, skip))
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   81) 		skip = 0; /* prefix mismatch, don't skip */
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   82) 
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   83) 	return path + skip;
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   84) }
2b6783191da72 (Jim Cromie         2011-12-19 17:13:12 -0500   85) 
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   86) static struct { unsigned flag:8; char opt_char; } opt_array[] = {
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   87) 	{ _DPRINTK_FLAGS_PRINT, 'p' },
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   88) 	{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   89) 	{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   90) 	{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   91) 	{ _DPRINTK_FLAGS_INCL_TID, 't' },
5ca7d2a6c5e4f (Jim Cromie         2011-12-19 17:12:44 -0500   92) 	{ _DPRINTK_FLAGS_NONE, '_' },
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   93) };
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100   94) 
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600   95) struct flagsbuf { char buf[ARRAY_SIZE(opt_array)+1]; };
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600   96) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   97) /* format a string into buf[] which describes the _ddebug's flags */
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600   98) static char *ddebug_describe_flags(unsigned int flags, struct flagsbuf *fb)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500   99) {
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  100) 	char *p = fb->buf;
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  101) 	int i;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  102) 
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  103) 	for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  104) 		if (flags & opt_array[i].flag)
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  105) 			*p++ = opt_array[i].opt_char;
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  106) 	if (p == fb->buf)
5ca7d2a6c5e4f (Jim Cromie         2011-12-19 17:12:44 -0500  107) 		*p++ = '_';
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  108) 	*p = '\0';
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  109) 
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  110) 	return fb->buf;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  111) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  112) 
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600  113) #define vnpr_info(lvl, fmt, ...)				\
b8ccd5dee776d (Jim Cromie         2012-04-27 14:30:32 -0600  114) do {								\
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600  115) 	if (verbose >= lvl)					\
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  116) 		pr_info(fmt, ##__VA_ARGS__);			\
574b3725e3275 (Jim Cromie         2011-12-19 17:13:16 -0500  117) } while (0)
574b3725e3275 (Jim Cromie         2011-12-19 17:13:16 -0500  118) 
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600  119) #define vpr_info(fmt, ...)	vnpr_info(1, fmt, ##__VA_ARGS__)
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600  120) #define v2pr_info(fmt, ...)	vnpr_info(2, fmt, ##__VA_ARGS__)
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600  121) 
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  122) static void vpr_info_dq(const struct ddebug_query *query, const char *msg)
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  123) {
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  124) 	/* trim any trailing newlines */
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  125) 	int fmtlen = 0;
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  126) 
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  127) 	if (query->format) {
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  128) 		fmtlen = strlen(query->format);
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  129) 		while (fmtlen && query->format[fmtlen - 1] == '\n')
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  130) 			fmtlen--;
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  131) 	}
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  132) 
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  133) 	vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n",
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  134) 		 msg,
f62fc08fdc51d (Jim Cromie         2020-07-19 17:10:51 -0600  135) 		 query->function ?: "",
f62fc08fdc51d (Jim Cromie         2020-07-19 17:10:51 -0600  136) 		 query->filename ?: "",
f62fc08fdc51d (Jim Cromie         2020-07-19 17:10:51 -0600  137) 		 query->module ?: "",
f62fc08fdc51d (Jim Cromie         2020-07-19 17:10:51 -0600  138) 		 fmtlen, query->format ?: "",
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  139) 		 query->first_lineno, query->last_lineno);
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  140) }
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  141) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  142) /*
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  143)  * Search the tables for _ddebug's which match the given `query' and
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  144)  * apply the `flags' and `mask' to them.  Returns number of matching
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  145)  * callsites, normally the same as number of changes.  If verbose,
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  146)  * logs the changes.  Takes ddebug_lock.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  147)  */
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  148) static int ddebug_change(const struct ddebug_query *query,
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  149) 			 struct flag_settings *modifiers)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  150) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  151) 	int i;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  152) 	struct ddebug_table *dt;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  153) 	unsigned int newflags;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  154) 	unsigned int nfound = 0;
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  155) 	struct flagsbuf fbuf;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  156) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  157) 	/* search for matching ddebugs */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  158) 	mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  159) 	list_for_each_entry(dt, &ddebug_tables, link) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  160) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  161) 		/* match against the module name */
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  162) 		if (query->module &&
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  163) 		    !match_wildcard(query->module, dt->mod_name))
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  164) 			continue;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  165) 
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  166) 		for (i = 0; i < dt->num_ddebugs; i++) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  167) 			struct _ddebug *dp = &dt->ddebugs[i];
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  168) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  169) 			/* match against the source filename */
d6a238d25014d (Jim Cromie         2011-12-19 17:12:39 -0500  170) 			if (query->filename &&
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  171) 			    !match_wildcard(query->filename, dp->filename) &&
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  172) 			    !match_wildcard(query->filename,
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  173) 					   kbasename(dp->filename)) &&
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  174) 			    !match_wildcard(query->filename,
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  175) 					   trim_prefix(dp->filename)))
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  176) 				continue;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  177) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  178) 			/* match against the function */
d6a238d25014d (Jim Cromie         2011-12-19 17:12:39 -0500  179) 			if (query->function &&
578b1e0701af3 (Changbin Du        2014-01-23 15:54:14 -0800  180) 			    !match_wildcard(query->function, dp->function))
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  181) 				continue;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  182) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  183) 			/* match against the format */
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  184) 			if (query->format) {
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  185) 				if (*query->format == '^') {
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  186) 					char *p;
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  187) 					/* anchored search. match must be at beginning */
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  188) 					p = strstr(dp->format, query->format+1);
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  189) 					if (p != dp->format)
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  190) 						continue;
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  191) 				} else if (!strstr(dp->format, query->format))
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  192) 					continue;
4b334484fa7f4 (Jim Cromie         2020-07-19 17:10:56 -0600  193) 			}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  194) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  195) 			/* match against the line number range */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  196) 			if (query->first_lineno &&
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  197) 			    dp->lineno < query->first_lineno)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  198) 				continue;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  199) 			if (query->last_lineno &&
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  200) 			    dp->lineno > query->last_lineno)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  201) 				continue;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  202) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  203) 			nfound++;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  204) 
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  205) 			newflags = (dp->flags & modifiers->mask) | modifiers->flags;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  206) 			if (newflags == dp->flags)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  207) 				continue;
e9666d10a5677 (Masahiro Yamada    2018-12-31 00:14:15 +0900  208) #ifdef CONFIG_JUMP_LABEL
9049fc745300c (Jason Baron        2016-08-03 13:46:39 -0700  209) 			if (dp->flags & _DPRINTK_FLAGS_PRINT) {
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  210) 				if (!(modifiers->flags & _DPRINTK_FLAGS_PRINT))
9049fc745300c (Jason Baron        2016-08-03 13:46:39 -0700  211) 					static_branch_disable(&dp->key.dd_key_true);
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  212) 			} else if (modifiers->flags & _DPRINTK_FLAGS_PRINT)
9049fc745300c (Jason Baron        2016-08-03 13:46:39 -0700  213) 				static_branch_enable(&dp->key.dd_key_true);
9049fc745300c (Jason Baron        2016-08-03 13:46:39 -0700  214) #endif
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  215) 			dp->flags = newflags;
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600  216) 			v2pr_info("changed %s:%d [%s]%s =%s\n",
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  217) 				 trim_prefix(dp->filename), dp->lineno,
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  218) 				 dt->mod_name, dp->function,
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  219) 				 ddebug_describe_flags(dp->flags, &fbuf));
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  220) 		}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  221) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  222) 	mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  223) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  224) 	if (!nfound && verbose)
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400  225) 		pr_info("no matches for query\n");
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  226) 
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  227) 	return nfound;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  228) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  229) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  230) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  231)  * Split the buffer `buf' into space-separated words.
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  232)  * Handles simple " and ' quoting, i.e. without nested,
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  233)  * embedded or escaped \".  Return the number of words
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  234)  * or <0 on error.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  235)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  236) static int ddebug_tokenize(char *buf, char *words[], int maxwords)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  237) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  238) 	int nwords = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  239) 
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  240) 	while (*buf) {
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  241) 		char *end;
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  242) 
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  243) 		/* Skip leading whitespace */
e7d2860b690d4 (André Goddard Rosa 2009-12-14 18:01:06 -0800  244) 		buf = skip_spaces(buf);
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  245) 		if (!*buf)
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  246) 			break;	/* oh, it was trailing whitespace */
8bd6026e88cb2 (Jim Cromie         2011-12-19 17:13:03 -0500  247) 		if (*buf == '#')
8bd6026e88cb2 (Jim Cromie         2011-12-19 17:13:03 -0500  248) 			break;	/* token starts comment, skip rest of line */
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  249) 
07100be7e0495 (Jim Cromie         2011-12-19 17:11:09 -0500  250) 		/* find `end' of word, whitespace separated or quoted */
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  251) 		if (*buf == '"' || *buf == '\'') {
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  252) 			int quote = *buf++;
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  253) 			for (end = buf; *end && *end != quote; end++)
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  254) 				;
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  255) 			if (!*end) {
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  256) 				pr_err("unclosed quote: %s\n", buf);
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  257) 				return -EINVAL;	/* unclosed quote */
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  258) 			}
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  259) 		} else {
7f6e1f3072b68 (Greg Kroah-Hartman 2020-09-10 18:42:38 +0200  260) 			for (end = buf; *end && !isspace(*end); end++)
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  261) 				;
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  262) 			BUG_ON(end == buf);
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  263) 		}
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  264) 
07100be7e0495 (Jim Cromie         2011-12-19 17:11:09 -0500  265) 		/* `buf' is start of word, `end' is one past its end */
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  266) 		if (nwords == maxwords) {
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  267) 			pr_err("too many words, legal max <=%d\n", maxwords);
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  268) 			return -EINVAL;	/* ran out of words[] before bytes */
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  269) 		}
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  270) 		if (*end)
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  271) 			*end++ = '\0';	/* terminate the word */
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  272) 		words[nwords++] = buf;
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  273) 		buf = end;
9898abb3d2331 (Greg Banks         2009-02-06 12:54:26 +1100  274) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  275) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  276) 	if (verbose) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  277) 		int i;
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400  278) 		pr_info("split into words:");
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  279) 		for (i = 0; i < nwords; i++)
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400  280) 			pr_cont(" \"%s\"", words[i]);
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400  281) 		pr_cont("\n");
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  282) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  283) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  284) 	return nwords;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  285) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  286) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  287) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  288)  * Parse a single line number.  Note that the empty string ""
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  289)  * is treated as a special case and converted to zero, which
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  290)  * is later treated as a "don't care" value.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  291)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  292) static inline int parse_lineno(const char *str, unsigned int *val)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  293) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  294) 	BUG_ON(str == NULL);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  295) 	if (*str == '\0') {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  296) 		*val = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  297) 		return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  298) 	}
4592599af36f5 (Andrey Ryabinin    2014-01-27 17:06:59 -0800  299) 	if (kstrtouint(str, 10, val) < 0) {
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  300) 		pr_err("bad line-number: %s\n", str);
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  301) 		return -EINVAL;
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  302) 	}
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  303) 	return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  304) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  305) 
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  306) static int parse_linerange(struct ddebug_query *query, const char *first)
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  307) {
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  308) 	char *last = strchr(first, '-');
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  309) 
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  310) 	if (query->first_lineno || query->last_lineno) {
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  311) 		pr_err("match-spec: line used 2x\n");
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  312) 		return -EINVAL;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  313) 	}
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  314) 	if (last)
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  315) 		*last++ = '\0';
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  316) 	if (parse_lineno(first, &query->first_lineno) < 0)
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  317) 		return -EINVAL;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  318) 	if (last) {
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  319) 		/* range <first>-<last> */
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  320) 		if (parse_lineno(last, &query->last_lineno) < 0)
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  321) 			return -EINVAL;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  322) 
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  323) 		/* special case for last lineno not specified */
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  324) 		if (query->last_lineno == 0)
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  325) 			query->last_lineno = UINT_MAX;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  326) 
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  327) 		if (query->last_lineno < query->first_lineno) {
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  328) 			pr_err("last-line:%d < 1st-line:%d\n",
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  329) 			       query->last_lineno,
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  330) 			       query->first_lineno);
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  331) 			return -EINVAL;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  332) 		}
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  333) 	} else {
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  334) 		query->last_lineno = query->first_lineno;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  335) 	}
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  336) 	vpr_info("parsed line %d-%d\n", query->first_lineno,
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  337) 		 query->last_lineno);
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  338) 	return 0;
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  339) }
8037072d8139d (Jim Cromie         2020-07-19 17:10:52 -0600  340) 
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  341) static int check_set(const char **dest, char *src, char *name)
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  342) {
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  343) 	int rc = 0;
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  344) 
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  345) 	if (*dest) {
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  346) 		rc = -EINVAL;
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  347) 		pr_err("match-spec:%s val:%s overridden by %s\n",
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  348) 		       name, *dest, src);
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  349) 	}
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  350) 	*dest = src;
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  351) 	return rc;
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  352) }
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  353) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  354) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  355)  * Parse words[] as a ddebug query specification, which is a series
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  356)  * of (keyword, value) pairs chosen from these possibilities:
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  357)  *
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  358)  * func <function-name>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  359)  * file <full-pathname>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  360)  * file <base-filename>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  361)  * module <module-name>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  362)  * format <escaped-string-to-find-in-format>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  363)  * line <lineno>
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  364)  * line <first-lineno>-<last-lineno> // where either may be empty
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  365)  *
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  366)  * Only 1 of each type is allowed.
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  367)  * Returns 0 on success, <0 on error.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  368)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  369) static int ddebug_parse_query(char *words[], int nwords,
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  370) 			struct ddebug_query *query, const char *modname)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  371) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  372) 	unsigned int i;
bd8c154a62d47 (jbaron@akamai.com  2013-08-27 16:50:03 +0000  373) 	int rc = 0;
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  374) 	char *fline;
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  375) 
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  376) 	/* check we have an even number of words */
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  377) 	if (nwords % 2 != 0) {
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  378) 		pr_err("expecting pairs of match-spec <value>\n");
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  379) 		return -EINVAL;
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  380) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  381) 
7f6e1f3072b68 (Greg Kroah-Hartman 2020-09-10 18:42:38 +0200  382) 	if (modname)
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  383) 		/* support $modname.dyndbg=<multiple queries> */
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  384) 		query->module = modname;
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  385) 
952e934d7f682 (Greg Kroah-Hartman 2020-09-10 18:45:03 +0200  386) 	for (i = 0; i < nwords; i += 2) {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  387) 		char *keyword = words[i];
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  388) 		char *arg = words[i+1];
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  389) 
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  390) 		if (!strcmp(keyword, "func")) {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  391) 			rc = check_set(&query->function, arg, "func");
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  392) 		} else if (!strcmp(keyword, "file")) {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  393) 			if (check_set(&query->filename, arg, "file"))
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  394) 				return -EINVAL;
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  395) 
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  396) 			/* tail :$info is function or line-range */
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  397) 			fline = strchr(query->filename, ':');
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  398) 			if (!fline)
7b1ae248279be (Shuo Chen          2021-04-14 14:24:00 -0700  399) 				continue;
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  400) 			*fline++ = '\0';
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  401) 			if (isalpha(*fline) || *fline == '*' || *fline == '?') {
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  402) 				/* take as function name */
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  403) 				if (check_set(&query->function, fline, "func"))
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  404) 					return -EINVAL;
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  405) 			} else {
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  406) 				if (parse_linerange(query, fline))
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  407) 					return -EINVAL;
aaebe329bff0d (Jim Cromie         2020-07-19 17:10:53 -0600  408) 			}
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  409) 		} else if (!strcmp(keyword, "module")) {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  410) 			rc = check_set(&query->module, arg, "module");
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  411) 		} else if (!strcmp(keyword, "format")) {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  412) 			string_unescape_inplace(arg, UNESCAPE_SPACE |
d338b1379f96b (Andy Shevchenko    2013-04-30 15:27:32 -0700  413) 							    UNESCAPE_OCTAL |
d338b1379f96b (Andy Shevchenko    2013-04-30 15:27:32 -0700  414) 							    UNESCAPE_SPECIAL);
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  415) 			rc = check_set(&query->format, arg, "format");
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  416) 		} else if (!strcmp(keyword, "line")) {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  417) 			if (parse_linerange(query, arg))
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  418) 				return -EINVAL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  419) 		} else {
e5e5fcef600e9 (Jim Cromie         2020-09-21 13:04:33 -0600  420) 			pr_err("unknown keyword \"%s\"\n", keyword);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  421) 			return -EINVAL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  422) 		}
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  423) 		if (rc)
820874c75ea0d (Jim Cromie         2011-12-19 17:12:49 -0500  424) 			return rc;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  425) 	}
574b3725e3275 (Jim Cromie         2011-12-19 17:13:16 -0500  426) 	vpr_info_dq(query, "parsed");
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  427) 	return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  428) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  429) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  430) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  431)  * Parse `str' as a flags specification, format [-+=][p]+.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  432)  * Sets up *maskp and *flagsp to be used when changing the
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  433)  * flags fields of matched _ddebug's.  Returns 0 on success
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  434)  * or <0 on error.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  435)  */
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  436) static int ddebug_parse_flags(const char *str, struct flag_settings *modifiers)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  437) {
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  438) 	int op, i;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  439) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  440) 	switch (*str) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  441) 	case '+':
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  442) 	case '-':
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  443) 	case '=':
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  444) 		op = *str++;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  445) 		break;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  446) 	default:
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  447) 		pr_err("bad flag-op %c, at start of %s\n", *str, str);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  448) 		return -EINVAL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  449) 	}
b8ccd5dee776d (Jim Cromie         2012-04-27 14:30:32 -0600  450) 	vpr_info("op='%c'\n", op);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  451) 
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  452) 	for (; *str ; ++str) {
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  453) 		for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  454) 			if (*str == opt_array[i].opt_char) {
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  455) 				modifiers->flags |= opt_array[i].flag;
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  456) 				break;
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  457) 			}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  458) 		}
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  459) 		if (i < 0) {
0b8f96be9bd41 (Jim Cromie         2020-07-19 17:10:48 -0600  460) 			pr_err("unknown flag '%c'\n", *str);
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  461) 			return -EINVAL;
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  462) 		}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  463) 	}
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  464) 	vpr_info("flags=0x%x\n", modifiers->flags);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  465) 
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  466) 	/* calculate final flags, mask based upon op */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  467) 	switch (op) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  468) 	case '=':
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  469) 		/* modifiers->flags already set */
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  470) 		modifiers->mask = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  471) 		break;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  472) 	case '+':
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  473) 		modifiers->mask = ~0U;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  474) 		break;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  475) 	case '-':
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  476) 		modifiers->mask = ~modifiers->flags;
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  477) 		modifiers->flags = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  478) 		break;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  479) 	}
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  480) 	vpr_info("*flagsp=0x%x *maskp=0x%x\n", modifiers->flags, modifiers->mask);
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  481) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  482) 	return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  483) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  484) 
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  485) static int ddebug_exec_query(char *query_string, const char *modname)
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  486) {
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  487) 	struct flag_settings modifiers = {};
9c9d0acbe2793 (Jim Cromie         2020-07-19 17:10:49 -0600  488) 	struct ddebug_query query = {};
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  489) #define MAXWORDS 9
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  490) 	int nwords, nfound;
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  491) 	char *words[MAXWORDS];
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  492) 
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  493) 	nwords = ddebug_tokenize(query_string, words, MAXWORDS);
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  494) 	if (nwords <= 0) {
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  495) 		pr_err("tokenize failed\n");
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  496) 		return -EINVAL;
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  497) 	}
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  498) 	/* check flags 1st (last arg) so query is pairs of spec,val */
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  499) 	if (ddebug_parse_flags(words[nwords-1], &modifiers)) {
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  500) 		pr_err("flags parse failed\n");
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  501) 		return -EINVAL;
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  502) 	}
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  503) 	if (ddebug_parse_query(words, nwords-1, &query, modname)) {
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  504) 		pr_err("query parse failed\n");
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  505) 		return -EINVAL;
18c216c53b29f (Jim Cromie         2012-12-05 16:48:27 -0500  506) 	}
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  507) 	/* actually go and implement the change */
84da83a6ffc0b (Jim Cromie         2020-07-19 17:10:55 -0600  508) 	nfound = ddebug_change(&query, &modifiers);
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  509) 	vpr_info_dq(&query, nfound ? "applied" : "no-match");
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  510) 
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  511) 	return nfound;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  512) }
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  513) 
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  514) /* handle multiple queries in query string, continue on error, return
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  515)    last error or number of matching callsites.  Module name is either
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  516)    in param (for boot arg) or perhaps in query string.
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  517) */
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  518) static int ddebug_exec_queries(char *query, const char *modname)
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  519) {
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  520) 	char *split;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  521) 	int i, errs = 0, exitcode = 0, rc, nfound = 0;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  522) 
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  523) 	for (i = 0; query; query = split) {
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  524) 		split = strpbrk(query, ";\n");
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  525) 		if (split)
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  526) 			*split++ = '\0';
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  527) 
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  528) 		query = skip_spaces(query);
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  529) 		if (!query || !*query || *query == '#')
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  530) 			continue;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  531) 
b8ccd5dee776d (Jim Cromie         2012-04-27 14:30:32 -0600  532) 		vpr_info("query %d: \"%s\"\n", i, query);
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  533) 
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  534) 		rc = ddebug_exec_query(query, modname);
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  535) 		if (rc < 0) {
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  536) 			errs++;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  537) 			exitcode = rc;
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  538) 		} else {
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  539) 			nfound += rc;
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  540) 		}
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  541) 		i++;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  542) 	}
b8ccd5dee776d (Jim Cromie         2012-04-27 14:30:32 -0600  543) 	vpr_info("processed %d queries, with %d matches, %d errs\n",
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  544) 		 i, nfound, errs);
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  545) 
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  546) 	if (exitcode)
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  547) 		return exitcode;
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  548) 	return nfound;
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  549) }
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  550) 
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  551) /**
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  552)  * dynamic_debug_exec_queries - select and change dynamic-debug prints
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  553)  * @query: query-string described in admin-guide/dynamic-debug-howto
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  554)  * @modname: string containing module name, usually &module.mod_name
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  555)  *
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  556)  * This uses the >/proc/dynamic_debug/control reader, allowing module
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  557)  * authors to modify their dynamic-debug callsites. The modname is
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  558)  * canonically struct module.mod_name, but can also be null or a
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  559)  * module-wildcard, for example: "drm*".
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  560)  */
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  561) int dynamic_debug_exec_queries(const char *query, const char *modname)
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  562) {
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  563) 	int rc;
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  564) 	char *qry; /* writable copy of query */
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  565) 
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  566) 	if (!query) {
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  567) 		pr_err("non-null query/command string expected\n");
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  568) 		return -EINVAL;
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  569) 	}
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  570) 	qry = kstrndup(query, PAGE_SIZE, GFP_KERNEL);
3577afb0052fc (Jim Cromie         2020-12-09 11:36:25 -0700  571) 	if (!qry)
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  572) 		return -ENOMEM;
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  573) 
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  574) 	rc = ddebug_exec_queries(qry, modname);
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  575) 	kfree(qry);
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  576) 	return rc;
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  577) }
a2d375eda771a (Jim Cromie         2020-08-31 12:22:09 -0600  578) EXPORT_SYMBOL_GPL(dynamic_debug_exec_queries);
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  579) 
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  580) #define PREFIX_SIZE 64
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  581) 
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  582) static int remaining(int wrote)
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  583) {
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  584) 	if (PREFIX_SIZE - wrote > 0)
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  585) 		return PREFIX_SIZE - wrote;
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  586) 	return 0;
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  587) }
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  588) 
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  589) static char *__dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  590) {
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  591) 	int pos_after_tid;
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  592) 	int pos = 0;
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  593) 
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  594) 	if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  595) 		if (in_interrupt())
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  596) 			pos += snprintf(buf + pos, remaining(pos), "<intr> ");
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  597) 		else
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  598) 			pos += snprintf(buf + pos, remaining(pos), "[%d] ",
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  599) 					task_pid_vnr(current));
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  600) 	}
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  601) 	pos_after_tid = pos;
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  602) 	if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  603) 		pos += snprintf(buf + pos, remaining(pos), "%s:",
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  604) 				desc->modname);
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  605) 	if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  606) 		pos += snprintf(buf + pos, remaining(pos), "%s:",
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  607) 				desc->function);
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  608) 	if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
07100be7e0495 (Jim Cromie         2011-12-19 17:11:09 -0500  609) 		pos += snprintf(buf + pos, remaining(pos), "%d:",
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  610) 				desc->lineno);
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  611) 	if (pos - pos_after_tid)
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  612) 		pos += snprintf(buf + pos, remaining(pos), " ");
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  613) 	if (pos >= PREFIX_SIZE)
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  614) 		buf[PREFIX_SIZE - 1] = '\0';
6c2140ee0ebf9 (Joe Perches        2011-08-11 14:36:25 -0400  615) 
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  616) 	return buf;
6c2140ee0ebf9 (Joe Perches        2011-08-11 14:36:25 -0400  617) }
6c2140ee0ebf9 (Joe Perches        2011-08-11 14:36:25 -0400  618) 
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  619) static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  620) {
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  621) 	if (unlikely(desc->flags & _DPRINTK_FLAGS_INCL_ANY))
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  622) 		return __dynamic_emit_prefix(desc, buf);
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  623) 	return buf;
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  624) }
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  625) 
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  626) void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  627) {
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  628) 	va_list args;
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  629) 	struct va_format vaf;
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  630) 	char buf[PREFIX_SIZE] = "";
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  631) 
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  632) 	BUG_ON(!descriptor);
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  633) 	BUG_ON(!fmt);
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  634) 
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  635) 	va_start(args, fmt);
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  636) 
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  637) 	vaf.fmt = fmt;
431625dac14de (Jason Baron        2011-10-04 14:13:19 -0700  638) 	vaf.va = &args;
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  639) 
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  640) 	printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  641) 
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  642) 	va_end(args);
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  643) }
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  644) EXPORT_SYMBOL(__dynamic_pr_debug);
8ba6ebf583f12 (Bart Van Assche    2011-01-23 17:17:24 +0100  645) 
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  646) void __dynamic_dev_dbg(struct _ddebug *descriptor,
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  647) 		      const struct device *dev, const char *fmt, ...)
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  648) {
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  649) 	struct va_format vaf;
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  650) 	va_list args;
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  651) 
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  652) 	BUG_ON(!descriptor);
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  653) 	BUG_ON(!fmt);
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  654) 
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  655) 	va_start(args, fmt);
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  656) 
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  657) 	vaf.fmt = fmt;
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  658) 	vaf.va = &args;
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  659) 
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  660) 	if (!dev) {
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  661) 		printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  662) 	} else {
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  663) 		char buf[PREFIX_SIZE] = "";
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  664) 
a39d4a857d4bb (Joe Perches        2014-12-10 15:50:15 -0800  665) 		dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  666) 				dynamic_emit_prefix(descriptor, buf),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  667) 				dev_driver_string(dev), dev_name(dev),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  668) 				&vaf);
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  669) 	}
798efc60e4276 (Joe Perches        2012-09-12 20:11:29 -0700  670) 
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  671) 	va_end(args);
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  672) }
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  673) EXPORT_SYMBOL(__dynamic_dev_dbg);
cbc4663552ee4 (Joe Perches        2011-08-11 14:36:21 -0400  674) 
0feefd97861f9 (Jason Baron        2011-10-04 14:13:22 -0700  675) #ifdef CONFIG_NET
0feefd97861f9 (Jason Baron        2011-10-04 14:13:22 -0700  676) 
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  677) void __dynamic_netdev_dbg(struct _ddebug *descriptor,
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  678) 			  const struct net_device *dev, const char *fmt, ...)
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  679) {
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  680) 	struct va_format vaf;
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  681) 	va_list args;
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  682) 
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  683) 	BUG_ON(!descriptor);
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  684) 	BUG_ON(!fmt);
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  685) 
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  686) 	va_start(args, fmt);
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  687) 
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  688) 	vaf.fmt = fmt;
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  689) 	vaf.va = &args;
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  690) 
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  691) 	if (dev && dev->dev.parent) {
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  692) 		char buf[PREFIX_SIZE] = "";
666f355f3805d (Joe Perches        2012-09-12 20:14:11 -0700  693) 
a39d4a857d4bb (Joe Perches        2014-12-10 15:50:15 -0800  694) 		dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  695) 				"%s%s %s %s%s: %pV",
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  696) 				dynamic_emit_prefix(descriptor, buf),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  697) 				dev_driver_string(dev->dev.parent),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  698) 				dev_name(dev->dev.parent),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  699) 				netdev_name(dev), netdev_reg_state(dev),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  700) 				&vaf);
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  701) 	} else if (dev) {
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  702) 		printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  703) 		       netdev_reg_state(dev), &vaf);
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  704) 	} else {
906d201530f2c (Joe Perches        2014-09-24 11:17:56 -0700  705) 		printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  706) 	}
b004ff4972e2a (Joe Perches        2012-09-12 20:12:19 -0700  707) 
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  708) 	va_end(args);
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  709) }
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  710) EXPORT_SYMBOL(__dynamic_netdev_dbg);
ffa10cb47a94c (Jason Baron        2011-08-11 14:36:48 -0400  711) 
0feefd97861f9 (Jason Baron        2011-10-04 14:13:22 -0700  712) #endif
0feefd97861f9 (Jason Baron        2011-10-04 14:13:22 -0700  713) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  714) #if IS_ENABLED(CONFIG_INFINIBAND)
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  715) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  716) void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  717) 			 const struct ib_device *ibdev, const char *fmt, ...)
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  718) {
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  719) 	struct va_format vaf;
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  720) 	va_list args;
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  721) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  722) 	va_start(args, fmt);
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  723) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  724) 	vaf.fmt = fmt;
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  725) 	vaf.va = &args;
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  726) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  727) 	if (ibdev && ibdev->dev.parent) {
640d1eaff2c09 (Jim Cromie         2021-05-04 16:22:34 -0600  728) 		char buf[PREFIX_SIZE] = "";
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  729) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  730) 		dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  731) 				"%s%s %s %s: %pV",
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  732) 				dynamic_emit_prefix(descriptor, buf),
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  733) 				dev_driver_string(ibdev->dev.parent),
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  734) 				dev_name(ibdev->dev.parent),
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  735) 				dev_name(&ibdev->dev),
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  736) 				&vaf);
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  737) 	} else if (ibdev) {
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  738) 		printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  739) 	} else {
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  740) 		printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  741) 	}
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  742) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  743) 	va_end(args);
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  744) }
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  745) EXPORT_SYMBOL(__dynamic_ibdev_dbg);
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  746) 
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  747) #endif
923abb9d797ba (Gal Pressman       2019-05-01 13:48:13 +0300  748) 
bc757f6f5bf4e (Jim Cromie         2011-12-19 17:12:29 -0500  749) #define DDEBUG_STRING_SIZE 1024
bc757f6f5bf4e (Jim Cromie         2011-12-19 17:12:29 -0500  750) static __initdata char ddebug_setup_string[DDEBUG_STRING_SIZE];
bc757f6f5bf4e (Jim Cromie         2011-12-19 17:12:29 -0500  751) 
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  752) static __init int ddebug_setup_query(char *str)
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  753) {
bc757f6f5bf4e (Jim Cromie         2011-12-19 17:12:29 -0500  754) 	if (strlen(str) >= DDEBUG_STRING_SIZE) {
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400  755) 		pr_warn("ddebug boot param string too large\n");
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  756) 		return 0;
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  757) 	}
bc757f6f5bf4e (Jim Cromie         2011-12-19 17:12:29 -0500  758) 	strlcpy(ddebug_setup_string, str, DDEBUG_STRING_SIZE);
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  759) 	return 1;
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  760) }
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  761) 
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  762) __setup("ddebug_query=", ddebug_setup_query);
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200  763) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  764) /*
231821d4c3fa7 (Masatake YAMATO    2014-12-15 12:04:16 +0900  765)  * File_ops->write method for <debugfs>/dynamic_debug/control.  Gathers the
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  766)  * command text from userspace, parses and executes it.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  767)  */
7281491c594e7 (Jim Cromie         2011-12-19 17:13:07 -0500  768) #define USER_BUF_PAGE 4096
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  769) static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  770) 				  size_t len, loff_t *offp)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  771) {
7281491c594e7 (Jim Cromie         2011-12-19 17:13:07 -0500  772) 	char *tmpbuf;
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  773) 	int ret;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  774) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  775) 	if (len == 0)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  776) 		return 0;
7281491c594e7 (Jim Cromie         2011-12-19 17:13:07 -0500  777) 	if (len > USER_BUF_PAGE - 1) {
7281491c594e7 (Jim Cromie         2011-12-19 17:13:07 -0500  778) 		pr_warn("expected <%d bytes into control\n", USER_BUF_PAGE);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  779) 		return -E2BIG;
7281491c594e7 (Jim Cromie         2011-12-19 17:13:07 -0500  780) 	}
16e5c1fc36040 (Al Viro            2015-12-24 00:06:05 -0500  781) 	tmpbuf = memdup_user_nul(ubuf, len);
16e5c1fc36040 (Al Viro            2015-12-24 00:06:05 -0500  782) 	if (IS_ERR(tmpbuf))
16e5c1fc36040 (Al Viro            2015-12-24 00:06:05 -0500  783) 		return PTR_ERR(tmpbuf);
b8ccd5dee776d (Jim Cromie         2012-04-27 14:30:32 -0600  784) 	vpr_info("read %d bytes from userspace\n", (int)len);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  785) 
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  786) 	ret = ddebug_exec_queries(tmpbuf, NULL);
7281491c594e7 (Jim Cromie         2011-12-19 17:13:07 -0500  787) 	kfree(tmpbuf);
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500  788) 	if (ret < 0)
fd89cfb871875 (Thomas Renninger   2010-08-06 16:11:01 +0200  789) 		return ret;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  790) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  791) 	*offp += len;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  792) 	return len;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  793) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  794) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  795) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  796)  * Set the iterator to point to the first _ddebug object
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  797)  * and return a pointer to that first object.  Returns
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  798)  * NULL if there are no _ddebugs at all.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  799)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  800) static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  801) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  802) 	if (list_empty(&ddebug_tables)) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  803) 		iter->table = NULL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  804) 		iter->idx = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  805) 		return NULL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  806) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  807) 	iter->table = list_entry(ddebug_tables.next,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  808) 				 struct ddebug_table, link);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  809) 	iter->idx = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  810) 	return &iter->table->ddebugs[iter->idx];
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  811) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  812) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  813) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  814)  * Advance the iterator to point to the next _ddebug
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  815)  * object from the one the iterator currently points at,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  816)  * and returns a pointer to the new _ddebug.  Returns
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  817)  * NULL if the iterator has seen all the _ddebugs.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  818)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  819) static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  820) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  821) 	if (iter->table == NULL)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  822) 		return NULL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  823) 	if (++iter->idx == iter->table->num_ddebugs) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  824) 		/* iterate to next table */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  825) 		iter->idx = 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  826) 		if (list_is_last(&iter->table->link, &ddebug_tables)) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  827) 			iter->table = NULL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  828) 			return NULL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  829) 		}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  830) 		iter->table = list_entry(iter->table->link.next,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  831) 					 struct ddebug_table, link);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  832) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  833) 	return &iter->table->ddebugs[iter->idx];
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  834) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  835) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  836) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  837)  * Seq_ops start method.  Called at the start of every
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  838)  * read() call from userspace.  Takes the ddebug_lock and
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  839)  * seeks the seq_file's iterator to the given position.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  840)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  841) static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  842) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  843) 	struct ddebug_iter *iter = m->private;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  844) 	struct _ddebug *dp;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  845) 	int n = *pos;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  846) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  847) 	mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  848) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  849) 	if (!n)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  850) 		return SEQ_START_TOKEN;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  851) 	if (n < 0)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  852) 		return NULL;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  853) 	dp = ddebug_iter_first(iter);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  854) 	while (dp != NULL && --n > 0)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  855) 		dp = ddebug_iter_next(iter);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  856) 	return dp;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  857) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  858) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  859) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  860)  * Seq_ops next method.  Called several times within a read()
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  861)  * call from userspace, with ddebug_lock held.  Walks to the
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  862)  * next _ddebug object with a special case for the header line.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  863)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  864) static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  865) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  866) 	struct ddebug_iter *iter = m->private;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  867) 	struct _ddebug *dp;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  868) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  869) 	if (p == SEQ_START_TOKEN)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  870) 		dp = ddebug_iter_first(iter);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  871) 	else
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  872) 		dp = ddebug_iter_next(iter);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  873) 	++*pos;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  874) 	return dp;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  875) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  876) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  877) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  878)  * Seq_ops show method.  Called several times within a read()
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  879)  * call from userspace, with ddebug_lock held.  Formats the
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  880)  * current _ddebug as a single human-readable line, with a
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  881)  * special case for the header line.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  882)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  883) static int ddebug_proc_show(struct seq_file *m, void *p)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  884) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  885) 	struct ddebug_iter *iter = m->private;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  886) 	struct _ddebug *dp = p;
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  887) 	struct flagsbuf flags;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  888) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  889) 	if (p == SEQ_START_TOKEN) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  890) 		seq_puts(m,
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  891) 			 "# filename:lineno [module]function flags format\n");
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  892) 		return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  893) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  894) 
5ca7d2a6c5e4f (Jim Cromie         2011-12-19 17:12:44 -0500  895) 	seq_printf(m, "%s:%u [%s]%s =%s \"",
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  896) 		   trim_prefix(dp->filename), dp->lineno,
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500  897) 		   iter->table->mod_name, dp->function,
f678ce8cc3cb2 (Jim Cromie         2020-07-19 17:10:47 -0600  898) 		   ddebug_describe_flags(dp->flags, &flags));
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  899) 	seq_escape(m, dp->format, "\t\r\n\"");
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  900) 	seq_puts(m, "\"\n");
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  901) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  902) 	return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  903) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  904) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  905) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  906)  * Seq_ops stop method.  Called at the end of each read()
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  907)  * call from userspace.  Drops ddebug_lock.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  908)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  909) static void ddebug_proc_stop(struct seq_file *m, void *p)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  910) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  911) 	mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  912) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  913) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  914) static const struct seq_operations ddebug_proc_seqops = {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  915) 	.start = ddebug_proc_start,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  916) 	.next = ddebug_proc_next,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  917) 	.show = ddebug_proc_show,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  918) 	.stop = ddebug_proc_stop
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  919) };
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  920) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  921) static int ddebug_proc_open(struct inode *inode, struct file *file)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  922) {
4bad78c550025 (Rob Jones          2014-10-13 15:51:32 -0700  923) 	return seq_open_private(file, &ddebug_proc_seqops,
4bad78c550025 (Rob Jones          2014-10-13 15:51:32 -0700  924) 				sizeof(struct ddebug_iter));
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  925) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  926) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  927) static const struct file_operations ddebug_proc_fops = {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  928) 	.owner = THIS_MODULE,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  929) 	.open = ddebug_proc_open,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  930) 	.read = seq_read,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  931) 	.llseek = seq_lseek,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  932) 	.release = seq_release_private,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  933) 	.write = ddebug_proc_write
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  934) };
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  935) 
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  936) static const struct proc_ops proc_fops = {
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  937) 	.proc_open = ddebug_proc_open,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  938) 	.proc_read = seq_read,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  939) 	.proc_lseek = seq_lseek,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  940) 	.proc_release = seq_release_private,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  941) 	.proc_write = ddebug_proc_write
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  942) };
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800  943) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  944) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  945)  * Allocate a new ddebug_table for the given module
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  946)  * and add it to the global list.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  947)  */
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  948) int ddebug_add_module(struct _ddebug *tab, unsigned int n,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  949) 			     const char *name)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  950) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  951) 	struct ddebug_table *dt;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  952) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  953) 	dt = kzalloc(sizeof(*dt), GFP_KERNEL);
513770f54edba (Rasmus Villemoes   2019-03-07 16:27:48 -0800  954) 	if (dt == NULL) {
513770f54edba (Rasmus Villemoes   2019-03-07 16:27:48 -0800  955) 		pr_err("error adding module: %s\n", name);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  956) 		return -ENOMEM;
513770f54edba (Rasmus Villemoes   2019-03-07 16:27:48 -0800  957) 	}
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  958) 	/*
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  959) 	 * For built-in modules, name lives in .rodata and is
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  960) 	 * immortal. For loaded modules, name points at the name[]
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  961) 	 * member of struct module, which lives at least as long as
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  962) 	 * this struct ddebug_table.
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  963) 	 */
cdf6d00696865 (Rasmus Villemoes   2019-03-07 16:27:37 -0800  964) 	dt->mod_name = name;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  965) 	dt->num_ddebugs = n;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  966) 	dt->ddebugs = tab;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  967) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  968) 	mutex_lock(&ddebug_lock);
47e9f5a823296 (Jim Cromie         2020-07-19 17:10:50 -0600  969) 	list_add(&dt->link, &ddebug_tables);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  970) 	mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  971) 
b52a95eac112f (Jim Cromie         2020-08-31 12:22:08 -0600  972) 	v2pr_info("%3u debug prints in module %s\n", n, dt->mod_name);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  973) 	return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  974) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500  975) 
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  976) /* helper for ddebug_dyndbg_(boot|module)_param_cb */
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  977) static int ddebug_dyndbg_param_cb(char *param, char *val,
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  978) 				const char *modname, int on_err)
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  979) {
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  980) 	char *sep;
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  981) 
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  982) 	sep = strchr(param, '.');
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  983) 	if (sep) {
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  984) 		/* needed only for ddebug_dyndbg_boot_param_cb */
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  985) 		*sep = '\0';
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  986) 		modname = param;
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  987) 		param = sep + 1;
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  988) 	}
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  989) 	if (strcmp(param, "dyndbg"))
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  990) 		return on_err; /* determined by caller */
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  991) 
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  992) 	ddebug_exec_queries((val ? val : "+p"), modname);
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600  993) 
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  994) 	return 0; /* query failure shouldnt stop module load */
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  995) }
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600  996) 
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  997) /* handle both dyndbg and $module.dyndbg params at boot */
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600  998) static int ddebug_dyndbg_boot_param_cb(char *param, char *val,
ecc8617053e0a (Luis R. Rodriguez  2015-03-30 16:20:03 -0700  999) 				const char *unused, void *arg)
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1000) {
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1001) 	vpr_info("%s=\"%s\"\n", param, val);
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1002) 	return ddebug_dyndbg_param_cb(param, val, NULL, 0);
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1003) }
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1004) 
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1005) /*
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1006)  * modprobe foo finds foo.params in boot-args, strips "foo.", and
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1007)  * passes them to load_module().  This callback gets unknown params,
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1008)  * processes dyndbg params, rejects others.
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1009)  */
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1010) int ddebug_dyndbg_module_param_cb(char *param, char *val, const char *module)
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1011) {
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1012) 	vpr_info("module: %s %s=\"%s\"\n", module, param, val);
6ab676e96422f (Jim Cromie         2012-04-27 14:30:37 -0600 1013) 	return ddebug_dyndbg_param_cb(param, val, module, -ENOENT);
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1014) }
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1015) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1016) static void ddebug_table_free(struct ddebug_table *dt)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1017) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1018) 	list_del_init(&dt->link);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1019) 	kfree(dt);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1020) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1021) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1022) /*
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1023)  * Called in response to a module being unloaded.  Removes
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1024)  * any ddebug_table's which point at the module.
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1025)  */
ff49d74ad383f (Yehuda Sadeh       2010-07-03 13:07:35 +1000 1026) int ddebug_remove_module(const char *mod_name)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1027) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1028) 	struct ddebug_table *dt, *nextdt;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1029) 	int ret = -ENOENT;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1030) 
481c0e33f1e71 (Jim Cromie         2020-07-19 17:10:44 -0600 1031) 	v2pr_info("removing module \"%s\"\n", mod_name);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1032) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1033) 	mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1034) 	list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
4573fe15437c9 (Rasmus Villemoes   2019-03-07 16:27:41 -0800 1035) 		if (dt->mod_name == mod_name) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1036) 			ddebug_table_free(dt);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1037) 			ret = 0;
4573fe15437c9 (Rasmus Villemoes   2019-03-07 16:27:41 -0800 1038) 			break;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1039) 		}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1040) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1041) 	mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1042) 	return ret;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1043) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1044) 
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1045) static void ddebug_remove_all_tables(void)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1046) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1047) 	mutex_lock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1048) 	while (!list_empty(&ddebug_tables)) {
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1049) 		struct ddebug_table *dt = list_entry(ddebug_tables.next,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1050) 						      struct ddebug_table,
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1051) 						      link);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1052) 		ddebug_table_free(dt);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1053) 	}
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1054) 	mutex_unlock(&ddebug_lock);
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1055) }
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1056) 
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1057) static __initdata int ddebug_init_success;
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1058) 
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1059) static int __init dynamic_debug_init_control(void)
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1060) {
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1061) 	struct proc_dir_entry *procfs_dir;
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1062) 	struct dentry *debugfs_dir;
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1063) 
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1064) 	if (!ddebug_init_success)
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1065) 		return -ENODEV;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1066) 
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1067) 	/* Create the control file in debugfs if it is enabled */
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1068) 	if (debugfs_initialized()) {
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1069) 		debugfs_dir = debugfs_create_dir("dynamic_debug", NULL);
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1070) 		debugfs_create_file("control", 0644, debugfs_dir, NULL,
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1071) 				    &ddebug_proc_fops);
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1072) 	}
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1073) 
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1074) 	/* Also create the control file in procfs */
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1075) 	procfs_dir = proc_mkdir("dynamic_debug", NULL);
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1076) 	if (procfs_dir)
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1077) 		proc_create("control", 0644, procfs_dir, &proc_fops);
9fd714cd7f467 (Greg Kroah-Hartman 2019-06-12 17:35:34 +0200 1078) 
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1079) 	return 0;
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1080) }
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1081) 
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1082) static int __init dynamic_debug_init(void)
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1083) {
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1084) 	struct _ddebug *iter, *iter_start;
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1085) 	const char *modname = NULL;
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1086) 	char *cmdline;
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1087) 	int ret = 0;
4107692760db8 (Jim Cromie         2012-04-27 14:30:39 -0600 1088) 	int n = 0, entries = 0, modct = 0;
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1089) 
e5ebffe18e5ad (Jim Cromie         2020-07-19 17:10:45 -0600 1090) 	if (&__start___dyndbg == &__stop___dyndbg) {
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1091) 		if (IS_ENABLED(CONFIG_DYNAMIC_DEBUG)) {
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1092) 			pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n");
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1093) 			return 1;
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1094) 		}
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1095) 		pr_info("Ignore empty _ddebug table in a CONFIG_DYNAMIC_DEBUG_CORE build\n");
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1096) 		ddebug_init_success = 1;
ceabef7dd7172 (Orson Zhai         2020-06-07 21:40:14 -0700 1097) 		return 0;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1098) 	}
e5ebffe18e5ad (Jim Cromie         2020-07-19 17:10:45 -0600 1099) 	iter = __start___dyndbg;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1100) 	modname = iter->modname;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1101) 	iter_start = iter;
e5ebffe18e5ad (Jim Cromie         2020-07-19 17:10:45 -0600 1102) 	for (; iter < __stop___dyndbg; iter++) {
4107692760db8 (Jim Cromie         2012-04-27 14:30:39 -0600 1103) 		entries++;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1104) 		if (strcmp(modname, iter->modname)) {
4107692760db8 (Jim Cromie         2012-04-27 14:30:39 -0600 1105) 			modct++;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1106) 			ret = ddebug_add_module(iter_start, n, modname);
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1107) 			if (ret)
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1108) 				goto out_err;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1109) 			n = 0;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1110) 			modname = iter->modname;
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1111) 			iter_start = iter;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1112) 		}
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1113) 		n++;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1114) 	}
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1115) 	ret = ddebug_add_module(iter_start, n, modname);
b5b78f83854af (Jim Cromie         2011-12-19 17:12:54 -0500 1116) 	if (ret)
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1117) 		goto out_err;
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200 1118) 
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1119) 	ddebug_init_success = 1;
81d0c2c60942c (Jim Cromie         2020-07-19 17:10:46 -0600 1120) 	vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in __dyndbg section\n",
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500 1121) 		 modct, entries, (int)(modct * sizeof(struct ddebug_table)),
81d0c2c60942c (Jim Cromie         2020-07-19 17:10:46 -0600 1122) 		 (int)(entries * sizeof(struct _ddebug)));
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1123) 
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1124) 	/* apply ddebug_query boot param, dont unload tables on err */
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200 1125) 	if (ddebug_setup_string[0] != '\0') {
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500 1126) 		pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n");
8e59b5cfb9a6f (Jim Cromie         2012-04-27 14:30:40 -0600 1127) 		ret = ddebug_exec_queries(ddebug_setup_string, NULL);
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500 1128) 		if (ret < 0)
f657fd21e16e3 (Joe Perches        2012-12-05 16:48:26 -0500 1129) 			pr_warn("Invalid ddebug boot param %s\n",
4ad275e5cb576 (Joe Perches        2011-08-11 14:36:33 -0400 1130) 				ddebug_setup_string);
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200 1131) 		else
85f7f6c0edb84 (Jim Cromie         2011-12-19 17:13:21 -0500 1132) 			pr_info("%d changes by ddebug_query\n", ret);
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200 1133) 	}
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1134) 	/* now that ddebug tables are loaded, process all boot args
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1135) 	 * again to find and activate queries given in dyndbg params.
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1136) 	 * While this has already been done for known boot params, it
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1137) 	 * ignored the unknown ones (dyndbg in particular).  Reusing
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1138) 	 * parse_args avoids ad-hoc parsing.  This will also attempt
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1139) 	 * to activate queries for not-yet-loaded modules, which is
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1140) 	 * slightly noisy if verbose, but harmless.
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1141) 	 */
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1142) 	cmdline = kstrdup(saved_command_line, GFP_KERNEL);
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1143) 	parse_args("dyndbg params", cmdline, NULL,
ecc8617053e0a (Luis R. Rodriguez  2015-03-30 16:20:03 -0700 1144) 		   0, 0, 0, NULL, &ddebug_dyndbg_boot_param_cb);
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1145) 	kfree(cmdline);
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1146) 	return 0;
a648ec05bb950 (Thomas Renninger   2010-08-06 16:11:02 +0200 1147) 
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1148) out_err:
af442399fcf37 (Jim Cromie         2012-04-27 14:30:38 -0600 1149) 	ddebug_remove_all_tables();
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1150) 	return 0;
e9d376f0fa66b (Jason Baron        2009-02-05 11:51:38 -0500 1151) }
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1152) /* Allow early initialization for boot messages via boot param */
3ec5652ab70f6 (Jim Cromie         2012-04-27 14:30:42 -0600 1153) early_initcall(dynamic_debug_init);
b48420c1d3019 (Jim Cromie         2012-04-27 14:30:35 -0600 1154) 
6a5c083de2f5f (Thomas Renninger   2010-08-06 16:11:03 +0200 1155) /* Debugfs setup must be done later */
239a5791ffd55 (Greg Kroah-Hartman 2020-02-10 13:11:42 -0800 1156) fs_initcall(dynamic_debug_init_control);