xref: /linux/arch/s390/include/asm/debug.h (revision 954ea91fb68b771dba6d87cfa61b68e09cc2497f)
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   */
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   */
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   */
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   */
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   */
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/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   */
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   */
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   */
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   */
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/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