linux/arch/s390/include/asm/debug.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 *   S/390 debug facility
   4 *
   5 *    Copyright IBM Corp. 1999, 2020
   6 */
   7#ifndef DEBUG_H
   8#define 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
  31struct __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
  39typedef struct __debug_entry debug_entry_t;
  40
  41struct debug_view;
  42
  43typedef 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
  64typedef 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
  70typedef int (debug_format_proc_t) (debug_info_t *id,
  71                                   struct debug_view *view, char *out_buf,
  72                                   const char *in_buf);
  73typedef int (debug_prolog_proc_t) (debug_info_t *id,
  74                                   struct debug_view *view,
  75                                   char *out_buf);
  76typedef 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
  82int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
  83                         int area, debug_entry_t *entry, char *out_buf);
  84
  85struct 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
  94extern struct debug_view debug_hex_ascii_view;
  95extern struct debug_view debug_sprintf_view;
  96
  97/* do NOT use the _common functions */
  98
  99debug_entry_t *debug_event_common(debug_info_t *id, int level,
 100                                  const void *data, int length);
 101
 102debug_entry_t *debug_exception_common(debug_info_t *id, int level,
 103                                      const void *data, int length);
 104
 105/* Debug Feature API: */
 106
 107debug_info_t *debug_register(const char *name, int pages, int nr_areas,
 108                             int buf_size);
 109
 110debug_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
 114void debug_unregister(debug_info_t *id);
 115
 116void debug_set_level(debug_info_t *id, int new_level);
 117
 118void debug_set_critical(void);
 119
 120void 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 */
 132static 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 */
 150static 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 */
 170static 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 */
 192static 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 */
 214static 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 */
 226extern 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 */
 274static 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 */
 295static 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 */
 318static 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 */
 342static 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 */
 354extern 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
 390int debug_register_view(debug_info_t *id, struct debug_view *view);
 391
 392int 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 /* DEBUG_H */
 429