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