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#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
  32struct __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
  40typedef struct __debug_entry debug_entry_t;
  41
  42struct debug_view;
  43
  44typedef 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
  65typedef 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
  71typedef int (debug_format_proc_t) (debug_info_t *id,
  72                                   struct debug_view *view, char *out_buf,
  73                                   const char *in_buf);
  74typedef int (debug_prolog_proc_t) (debug_info_t *id,
  75                                   struct debug_view *view,
  76                                   char *out_buf);
  77typedef 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
  83int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view,
  84                         int area, debug_entry_t *entry, char *out_buf);
  85
  86struct 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
  95extern struct debug_view debug_hex_ascii_view;
  96extern struct debug_view debug_sprintf_view;
  97
  98/* do NOT use the _common functions */
  99
 100debug_entry_t *debug_event_common(debug_info_t *id, int level,
 101                                  const void *data, int length);
 102
 103debug_entry_t *debug_exception_common(debug_info_t *id, int level,
 104                                      const void *data, int length);
 105
 106/* Debug Feature API: */
 107
 108debug_info_t *debug_register(const char *name, int pages, int nr_areas,
 109                             int buf_size);
 110
 111debug_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
 115void debug_unregister(debug_info_t *id);
 116
 117void debug_set_level(debug_info_t *id, int new_level);
 118
 119void debug_set_critical(void);
 120
 121void 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 */
 133static 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 */
 151static 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 */
 171static 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 */
 193static 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 */
 215static 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 */
 227extern 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 */
 275static 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 */
 296static 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 */
 319static 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 */
 343static 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 */
 355extern 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
 391int debug_register_view(debug_info_t *id, struct debug_view *view);
 392
 393int 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)                                       \
 413static char VNAME(var, data)[EARLY_PAGES][PAGE_SIZE] __initdata;        \
 414static 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};                                                                      \
 424static debug_entry_t **VNAME(var, areas)[EARLY_AREAS] __initdata = {    \
 425        (debug_entry_t **)VNAME(var, pages),                            \
 426};                                                                      \
 427static int VNAME(var, active_pages)[EARLY_AREAS] __initdata;            \
 428static 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)     \
 452static int __init VNAME(var, reg)(void)                                 \
 453{                                                                       \
 454        debug_register_static(&var, (pages), (areas));                  \
 455        debug_register_view(&var, (view));                              \
 456        return 0;                                                       \
 457}                                                                       \
 458arch_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_per_area: 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);                                              \
 482static 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
 486void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas);
 487
 488#endif /* MODULE */
 489
 490#endif /* DEBUG_H */
 491