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