~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/s390/include/asm/debug.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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/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  */
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/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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php