Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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