xref: /openbmc/linux/arch/s390/include/asm/debug.h (revision 37002bc6)
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 #include <linux/init.h>
17 
18 #define DEBUG_MAX_LEVEL		   6  /* debug levels range from 0 to 6 */
19 #define DEBUG_OFF_LEVEL		   -1 /* level where debug is switched off */
20 #define DEBUG_FLUSH_ALL		   -1 /* parameter to flush all areas */
21 #define DEBUG_MAX_VIEWS		   10 /* max number of views in proc fs */
22 #define DEBUG_MAX_NAME_LEN	   64 /* max length for a debugfs file name */
23 #define DEBUG_DEFAULT_LEVEL	   3  /* initial debug level */
24 
25 #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */
26 
27 #define DEBUG_DATA(entry) (char *)(entry + 1) /* data is stored behind */
28 					      /* the entry information */
29 
30 #define __DEBUG_FEATURE_VERSION	   3  /* version of debug feature */
31 
32 struct __debug_entry {
33 	unsigned long clock	: 60;
34 	unsigned long exception	:  1;
35 	unsigned long level	:  3;
36 	void *caller;
37 	unsigned short cpu;
38 } __packed;
39 
40 typedef struct __debug_entry debug_entry_t;
41 
42 struct debug_view;
43 
44 typedef struct debug_info {
45 	struct debug_info *next;
46 	struct debug_info *prev;
47 	refcount_t ref_count;
48 	spinlock_t lock;
49 	int level;
50 	int nr_areas;
51 	int pages_per_area;
52 	int buf_size;
53 	int entry_size;
54 	debug_entry_t ***areas;
55 	int active_area;
56 	int *active_pages;
57 	int *active_entries;
58 	struct dentry *debugfs_root_entry;
59 	struct dentry *debugfs_entries[DEBUG_MAX_VIEWS];
60 	struct debug_view *views[DEBUG_MAX_VIEWS];
61 	char name[DEBUG_MAX_NAME_LEN];
62 	umode_t mode;
63 } debug_info_t;
64 
65 typedef int (debug_header_proc_t) (debug_info_t *id,
66 				   struct debug_view *view,
67 				   int area,
68 				   debug_entry_t *entry,
69 				   char *out_buf);
70 
71 typedef int (debug_format_proc_t) (debug_info_t *id,
72 				   struct debug_view *view, char *out_buf,
73 				   const char *in_buf);
74 typedef int (debug_prolog_proc_t) (debug_info_t *id,
75 				   struct debug_view *view,
76 				   char *out_buf);
77 typedef int (debug_input_proc_t) (debug_info_t *id,
78 				  struct debug_view *view,
79 				  struct file *file,
80 				  const char __user *user_buf,
81 				  size_t in_buf_size, loff_t *offset);
82 
83 int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
84 			 int area, debug_entry_t *entry, char *out_buf);
85 
86 struct debug_view {
87 	char name[DEBUG_MAX_NAME_LEN];
88 	debug_prolog_proc_t *prolog_proc;
89 	debug_header_proc_t *header_proc;
90 	debug_format_proc_t *format_proc;
91 	debug_input_proc_t  *input_proc;
92 	void		    *private_data;
93 };
94 
95 extern struct debug_view debug_hex_ascii_view;
96 extern struct debug_view debug_sprintf_view;
97 
98 /* do NOT use the _common functions */
99 
100 debug_entry_t *debug_event_common(debug_info_t *id, int level,
101 				  const void *data, int length);
102 
103 debug_entry_t *debug_exception_common(debug_info_t *id, int level,
104 				      const void *data, int length);
105 
106 /* Debug Feature API: */
107 
108 debug_info_t *debug_register(const char *name, int pages, int nr_areas,
109 			     int buf_size);
110 
111 debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas,
112 				  int buf_size, umode_t mode, uid_t uid,
113 				  gid_t gid);
114 
115 void debug_unregister(debug_info_t *id);
116 
117 void debug_set_level(debug_info_t *id, int new_level);
118 
119 void debug_set_critical(void);
120 
121 void debug_stop_all(void);
122 
123 /**
124  * debug_level_enabled() - Returns true if debug events for the specified
125  *			   level would be logged. Otherwise returns false.
126  *
127  * @id:		handle for debug log
128  * @level:	debug level
129  *
130  * Return:
131  * - %true if level is less or equal to the current debug level.
132  */
debug_level_enabled(debug_info_t * id,int level)133 static inline bool debug_level_enabled(debug_info_t *id, int level)
134 {
135 	return level <= id->level;
136 }
137 
138 /**
139  * debug_event() - writes binary debug entry to active debug area
140  *		   (if level <= actual debug level)
141  *
142  * @id:		handle for debug log
143  * @level:	debug level
144  * @data:	pointer to data for debug entry
145  * @length:	length of data in bytes
146  *
147  * Return:
148  * - Address of written debug entry
149  * - %NULL if error
150  */
debug_event(debug_info_t * id,int level,void * data,int length)151 static inline debug_entry_t *debug_event(debug_info_t *id, int level,
152 					 void *data, int length)
153 {
154 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
155 		return NULL;
156 	return debug_event_common(id, level, data, length);
157 }
158 
159 /**
160  * debug_int_event() - writes unsigned integer debug entry to active debug area
161  *		       (if level <= actual debug level)
162  *
163  * @id:		handle for debug log
164  * @level:	debug level
165  * @tag:	integer value for debug entry
166  *
167  * Return:
168  * - Address of written debug entry
169  * - %NULL if error
170  */
debug_int_event(debug_info_t * id,int level,unsigned int tag)171 static inline debug_entry_t *debug_int_event(debug_info_t *id, int level,
172 					     unsigned int tag)
173 {
174 	unsigned int t = tag;
175 
176 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
177 		return NULL;
178 	return debug_event_common(id, level, &t, sizeof(unsigned int));
179 }
180 
181 /**
182  * debug_long_event() - writes unsigned long debug entry to active debug area
183  *		       (if level <= actual debug level)
184  *
185  * @id:		handle for debug log
186  * @level:	debug level
187  * @tag:	long integer value for debug entry
188  *
189  * Return:
190  * - Address of written debug entry
191  * - %NULL if error
192  */
debug_long_event(debug_info_t * id,int level,unsigned long tag)193 static inline debug_entry_t *debug_long_event(debug_info_t *id, int level,
194 					      unsigned long tag)
195 {
196 	unsigned long t = tag;
197 
198 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
199 		return NULL;
200 	return debug_event_common(id, level, &t, sizeof(unsigned long));
201 }
202 
203 /**
204  * debug_text_event() - writes string debug entry in ascii format to active
205  *			debug area (if level <= actual debug level)
206  *
207  * @id:		handle for debug log
208  * @level:	debug level
209  * @txt:	string for debug entry
210  *
211  * Return:
212  * - Address of written debug entry
213  * - %NULL if error
214  */
debug_text_event(debug_info_t * id,int level,const char * txt)215 static inline debug_entry_t *debug_text_event(debug_info_t *id, int level,
216 					      const char *txt)
217 {
218 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
219 		return NULL;
220 	return debug_event_common(id, level, txt, strlen(txt));
221 }
222 
223 /*
224  * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
225  * stored in the s390dbf. See Documentation/arch/s390/s390dbf.rst for more details!
226  */
227 extern debug_entry_t *
228 __debug_sprintf_event(debug_info_t *id, int level, char *string, ...)
229 	__attribute__ ((format(printf, 3, 4)));
230 
231 /**
232  * debug_sprintf_event() - writes debug entry with format string
233  *			   and varargs (longs) to active debug area
234  *			   (if level $<=$ actual debug level).
235  *
236  * @_id:	handle for debug log
237  * @_level:	debug level
238  * @_fmt:	format string for debug entry
239  * @...:	varargs used as in sprintf()
240  *
241  * Return:
242  * - Address of written debug entry
243  * - %NULL if error
244  *
245  * floats and long long datatypes cannot be used as varargs.
246  */
247 #define debug_sprintf_event(_id, _level, _fmt, ...)			\
248 ({									\
249 	debug_entry_t *__ret;						\
250 	debug_info_t *__id = _id;					\
251 	int __level = _level;						\
252 									\
253 	if ((!__id) || (__level > __id->level))				\
254 		__ret = NULL;						\
255 	else								\
256 		__ret = __debug_sprintf_event(__id, __level,		\
257 					      _fmt, ## __VA_ARGS__);	\
258 	__ret;								\
259 })
260 
261 /**
262  * debug_exception() - writes binary debug entry to active debug area
263  *		       (if level <= actual debug level)
264  *		       and switches to next debug area
265  *
266  * @id:		handle for debug log
267  * @level:	debug level
268  * @data:	pointer to data for debug entry
269  * @length:	length of data in bytes
270  *
271  * Return:
272  * - Address of written debug entry
273  * - %NULL if error
274  */
debug_exception(debug_info_t * id,int level,void * data,int length)275 static inline debug_entry_t *debug_exception(debug_info_t *id, int level,
276 					     void *data, int length)
277 {
278 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
279 		return NULL;
280 	return debug_exception_common(id, level, data, length);
281 }
282 
283 /**
284  * debug_int_exception() - writes unsigned int debug entry to active debug area
285  *			   (if level <= actual debug level)
286  *			   and switches to next debug area
287  *
288  * @id:		handle for debug log
289  * @level:	debug level
290  * @tag:	integer value for debug entry
291  *
292  * Return:
293  * - Address of written debug entry
294  * - %NULL if error
295  */
debug_int_exception(debug_info_t * id,int level,unsigned int tag)296 static inline debug_entry_t *debug_int_exception(debug_info_t *id, int level,
297 						 unsigned int tag)
298 {
299 	unsigned int t = tag;
300 
301 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
302 		return NULL;
303 	return debug_exception_common(id, level, &t, sizeof(unsigned int));
304 }
305 
306 /**
307  * debug_long_exception() - writes long debug entry to active debug area
308  *			   (if level <= actual debug level)
309  *			   and switches to next debug area
310  *
311  * @id:		handle for debug log
312  * @level:	debug level
313  * @tag:	long integer value for debug entry
314  *
315  * Return:
316  * - Address of written debug entry
317  * - %NULL if error
318  */
debug_long_exception(debug_info_t * id,int level,unsigned long tag)319 static inline debug_entry_t *debug_long_exception (debug_info_t *id, int level,
320 						   unsigned long tag)
321 {
322 	unsigned long t = tag;
323 
324 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
325 		return NULL;
326 	return debug_exception_common(id, level, &t, sizeof(unsigned long));
327 }
328 
329 /**
330  * debug_text_exception() - writes string debug entry in ascii format to active
331  *			    debug area (if level <= actual debug level)
332  *			    and switches to next debug area
333  * area
334  *
335  * @id:	handle for debug log
336  * @level:	debug level
337  * @txt:	string for debug entry
338  *
339  * Return:
340  * - Address of written debug entry
341  * - %NULL if error
342  */
debug_text_exception(debug_info_t * id,int level,const char * txt)343 static inline debug_entry_t *debug_text_exception(debug_info_t *id, int level,
344 						  const char *txt)
345 {
346 	if ((!id) || (level > id->level) || (id->pages_per_area == 0))
347 		return NULL;
348 	return debug_exception_common(id, level, txt, strlen(txt));
349 }
350 
351 /*
352  * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are
353  * stored in the s390dbf. See Documentation/arch/s390/s390dbf.rst for more details!
354  */
355 extern debug_entry_t *
356 __debug_sprintf_exception(debug_info_t *id, int level, char *string, ...)
357 	__attribute__ ((format(printf, 3, 4)));
358 
359 
360 /**
361  * debug_sprintf_exception() - writes debug entry with format string and
362  *			       varargs (longs) to active debug area
363  *			       (if level <= actual debug level)
364  *			       and switches to next debug area.
365  *
366  * @_id:	handle for debug log
367  * @_level:	debug level
368  * @_fmt:	format string for debug entry
369  * @...:	varargs used as in sprintf()
370  *
371  * Return:
372  * - Address of written debug entry
373  * - %NULL if error
374  *
375  * floats and long long datatypes cannot be used as varargs.
376  */
377 #define debug_sprintf_exception(_id, _level, _fmt, ...)			\
378 ({									\
379 	debug_entry_t *__ret;						\
380 	debug_info_t *__id = _id;					\
381 	int __level = _level;						\
382 									\
383 	if ((!__id) || (__level > __id->level))				\
384 		__ret = NULL;						\
385 	else								\
386 		__ret = __debug_sprintf_exception(__id, __level,	\
387 						  _fmt, ## __VA_ARGS__);\
388 	__ret;								\
389 })
390 
391 int debug_register_view(debug_info_t *id, struct debug_view *view);
392 
393 int debug_unregister_view(debug_info_t *id, struct debug_view *view);
394 
395 #ifndef MODULE
396 
397 /*
398  * Note: Initial page and area numbers must be fixed to allow static
399  * initialization. This enables very early tracing. Changes to these values
400  * must be reflected in __DEFINE_STATIC_AREA.
401  */
402 #define EARLY_PAGES		8
403 #define EARLY_AREAS		1
404 
405 #define VNAME(var, suffix)	__##var##_##suffix
406 
407 /*
408  * Define static areas for early trace data. During boot debug_register_static()
409  * will replace these with dynamically allocated areas to allow custom page and
410  * area sizes, and dynamic resizing.
411  */
412 #define __DEFINE_STATIC_AREA(var)					\
413 static char VNAME(var, data)[EARLY_PAGES][PAGE_SIZE] __initdata;	\
414 static debug_entry_t *VNAME(var, pages)[EARLY_PAGES] __initdata = {	\
415 	(debug_entry_t *)VNAME(var, data)[0],				\
416 	(debug_entry_t *)VNAME(var, data)[1],				\
417 	(debug_entry_t *)VNAME(var, data)[2],				\
418 	(debug_entry_t *)VNAME(var, data)[3],				\
419 	(debug_entry_t *)VNAME(var, data)[4],				\
420 	(debug_entry_t *)VNAME(var, data)[5],				\
421 	(debug_entry_t *)VNAME(var, data)[6],				\
422 	(debug_entry_t *)VNAME(var, data)[7],				\
423 };									\
424 static debug_entry_t **VNAME(var, areas)[EARLY_AREAS] __initdata = {	\
425 	(debug_entry_t **)VNAME(var, pages),				\
426 };									\
427 static int VNAME(var, active_pages)[EARLY_AREAS] __initdata;		\
428 static int VNAME(var, active_entries)[EARLY_AREAS] __initdata
429 
430 #define __DEBUG_INFO_INIT(var, _name, _buf_size) {			\
431 	.next = NULL,							\
432 	.prev = NULL,							\
433 	.ref_count = REFCOUNT_INIT(1),					\
434 	.lock = __SPIN_LOCK_UNLOCKED(var.lock),				\
435 	.level = DEBUG_DEFAULT_LEVEL,					\
436 	.nr_areas = EARLY_AREAS,					\
437 	.pages_per_area = EARLY_PAGES,					\
438 	.buf_size = (_buf_size),					\
439 	.entry_size = sizeof(debug_entry_t) + (_buf_size),		\
440 	.areas = VNAME(var, areas),					\
441 	.active_area = 0,						\
442 	.active_pages = VNAME(var, active_pages),			\
443 	.active_entries = VNAME(var, active_entries),			\
444 	.debugfs_root_entry = NULL,					\
445 	.debugfs_entries = { NULL },					\
446 	.views = { NULL },						\
447 	.name = (_name),						\
448 	.mode = 0600,							\
449 }
450 
451 #define __REGISTER_STATIC_DEBUG_INFO(var, name, pages, areas, view)	\
452 static int __init VNAME(var, reg)(void)					\
453 {									\
454 	debug_register_static(&var, (pages), (areas));			\
455 	debug_register_view(&var, (view));				\
456 	return 0;							\
457 }									\
458 arch_initcall(VNAME(var, reg))
459 
460 /**
461  * DEFINE_STATIC_DEBUG_INFO - Define static debug_info_t
462  *
463  * @var: Name of debug_info_t variable
464  * @name: Name of debug log (e.g. used for debugfs entry)
465  * @pages: Number of pages per area
466  * @nr_areas: Number of debug areas
467  * @buf_size: Size of data area in each debug entry
468  * @view: Pointer to debug view struct
469  *
470  * Define a static debug_info_t for early tracing. The associated debugfs log
471  * is automatically registered with the specified debug view.
472  *
473  * Important: Users of this macro must not call any of the
474  * debug_register/_unregister() functions for this debug_info_t!
475  *
476  * Note: Tracing will start with a fixed number of initial pages and areas.
477  * The debug area will be changed to use the specified numbers during
478  * arch_initcall.
479  */
480 #define DEFINE_STATIC_DEBUG_INFO(var, name, pages, nr_areas, buf_size, view) \
481 __DEFINE_STATIC_AREA(var);						\
482 static debug_info_t __refdata var =					\
483 	__DEBUG_INFO_INIT(var, (name), (buf_size));			\
484 __REGISTER_STATIC_DEBUG_INFO(var, name, pages, nr_areas, view)
485 
486 void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
487 
488 #endif /* MODULE */
489 
490 #endif /* _ASM_S390_DEBUG_H */
491