• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  *   S/390 debug facility
4  *
5  *    Copyright IBM Corp. 1999, 2020
6  */
7 #ifndef _ASM_S390_DEBUG_H
8 #define _ASM_S390_DEBUG_H
9 
10 #include <linux/string.h>
11 #include <linux/spinlock.h>
12 #include <linux/kernel.h>
13 #include <linux/time.h>
14 #include <linux/refcount.h>
15 #include <linux/fs.h>
16 
17 #define DEBUG_MAX_LEVEL		   6  /* debug levels range from 0 to 6 */
18 #define DEBUG_OFF_LEVEL		   -1 /* level where debug is switched off */
19 #define DEBUG_FLUSH_ALL		   -1 /* parameter to flush all areas */
20 #define DEBUG_MAX_VIEWS		   10 /* max number of views in proc fs */
21 #define DEBUG_MAX_NAME_LEN	   64 /* max length for a debugfs file name */
22 #define DEBUG_DEFAULT_LEVEL	   3  /* initial debug level */
23 
24 #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */
25 
26 #define DEBUG_DATA(entry) (char *)(entry + 1) /* data is stored behind */
27 					      /* the entry information */
28 
29 #define __DEBUG_FEATURE_VERSION	   3  /* version of debug feature */
30 
31 struct __debug_entry {
32 	unsigned long clock	: 60;
33 	unsigned long exception	:  1;
34 	unsigned long level	:  3;
35 	void *caller;
36 	unsigned short cpu;
37 } __packed;
38 
39 typedef struct __debug_entry debug_entry_t;
40 
41 struct debug_view;
42 
43 typedef struct debug_info {
44 	struct debug_info *next;
45 	struct debug_info *prev;
46 	refcount_t ref_count;
47 	spinlock_t lock;
48 	int level;
49 	int nr_areas;
50 	int pages_per_area;
51 	int buf_size;
52 	int entry_size;
53 	debug_entry_t ***areas;
54 	int active_area;
55 	int *active_pages;
56 	int *active_entries;
57 	struct dentry *debugfs_root_entry;
58 	struct dentry *debugfs_entries[DEBUG_MAX_VIEWS];
59 	struct debug_view *views[DEBUG_MAX_VIEWS];
60 	char name[DEBUG_MAX_NAME_LEN];
61 	umode_t mode;
62 } debug_info_t;
63 
64 typedef int (debug_header_proc_t) (debug_info_t *id,
65 				   struct debug_view *view,
66 				   int area,
67 				   debug_entry_t *entry,
68 				   char *out_buf);
69 
70 typedef int (debug_format_proc_t) (debug_info_t *id,
71 				   struct debug_view *view, char *out_buf,
72 				   const char *in_buf);
73 typedef int (debug_prolog_proc_t) (debug_info_t *id,
74 				   struct debug_view *view,
75 				   char *out_buf);
76 typedef int (debug_input_proc_t) (debug_info_t *id,
77 				  struct debug_view *view,
78 				  struct file *file,
79 				  const char __user *user_buf,
80 				  size_t in_buf_size, loff_t *offset);
81 
82 int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
83 			 int area, debug_entry_t *entry, char *out_buf);
84 
85 struct debug_view {
86 	char name[DEBUG_MAX_NAME_LEN];
87 	debug_prolog_proc_t *prolog_proc;
88 	debug_header_proc_t *header_proc;
89 	debug_format_proc_t *format_proc;
90 	debug_input_proc_t  *input_proc;
91 	void		    *private_data;
92 };
93 
94 extern struct debug_view debug_hex_ascii_view;
95 extern struct debug_view debug_sprintf_view;
96 
97 /* do NOT use the _common functions */
98 
99 debug_entry_t *debug_event_common(debug_info_t *id, int level,
100 				  const void *data, int length);
101 
102 debug_entry_t *debug_exception_common(debug_info_t *id, int level,
103 				      const void *data, int length);
104 
105 /* Debug Feature API: */
106 
107 debug_info_t *debug_register(const char *name, int pages, int nr_areas,
108 			     int buf_size);
109 
110 debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas,
111 				  int buf_size, umode_t mode, uid_t uid,
112 				  gid_t gid);
113 
114 void debug_unregister(debug_info_t *id);
115 
116 void debug_set_level(debug_info_t *id, int new_level);
117 
118 void debug_set_critical(void);
119 
120 void debug_stop_all(void);
121 
122 /**
123  * debug_level_enabled() - Returns true if debug events for the specified
124  *			   level would be logged. Otherwise returns false.
125  *
126  * @id:		handle for debug log
127  * @level:	debug level
128  *
129  * Return:
130  * - %true if level is less or equal to the current debug level.
131  */
debug_level_enabled(debug_info_t * id,int level)132 static inline bool debug_level_enabled(debug_info_t *id, int level)
133 {
134 	return level <= id->level;
135 }
136 
137 /**
138  * debug_event() - writes binary debug entry to active debug area
139  *		   (if level <= actual debug level)
140  *
141  * @id:		handle for debug log
142  * @level:	debug level
143  * @data:	pointer to data for debug entry
144  * @length:	length of data in bytes
145  *
146  * Return:
147  * - Address of written debug entry
148  * - %NULL if error
149  */
debug_event(debug_info_t * id,int level,void * data,int length)150 static inline debug_entry_t *debug_event(debug_info_t *id, int level,
151 					 void *data, int length)
152 {
153 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
154 		return NULL;
155 	return debug_event_common(id, level, data, length);
156 }
157 
158 /**
159  * debug_int_event() - writes unsigned integer debug entry to active debug area
160  *		       (if level <= actual debug level)
161  *
162  * @id:		handle for debug log
163  * @level:	debug level
164  * @tag:	integer value for debug entry
165  *
166  * Return:
167  * - Address of written debug entry
168  * - %NULL if error
169  */
debug_int_event(debug_info_t * id,int level,unsigned int tag)170 static inline debug_entry_t *debug_int_event(debug_info_t *id, int level,
171 					     unsigned int tag)
172 {
173 	unsigned int t = tag;
174 
175 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
176 		return NULL;
177 	return debug_event_common(id, level, &t, sizeof(unsigned int));
178 }
179 
180 /**
181  * debug_long_event() - writes unsigned long debug entry to active debug area
182  *		       (if level <= actual debug level)
183  *
184  * @id:		handle for debug log
185  * @level:	debug level
186  * @tag:	long integer value for debug entry
187  *
188  * Return:
189  * - Address of written debug entry
190  * - %NULL if error
191  */
debug_long_event(debug_info_t * id,int level,unsigned long tag)192 static inline debug_entry_t *debug_long_event(debug_info_t *id, int level,
193 					      unsigned long tag)
194 {
195 	unsigned long t = tag;
196 
197 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
198 		return NULL;
199 	return debug_event_common(id, level, &t, sizeof(unsigned long));
200 }
201 
202 /**
203  * debug_text_event() - writes string debug entry in ascii format to active
204  *			debug area (if level <= actual debug level)
205  *
206  * @id:		handle for debug log
207  * @level:	debug level
208  * @txt:	string for debug entry
209  *
210  * Return:
211  * - Address of written debug entry
212  * - %NULL if error
213  */
debug_text_event(debug_info_t * id,int level,const char * txt)214 static inline debug_entry_t *debug_text_event(debug_info_t *id, int level,
215 					      const char *txt)
216 {
217 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
218 		return NULL;
219 	return debug_event_common(id, level, txt, strlen(txt));
220 }
221 
222 /*
223  * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
224  * stored in the s390dbf. See Documentation/s390/s390dbf.rst for more details!
225  */
226 extern debug_entry_t *
227 __debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
228 	__attribute__ ((format(printf, 3, 4)));
229 
230 /**
231  * debug_sprintf_event() - writes debug entry with format string
232  *			   and varargs (longs) to active debug area
233  *			   (if level $<=$ actual debug level).
234  *
235  * @_id:	handle for debug log
236  * @_level:	debug level
237  * @_fmt:	format string for debug entry
238  * @...:	varargs used as in sprintf()
239  *
240  * Return:
241  * - Address of written debug entry
242  * - %NULL if error
243  *
244  * floats and long long datatypes cannot be used as varargs.
245  */
246 #define debug_sprintf_event(_id, _level, _fmt, ...)			\
247 ({									\
248 	debug_entry_t *__ret;						\
249 	debug_info_t *__id = _id;					\
250 	int __level = _level;						\
251 									\
252 	if ((!__id) || (__level > __id->level))				\
253 		__ret = NULL;						\
254 	else								\
255 		__ret = __debug_sprintf_event(__id, __level,		\
256 					      _fmt, ## __VA_ARGS__);	\
257 	__ret;								\
258 })
259 
260 /**
261  * debug_exception() - writes binary debug entry to active debug area
262  *		       (if level <= actual debug level)
263  *		       and switches to next debug area
264  *
265  * @id:		handle for debug log
266  * @level:	debug level
267  * @data:	pointer to data for debug entry
268  * @length:	length of data in bytes
269  *
270  * Return:
271  * - Address of written debug entry
272  * - %NULL if error
273  */
debug_exception(debug_info_t * id,int level,void * data,int length)274 static inline debug_entry_t *debug_exception(debug_info_t *id, int level,
275 					     void *data, int length)
276 {
277 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
278 		return NULL;
279 	return debug_exception_common(id, level, data, length);
280 }
281 
282 /**
283  * debug_int_exception() - writes unsigned int debug entry to active debug area
284  *			   (if level <= actual debug level)
285  *			   and switches to next debug area
286  *
287  * @id:		handle for debug log
288  * @level:	debug level
289  * @tag:	integer value for debug entry
290  *
291  * Return:
292  * - Address of written debug entry
293  * - %NULL if error
294  */
debug_int_exception(debug_info_t * id,int level,unsigned int tag)295 static inline debug_entry_t *debug_int_exception(debug_info_t *id, int level,
296 						 unsigned int tag)
297 {
298 	unsigned int t = tag;
299 
300 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
301 		return NULL;
302 	return debug_exception_common(id, level, &t, sizeof(unsigned int));
303 }
304 
305 /**
306  * debug_long_exception() - writes long debug entry to active debug area
307  *			   (if level <= actual debug level)
308  *			   and switches to next debug area
309  *
310  * @id:		handle for debug log
311  * @level:	debug level
312  * @tag:	long integer value for debug entry
313  *
314  * Return:
315  * - Address of written debug entry
316  * - %NULL if error
317  */
debug_long_exception(debug_info_t * id,int level,unsigned long tag)318 static inline debug_entry_t *debug_long_exception (debug_info_t *id, int level,
319 						   unsigned long tag)
320 {
321 	unsigned long t = tag;
322 
323 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
324 		return NULL;
325 	return debug_exception_common(id, level, &t, sizeof(unsigned long));
326 }
327 
328 /**
329  * debug_text_exception() - writes string debug entry in ascii format to active
330  *			    debug area (if level <= actual debug level)
331  *			    and switches to next debug area
332  * area
333  *
334  * @id:	handle for debug log
335  * @level:	debug level
336  * @txt:	string for debug entry
337  *
338  * Return:
339  * - Address of written debug entry
340  * - %NULL if error
341  */
debug_text_exception(debug_info_t * id,int level,const char * txt)342 static inline debug_entry_t *debug_text_exception(debug_info_t *id, int level,
343 						  const char *txt)
344 {
345 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
346 		return NULL;
347 	return debug_exception_common(id, level, txt, strlen(txt));
348 }
349 
350 /*
351  * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
352  * stored in the s390dbf. See Documentation/s390/s390dbf.rst for more details!
353  */
354 extern debug_entry_t *
355 __debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
356 	__attribute__ ((format(printf, 3, 4)));
357 
358 
359 /**
360  * debug_sprintf_exception() - writes debug entry with format string and
361  *			       varargs (longs) to active debug area
362  *			       (if level <= actual debug level)
363  *			       and switches to next debug area.
364  *
365  * @_id:	handle for debug log
366  * @_level:	debug level
367  * @_fmt:	format string for debug entry
368  * @...:	varargs used as in sprintf()
369  *
370  * Return:
371  * - Address of written debug entry
372  * - %NULL if error
373  *
374  * floats and long long datatypes cannot be used as varargs.
375  */
376 #define debug_sprintf_exception(_id, _level, _fmt, ...)			\
377 ({									\
378 	debug_entry_t *__ret;						\
379 	debug_info_t *__id = _id;					\
380 	int __level = _level;						\
381 									\
382 	if ((!__id) || (__level > __id->level))				\
383 		__ret = NULL;						\
384 	else								\
385 		__ret = __debug_sprintf_exception(__id, __level,	\
386 						  _fmt, ## __VA_ARGS__);\
387 	__ret;								\
388 })
389 
390 int debug_register_view(debug_info_t *id, struct debug_view *view);
391 
392 int debug_unregister_view(debug_info_t *id, struct debug_view *view);
393 
394 /*
395    define the debug levels:
396    - 0 No debugging output to console or syslog
397    - 1 Log internal errors to syslog, ignore check conditions
398    - 2 Log internal errors and check conditions to syslog
399    - 3 Log internal errors to console, log check conditions to syslog
400    - 4 Log internal errors and check conditions to console
401    - 5 panic on internal errors, log check conditions to console
402    - 6 panic on both, internal errors and check conditions
403  */
404 
405 #ifndef DEBUG_LEVEL
406 #define DEBUG_LEVEL 4
407 #endif
408 
409 #define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y
410 #define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y
411 #define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y
412 #define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y
413 
414 #if DEBUG_LEVEL > 0
415 #define PRINT_DEBUG(x...)	printk(KERN_DEBUG PRINTK_HEADER x)
416 #define PRINT_INFO(x...)	printk(KERN_INFO PRINTK_HEADER x)
417 #define PRINT_WARN(x...)	printk(KERN_WARNING PRINTK_HEADER x)
418 #define PRINT_ERR(x...)		printk(KERN_ERR PRINTK_HEADER x)
419 #define PRINT_FATAL(x...)	panic(PRINTK_HEADER x)
420 #else
421 #define PRINT_DEBUG(x...)	printk(KERN_DEBUG PRINTK_HEADER x)
422 #define PRINT_INFO(x...)	printk(KERN_DEBUG PRINTK_HEADER x)
423 #define PRINT_WARN(x...)	printk(KERN_DEBUG PRINTK_HEADER x)
424 #define PRINT_ERR(x...)		printk(KERN_DEBUG PRINTK_HEADER x)
425 #define PRINT_FATAL(x...)	printk(KERN_DEBUG PRINTK_HEADER x)
426 #endif /* DASD_DEBUG */
427 
428 #endif /* _ASM_S390_DEBUG_H */
429