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