11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * arch/s390/kernel/debug.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * S/390 debug facility 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 53ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu * Copyright IBM Corp. 1999, 2012 63ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu * 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author(s): Michael Holzheu (holzheu@de.ibm.com), 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Holger Smolinski (Holger.Smolinski@de.ibm.com) 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Bugreports to: <Linux390@de.ibm.com> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu#define KMSG_COMPONENT "s390dbf" 14c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 15c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/stddef.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ctype.h> 21e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa#include <linux/string.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sysctl.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 2666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu#include <linux/fs.h> 2766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu#include <linux/debugfs.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/debug.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUG_PROLOG_ENTRY -1 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu#define ALL_AREAS 0 /* copy all debug areas */ 3466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu#define NO_AREAS 1 /* copy no debug areas */ 3566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* typedefs */ 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct file_private_info { 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds loff_t offset; /* offset of last read in file */ 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int act_area; /* number of last formated area */ 4166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int act_page; /* act page in given area */ 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int act_entry; /* last formated entry (offset */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* relative to beginning of last */ 4466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* formated page) */ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t act_entry_offset; /* up to this offset we copied */ 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* in last read the last formated */ 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* entry to userland */ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char temp_buf[2048]; /* buffer for output */ 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t *debug_info_org; /* original debug information */ 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t *debug_info_snap; /* snapshot of debug information */ 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct debug_view *view; /* used view of debug info */ 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} file_private_info_t; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstypedef struct 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *string; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This assumes that all args are converted into longs 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * on L/390 this is the case for all types of parameter 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * except of floats, and long long (32 bit) 6166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * 6266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu */ 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds long args[0]; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} debug_sprintf_entry_t; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* internal function prototyes */ 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_init(void); 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t debug_output(struct file *file, char __user *user_buf, 7166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_len, loff_t * offset); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic ssize_t debug_input(struct file *file, const char __user *user_buf, 7366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_len, loff_t * offset); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_open(struct inode *inode, struct file *file); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_close(struct inode *inode, struct file *file); 765cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huckstatic debug_info_t *debug_info_create(const char *name, int pages_per_area, 77f4ae40a6a50a98ac23d4b285f739455e926a473eAl Viro int nr_areas, int buf_size, umode_t mode); 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void debug_info_get(debug_info_t *); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void debug_info_put(debug_info_t *); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_prolog_level_fn(debug_info_t * id, 8166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct debug_view *view, char *out_buf); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_input_level_fn(debug_info_t * id, struct debug_view *view, 8366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct file *file, const char __user *user_buf, 8466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_buf_size, loff_t * offset); 8566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int debug_prolog_pages_fn(debug_info_t * id, 8666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct debug_view *view, char *out_buf); 8766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int debug_input_pages_fn(debug_info_t * id, struct debug_view *view, 8866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct file *file, const char __user *user_buf, 8966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_buf_size, loff_t * offset); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_input_flush_fn(debug_info_t * id, struct debug_view *view, 9166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct file *file, const char __user *user_buf, 9266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_buf_size, loff_t * offset); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, 9466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char *out_buf, const char *in_buf); 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_raw_format_fn(debug_info_t * id, 9666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct debug_view *view, char *out_buf, 9766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu const char *in_buf); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_raw_header_fn(debug_info_t * id, struct debug_view *view, 9966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int area, debug_entry_t * entry, char *out_buf); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, 10266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char *out_buf, debug_sprintf_entry_t *curr_event); 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* globals */ 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct debug_view debug_raw_view = { 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "raw", 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_raw_header_fn, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_raw_format_fn, 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct debug_view debug_hex_ascii_view = { 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "hex_ascii", 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_dflt_header_fn, 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_hex_ascii_format_fn, 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1242b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensstatic struct debug_view debug_level_view = { 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "level", 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_prolog_level_fn, 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_input_level_fn, 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1332b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensstatic struct debug_view debug_pages_view = { 13466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu "pages", 13566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu &debug_prolog_pages_fn, 13666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu NULL, 13766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu NULL, 13866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu &debug_input_pages_fn, 13966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu NULL 14066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu}; 14166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 1422b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensstatic struct debug_view debug_flush_view = { 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "flush", 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_input_flush_fn, 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct debug_view debug_sprintf_view = { 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "sprintf", 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &debug_dflt_header_fn, 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (debug_format_proc_t*)&debug_sprintf_format_fn, 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL, 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds NULL 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1602b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstens/* used by dump analysis tools to determine version of debug feature */ 161a806170e29c5468b1d641a22518243bdf1b8d58bHeiko Carstensstatic unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* static globals */ 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic debug_info_t *debug_area_first = NULL; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic debug_info_t *debug_area_last = NULL; 167e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwigstatic DEFINE_MUTEX(debug_mutex); 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int initialized; 1703ab121ab18669226742891416fe7ecc86dadb047Michael Holzheustatic int debug_critical; 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1725dfe4c964a0dd7bb3a1d64a4166835a153146207Arjan van de Venstatic const struct file_operations debug_file_ops = { 17366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu .owner = THIS_MODULE, 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = debug_output, 17566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu .write = debug_input, 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .open = debug_open, 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = debug_close, 1786038f373a3dc1f1c26496e60b6c40b164716f07eArnd Bergmann .llseek = no_llseek, 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic struct dentry *debug_debugfs_root_entry; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* functions */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 18666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * debug_areas_alloc 18766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * - Debug areas are implemented as a threedimensonal array: 18866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * areas[areanumber][pagenumber][pageoffset] 18966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu */ 19066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 19166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic debug_entry_t*** 19266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_areas_alloc(int pages_per_area, int nr_areas) 19366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 19466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_entry_t*** areas; 19566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int i,j; 19666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 1975cbded585d129d0226cb48ac4202b253c781be26Robert P. J. Day areas = kmalloc(nr_areas * 19866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu sizeof(debug_entry_t**), 19966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu GFP_KERNEL); 20066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!areas) 20166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto fail_malloc_areas; 20266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for (i = 0; i < nr_areas; i++) { 2035cbded585d129d0226cb48ac4202b253c781be26Robert P. J. Day areas[i] = kmalloc(pages_per_area * 20466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu sizeof(debug_entry_t*),GFP_KERNEL); 20566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!areas[i]) { 20666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto fail_malloc_areas2; 20766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 20866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(j = 0; j < pages_per_area; j++) { 209fb630517f0d0736ea73af07d6b357be9ad67e6f1Eric Sesterhenn areas[i][j] = kzalloc(PAGE_SIZE, GFP_KERNEL); 21066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!areas[i][j]) { 21166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(j--; j >=0 ; j--) { 21266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(areas[i][j]); 21366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 21466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(areas[i]); 21566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto fail_malloc_areas2; 21666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 21766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 21866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 21966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return areas; 22066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 22166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufail_malloc_areas2: 22266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(i--; i >= 0; i--){ 22366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(j=0; j < pages_per_area;j++){ 22466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(areas[i][j]); 22566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 22666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(areas[i]); 22766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 22866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(areas); 22966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufail_malloc_areas: 23066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return NULL; 23166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 23266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 23366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 23466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 23566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu/* 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_info_alloc 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - alloc new debug-info 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic debug_info_t* 2415cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huckdebug_info_alloc(const char *name, int pages_per_area, int nr_areas, 2425cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huck int buf_size, int level, int mode) 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t* rc; 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* alloc everything */ 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2485cbded585d129d0226cb48ac4202b253c781be26Robert P. J. Day rc = kmalloc(sizeof(debug_info_t), GFP_KERNEL); 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!rc) 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto fail_malloc_rc; 251fb630517f0d0736ea73af07d6b357be9ad67e6f1Eric Sesterhenn rc->active_entries = kcalloc(nr_areas, sizeof(int), GFP_KERNEL); 25266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!rc->active_entries) 25366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto fail_malloc_active_entries; 254fb630517f0d0736ea73af07d6b357be9ad67e6f1Eric Sesterhenn rc->active_pages = kcalloc(nr_areas, sizeof(int), GFP_KERNEL); 25566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!rc->active_pages) 25666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto fail_malloc_active_pages; 25766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if((mode == ALL_AREAS) && (pages_per_area != 0)){ 25866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->areas = debug_areas_alloc(pages_per_area, nr_areas); 25966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!rc->areas) 26066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto fail_malloc_areas; 26166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } else { 26266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->areas = NULL; 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* initialize members */ 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&rc->lock); 26866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->pages_per_area = pages_per_area; 26966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->nr_areas = nr_areas; 27066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->active_area = 0; 27166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->level = level; 27266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->buf_size = buf_size; 27366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->entry_size = sizeof(debug_entry_t) + buf_size; 27420cb9e79b963b8f5142e4dd946baf44a75e7935fJean Delvare strlcpy(rc->name, name, sizeof(rc->name)); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); 27666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS * 27766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu sizeof(struct dentry*)); 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_set(&(rc->ref_count), 0); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfail_malloc_areas: 28366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(rc->active_pages); 28466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufail_malloc_active_pages: 28566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(rc->active_entries); 28666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufail_malloc_active_entries: 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(rc); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsfail_malloc_rc: 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 29366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * debug_areas_free 29466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * - free all debug areas 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic void 29866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_areas_free(debug_info_t* db_info) 29966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 30066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int i,j; 30166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 30266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!db_info->areas) 30366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < db_info->nr_areas; i++) { 30566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(j = 0; j < db_info->pages_per_area; j++) { 30666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(db_info->areas[i][j]); 30766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 30866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(db_info->areas[i]); 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(db_info->areas); 31166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu db_info->areas = NULL; 31266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 31366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 31466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu/* 31566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * debug_info_free 31666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * - free memory debug-info 31766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu */ 31866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 31966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic void 32066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_info_free(debug_info_t* db_info){ 32166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_areas_free(db_info); 32266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(db_info->active_entries); 32366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(db_info->active_pages); 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(db_info); 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_info_create 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - create new debug-info 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic debug_info_t* 3335cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huckdebug_info_create(const char *name, int pages_per_area, int nr_areas, 334f4ae40a6a50a98ac23d4b285f739455e926a473eAl Viro int buf_size, umode_t mode) 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t* rc; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 33866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, 33966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu DEBUG_DEFAULT_LEVEL, ALL_AREAS); 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!rc) 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3439637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu rc->mode = mode & ~S_IFMT; 3449637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu 34566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* create root directory */ 34666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc->debugfs_root_entry = debugfs_create_dir(rc->name, 34766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_debugfs_root_entry); 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* append new element to linked list */ 35066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!debug_area_first) { 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* first element in list */ 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_area_first = rc; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc->prev = NULL; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* append element to end of list */ 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_area_last->next = rc; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc->prev = debug_area_last; 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_area_last = rc; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc->next = NULL; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_get(rc); 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_info_copy 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - copy debug-info 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic debug_info_t* 37366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_info_copy(debug_info_t* in, int mode) 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 37566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int i,j; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t* rc; 377942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu unsigned long flags; 378942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu 379942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu /* get a consistent copy of the debug areas */ 380942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu do { 381942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu rc = debug_info_alloc(in->name, in->pages_per_area, 382942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu in->nr_areas, in->buf_size, in->level, mode); 383942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu spin_lock_irqsave(&in->lock, flags); 384942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu if(!rc) 385942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu goto out; 386942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu /* has something changed in the meantime ? */ 387942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu if((rc->pages_per_area == in->pages_per_area) && 388942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu (rc->nr_areas == in->nr_areas)) { 389942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu break; 390942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu } 391942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu spin_unlock_irqrestore(&in->lock, flags); 392942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu debug_info_free(rc); 393942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu } while (1); 39466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 395acfa922c5a00eca0abac0e2b6d6666c606c27345Julia Lawall if (mode == NO_AREAS) 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < in->nr_areas; i++){ 39966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(j = 0; j < in->pages_per_area; j++) { 40066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memcpy(rc->areas[i][j], in->areas[i][j],PAGE_SIZE); 40166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 404942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu spin_unlock_irqrestore(&in->lock, flags); 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_info_get 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - increments reference count for debug-info 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic void 41466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_info_get(debug_info_t * db_info) 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (db_info) 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds atomic_inc(&db_info->ref_count); 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_info_put: 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - decreases reference count for debug-info and frees it if necessary 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic void 42666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_info_put(debug_info_t *db_info) 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!db_info) 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (atomic_dec_and_test(&db_info->ref_count)) { 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 43466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!db_info->views[i]) 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 43666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debugfs_remove(db_info->debugfs_entries[i]); 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 43866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debugfs_remove(db_info->debugfs_root_entry); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(db_info == debug_area_first) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_area_first = db_info->next; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(db_info == debug_area_last) 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_area_last = db_info->prev; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(db_info->prev) db_info->prev->next = db_info->next; 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(db_info->next) db_info->next->prev = db_info->prev; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_free(db_info); 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_format_entry: 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - format one debug entry and return size of formated data 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 45466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 45566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_format_entry(file_private_info_t *p_info) 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t *id_snap = p_info->debug_info_snap; 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct debug_view *view = p_info->view; 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_entry_t *act_entry; 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t len = 0; 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* print prolog */ 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (view->prolog_proc) 46466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu len += view->prolog_proc(id_snap,view,p_info->temp_buf); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 46766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!id_snap->areas) /* this is true, if we have a prolog only view */ 46866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto out; /* or if 'pages_per_area' is 0 */ 46966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] 47066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu [p_info->act_page] + p_info->act_entry); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (act_entry->id.stck == 0LL) 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; /* empty entry */ 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (view->header_proc) 47566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu len += view->header_proc(id_snap, view, p_info->act_area, 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds act_entry, p_info->temp_buf + len); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (view->format_proc) 47866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu len += view->format_proc(id_snap, view, p_info->temp_buf + len, 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DEBUG_DATA(act_entry)); 48066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return len; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_next_entry: 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - goto next entry in p_info 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4894448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int 49066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_next_entry(file_private_info_t *p_info) 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 49266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_info_t *id; 49366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 49466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id = p_info->debug_info_snap; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(p_info->act_entry == DEBUG_PROLOG_ENTRY){ 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->act_entry = 0; 49766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_page = 0; 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 50066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!id->areas) 50166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return 1; 50266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_entry += id->entry_size; 50366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* switch to next page, if we reached the end of the page */ 50466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (p_info->act_entry > (PAGE_SIZE - id->entry_size)){ 50566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* next page */ 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->act_entry = 0; 50766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_page += 1; 50866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if((p_info->act_page % id->pages_per_area) == 0) { 50966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* next area */ 51066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_area++; 51166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_page=0; 51266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(p_info->act_area >= id->nr_areas) 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_output: 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - called for user read() 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - copies formated debug entries to the user buffer 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic ssize_t 52766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_output(struct file *file, /* file descriptor */ 52866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char __user *user_buf, /* user buffer */ 52966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t len, /* length of buffer */ 53066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu loff_t *offset) /* offset in the file */ 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t count = 0; 53366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t entry_offset; 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file_private_info_t *p_info; 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info = ((file_private_info_t *) file->private_data); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (*offset != p_info->offset) 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EPIPE; 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(p_info->act_area >= p_info->debug_info_snap->nr_areas) 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds entry_offset = p_info->act_entry_offset; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(count < len){ 54366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int formatted_line_size; 54466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int formatted_line_residue; 54566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int user_buf_residue; 54666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t copy_size; 54766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 54866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu formatted_line_size = debug_format_entry(p_info); 54966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu formatted_line_residue = formatted_line_size - entry_offset; 55066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu user_buf_residue = len-count; 55166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu copy_size = min(user_buf_residue, formatted_line_residue); 55266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(copy_size){ 55366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (copy_to_user(user_buf + count, p_info->temp_buf 55466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu + entry_offset, copy_size)) 55566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return -EFAULT; 55666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu count += copy_size; 55766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu entry_offset += copy_size; 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(copy_size == formatted_line_residue){ 56066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu entry_offset = 0; 56166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(debug_next_entry(p_info)) 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 56366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->offset = *offset + count; 56766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_entry_offset = entry_offset; 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *offset = p_info->offset; 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_input: 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - called for user write() 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - calls input function of view 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic ssize_t 57966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_input(struct file *file, const char __user *user_buf, size_t length, 58066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu loff_t *offset) 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = 0; 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file_private_info_t *p_info; 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 585e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_lock(&debug_mutex); 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info = ((file_private_info_t *) file->private_data); 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (p_info->view->input_proc) 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = p_info->view->input_proc(p_info->debug_info_org, 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->view, file, user_buf, 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds length, offset); 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -EPERM; 593e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_unlock(&debug_mutex); 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; /* number of input characters */ 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_open: 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - called for user open() 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - copies formated output to private_data area of the file 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handle 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 60466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 60566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_open(struct inode *inode, struct file *file) 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 607a0fa8e3743c80643a06a770b95e73e751548ab17Michael Holzheu int i, rc = 0; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file_private_info_t *p_info; 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t *debug_info, *debug_info_snapshot; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_lock(&debug_mutex); 612d20343e7406a114a561030e683fafc4fdbc9c6bdJosef Sipek debug_info = file->f_path.dentry->d_inode->i_private; 613942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu /* find debug view */ 614942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 615942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu if (!debug_info->views[i]) 616942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu continue; 617942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu else if (debug_info->debugfs_entries[i] == 618d20343e7406a114a561030e683fafc4fdbc9c6bdJosef Sipek file->f_path.dentry) { 619942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu goto found; /* found view ! */ 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* no entry found */ 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -EINVAL; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 62666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufound: 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 62866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* Make snapshot of current debug areas to get it consistent. */ 62966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* To copy all the areas is only needed, if we have a view which */ 63066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* formats the debug areas. */ 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 63266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!debug_info->views[i]->format_proc && 63366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu !debug_info->views[i]->header_proc){ 63466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_info_snapshot = debug_info_copy(debug_info, NO_AREAS); 63566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } else { 63666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_info_snapshot = debug_info_copy(debug_info, ALL_AREAS); 63766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!debug_info_snapshot){ 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -ENOMEM; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6435cbded585d129d0226cb48ac4202b253c781be26Robert P. J. Day p_info = kmalloc(sizeof(file_private_info_t), 64466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu GFP_KERNEL); 64566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!p_info){ 64658ace9f2a8f1caa0303aa64079d3929be28a937aMichael Holzheu debug_info_free(debug_info_snapshot); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -ENOMEM; 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->offset = 0; 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->debug_info_snap = debug_info_snapshot; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->debug_info_org = debug_info; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->view = debug_info->views[i]; 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->act_area = 0; 65566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu p_info->act_page = 0; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->act_entry = DEBUG_PROLOG_ENTRY; 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info->act_entry_offset = 0; 65866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu file->private_data = p_info; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_get(debug_info); 66058ea91c05346f7c6336e6248b743aa9a8e1c19a9Martin Schwidefsky nonseekable_open(inode, file); 66166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 662e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_unlock(&debug_mutex); 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_close: 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - called for user close() 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - deletes private_data area of the file handle 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 67266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 67366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_close(struct inode *inode, struct file *file) 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds file_private_info_t *p_info; 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds p_info = (file_private_info_t *) file->private_data; 67766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(p_info->debug_info_snap) 67866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_info_free(p_info->debug_info_snap); 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_put(p_info->debug_info_org); 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(file->private_data); 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; /* success */ 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 6859637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * debug_register_mode: 6869637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * - Creates and initializes debug area for the caller 6879637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * The mode parameter allows to specify access rights for the s390dbf files 6889637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * - Returns handle for debug area 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6915cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huckdebug_info_t *debug_register_mode(const char *name, int pages_per_area, 692f4ae40a6a50a98ac23d4b285f739455e926a473eAl Viro int nr_areas, int buf_size, umode_t mode, 6935cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huck uid_t uid, gid_t gid) 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_t *rc = NULL; 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6979637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu /* Since debugfs currently does not support uid/gid other than root, */ 6989637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu /* we do not allow gid/uid != 0 until we get support for that. */ 6999637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu if ((uid != 0) || (gid != 0)) 700c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_warning("Root becomes the owner of all s390dbf files " 701c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu "in sysfs\n"); 7026aa0d3a922c4f58fc36cc1502c6ac72f999e26bbStoyan Gaydarov BUG_ON(!initialized); 703e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_lock(&debug_mutex); 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* create new debug_info */ 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7079637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu rc = debug_info_create(name, pages_per_area, nr_areas, buf_size, mode); 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!rc) 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_register_view(rc, &debug_level_view); 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_register_view(rc, &debug_flush_view); 71266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_register_view(rc, &debug_pages_view); 71366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 71466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!rc){ 715c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_err("Registering debug feature %s failed\n", name); 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 717e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_unlock(&debug_mutex); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7209637c3f318374e2fcc37e354f9782a705b517387Michael HolzheuEXPORT_SYMBOL(debug_register_mode); 7219637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu 7229637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu/* 7239637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * debug_register: 7249637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * - creates and initializes debug area for the caller 7259637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu * - returns handle for debug area 7269637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu */ 7279637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu 7285cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huckdebug_info_t *debug_register(const char *name, int pages_per_area, 7295cbbf16a0fab91662af8400b5ada658990932a87Cornelia Huck int nr_areas, int buf_size) 7309637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu{ 7319637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu return debug_register_mode(name, pages_per_area, nr_areas, buf_size, 7329637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu S_IRUSR | S_IWUSR, 0, 0); 7339637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu} 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_unregister: 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - give back debug area 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 74066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuvoid 74166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_unregister(debug_info_t * id) 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!id) 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 745e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_lock(&debug_mutex); 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_info_put(id); 747e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_unlock(&debug_mutex); 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 74966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 75466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * debug_set_size: 75566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * - set area size (number of pages) and number of areas 75666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu */ 75766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 75866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_set_size(debug_info_t* id, int nr_areas, int pages_per_area) 75966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 76066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu unsigned long flags; 76166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_entry_t *** new_areas; 76266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int rc=0; 76366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 76466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!id || (nr_areas <= 0) || (pages_per_area < 0)) 76566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return -EINVAL; 76666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(pages_per_area > 0){ 76766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu new_areas = debug_areas_alloc(pages_per_area, nr_areas); 76866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!new_areas) { 769c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_info("Allocating memory for %i pages failed\n", 770c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pages_per_area); 77166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -ENOMEM; 77266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto out; 77366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 77466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } else { 77566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu new_areas = NULL; 77666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 77766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu spin_lock_irqsave(&id->lock,flags); 77866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_areas_free(id); 77966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->areas = new_areas; 78066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->nr_areas = nr_areas; 78166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->pages_per_area = pages_per_area; 78266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_area = 0; 78366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memset(id->active_entries,0,sizeof(int)*id->nr_areas); 78466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memset(id->active_pages, 0, sizeof(int)*id->nr_areas); 78566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu spin_unlock_irqrestore(&id->lock,flags); 786c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_info("%s: set new size (%i pages)\n" ,id->name, pages_per_area); 78766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 78866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return rc; 78966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 79066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 79166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu/* 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_set_level: 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - set actual debug level 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 79666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuvoid 79766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_set_level(debug_info_t* id, int new_level) 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(!id) 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&id->lock,flags); 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(new_level == DEBUG_OFF_LEVEL){ 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->level = DEBUG_OFF_LEVEL; 805c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_info("%s: switched off\n",id->name); 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) { 807c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_info("%s: level %i is out of range (%i - %i)\n", 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->name, new_level, 0, DEBUG_MAX_LEVEL); 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->level = new_level; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock,flags); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * proceed_active_entry: 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - set active entry to next in the ring buffer 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8214448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline void 82266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuproceed_active_entry(debug_info_t * id) 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 82466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if ((id->active_entries[id->active_area] += id->entry_size) 82566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu > (PAGE_SIZE - id->entry_size)){ 82666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_entries[id->active_area] = 0; 82766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_pages[id->active_area] = 82866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu (id->active_pages[id->active_area] + 1) % 82966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->pages_per_area; 83066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * proceed_active_area: 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - set active area to next in the ring buffer 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8384448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline void 83966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuproceed_active_area(debug_info_t * id) 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->active_area++; 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->active_area = id->active_area % id->nr_areas; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * get_active_entry: 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8494448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline debug_entry_t* 85066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuget_active_entry(debug_info_t * id) 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 85266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return (debug_entry_t *) (((char *) id->areas[id->active_area] 85366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu [id->active_pages[id->active_area]]) + 85466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_entries[id->active_area]); 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_finish_entry: 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - set timestamp, caller address, cpu number etc. 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8624448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline void 86366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_finish_entry(debug_info_t * id, debug_entry_t* active, int level, 86466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int exception) 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 866942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu active->id.stck = get_clock(); 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active->id.fields.cpuid = smp_processor_id(); 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active->caller = __builtin_return_address(0); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active->id.fields.exception = exception; 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active->id.fields.level = level; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds proceed_active_entry(id); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(exception) 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds proceed_active_area(id); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_stoppable=1; 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug_active=1; 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CTL_S390DBF_STOPPABLE 5678 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define CTL_S390DBF_ACTIVE 5679 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * proc handler for the running debug_active sysctl 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * always allow read, allow write only if debug_stoppable is set or 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * if debug_active is already off 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 88766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 8888d65af789f3e2cf4cfbdbf71a0f7a61ebcd41d38Alexey Dobriyans390dbf_procactive(ctl_table *table, int write, 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void __user *buffer, size_t *lenp, loff_t *ppos) 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!write || debug_stoppable || !debug_active) 8928d65af789f3e2cf4cfbdbf71a0f7a61ebcd41d38Alexey Dobriyan return proc_dointvec(table, write, buffer, lenp, ppos); 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ctl_table s390dbf_table[] = { 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .procname = "debug_stoppable", 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .data = &debug_stoppable, 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .maxlen = sizeof(int), 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .mode = S_IRUGO | S_IWUSR, 9046d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman .proc_handler = proc_dointvec, 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .procname = "debug_active", 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .data = &debug_active, 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .maxlen = sizeof(int), 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .mode = S_IRUGO | S_IWUSR, 9116d4561110a3e9fa742aeec6717248a491dfb1878Eric W. Biederman .proc_handler = s390dbf_procactive, 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 913b05fd35d9146c184e1903a26b6516f1660ca230fEric W. Biederman { } 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ctl_table s390dbf_dir_table[] = { 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .procname = "s390dbf", 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .maxlen = 0, 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .mode = S_IRUGO | S_IXUGO, 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .child = s390dbf_table, 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 923b05fd35d9146c184e1903a26b6516f1660ca230fEric W. Biederman { } 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9262b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensstatic struct ctl_table_header *s390dbf_sysctl_header; 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 92866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuvoid 92966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_stop_all(void) 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (debug_stoppable) 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_active = 0; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9363ab121ab18669226742891416fe7ecc86dadb047Michael Holzheuvoid debug_set_critical(void) 9373ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu{ 9383ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu debug_critical = 1; 9393ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu} 9403ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_event_common: 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - write debug entry with given size 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 94666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_entry_t* 94766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_event_common(debug_info_t * id, int level, const void *buf, int len) 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_entry_t *active; 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 95266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!debug_active || !id->areas) 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 9543ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (debug_critical) { 9553ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (!spin_trylock_irqsave(&id->lock, flags)) 9563ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu return NULL; 9573ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu } else 9583ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu spin_lock_irqsave(&id->lock, flags); 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active = get_active_entry(id); 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(DEBUG_DATA(active), 0, id->buf_size); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_finish_entry(id, active, level, 0); 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock, flags); 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return active; 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_exception_common: 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - write debug entry with given size and switch to next debug area 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 97366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_entry_t 97466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu*debug_exception_common(debug_info_t * id, int level, const void *buf, int len) 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_entry_t *active; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 97966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!debug_active || !id->areas) 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 9813ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (debug_critical) { 9823ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (!spin_trylock_irqsave(&id->lock, flags)) 9833ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu return NULL; 9843ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu } else 9853ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu spin_lock_irqsave(&id->lock, flags); 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active = get_active_entry(id); 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(DEBUG_DATA(active), 0, id->buf_size); 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size)); 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_finish_entry(id, active, level, 1); 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock, flags); 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return active; 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * counts arguments in format string for sprintf view 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9994448aaf0faafff3f275d15937c28b6346760e028Adrian Bunkstatic inline int 100066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_count_numargs(char *string) 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int numargs=0; 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while(*string) { 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(*string++=='%') 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numargs++; 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return(numargs); 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_sprintf_event: 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_entry_t* 101666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_sprintf_event(debug_info_t* id, int level,char *string,...) 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_list ap; 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int numargs,idx; 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_sprintf_entry_t *curr_event; 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_entry_t *active; 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((!id) || (level > id->level)) 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 102666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!debug_active || !id->areas) 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numargs=debug_count_numargs(string); 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10303ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (debug_critical) { 10313ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (!spin_trylock_irqsave(&id->lock, flags)) 10323ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu return NULL; 10333ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu } else 10343ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu spin_lock_irqsave(&id->lock, flags); 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active = get_active_entry(id); 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active); 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_start(ap,string); 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->string=string; 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(idx=0;idx<min(numargs,(int)(id->buf_size / sizeof(long))-1);idx++) 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[idx]=va_arg(ap,long); 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_end(ap); 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_finish_entry(id, active, level, 0); 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock, flags); 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return active; 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_sprintf_exception: 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 105266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_entry_t* 105366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_sprintf_exception(debug_info_t* id, int level,char *string,...) 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_list ap; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int numargs,idx; 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_sprintf_entry_t *curr_event; 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_entry_t *active; 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if((!id) || (level > id->level)) 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 106366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!debug_active || !id->areas) 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 10651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds numargs=debug_count_numargs(string); 10671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10683ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (debug_critical) { 10693ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (!spin_trylock_irqsave(&id->lock, flags)) 10703ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu return NULL; 10713ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu } else 10723ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu spin_lock_irqsave(&id->lock, flags); 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds active = get_active_entry(id); 10741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_start(ap,string); 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->string=string; 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(idx=0;idx<min(numargs,(int)(id->buf_size / sizeof(long))-1);idx++) 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[idx]=va_arg(ap,long); 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds va_end(ap); 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_finish_entry(id, active, level, 1); 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock, flags); 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return active; 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_init: 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * - is called exactly once to initialize the debug feature 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 109166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 109266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu__init debug_init(void) 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = 0; 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10960b4d414714f0d2f922d39424b0c5c82ad900a381Eric W. Biederman s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table); 1097e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_lock(&debug_mutex); 109866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL); 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds initialized = 1; 1100e11f0d04c6bc6bcf301bc60c060c4ac346e61885Christoph Hellwig mutex_unlock(&debug_mutex); 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_register_view: 11071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 110966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuint 111066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_register_view(debug_info_t * id, struct debug_view *view) 11111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = 0; 11131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 11141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 1115f4ae40a6a50a98ac23d4b285f739455e926a473eAl Viro umode_t mode; 111666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct dentry *pde; 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!id) 11191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 11209637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu mode = (id->mode | S_IFREG) & ~S_IXUGO; 11219637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu if (!(view->prolog_proc || view->format_proc || view->header_proc)) 11229637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu mode &= ~(S_IRUSR | S_IRGRP | S_IROTH); 11239637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu if (!view->input_proc) 11249637c3f318374e2fcc37e354f9782a705b517387Michael Holzheu mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); 112566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, 1126942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu id , &debug_file_ops); 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!pde){ 1128c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_err("Registering view %s/%s failed due to out of " 1129c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu "memory\n", id->name,view->name); 11301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -1; 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&id->lock, flags); 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 113566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!id->views[i]) 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i == DEBUG_MAX_VIEWS) { 1139c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_err("Registering view %s/%s would exceed the maximum " 1140c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu "number of views %i\n", id->name, view->name, i); 114166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debugfs_remove(pde); 11421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -1; 114366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } else { 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->views[i] = view; 114566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->debugfs_entries[i] = pde; 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock, flags); 114866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 11491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 11501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 11531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_unregister_view: 11541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 115666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuint 115766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_unregister_view(debug_info_t * id, struct debug_view *view) 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = 0; 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!id) 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&id->lock, flags); 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < DEBUG_MAX_VIEWS; i++) { 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (id->views[i] == view) 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (i == DEBUG_MAX_VIEWS) 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -1; 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 117366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debugfs_remove(id->debugfs_entries[i]); 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->views[i] = NULL; 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock, flags); 117766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 117866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return rc; 117966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 118066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 118166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic inline char * 118266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_get_user_string(const char __user *user_buf, size_t user_len) 118366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 118466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char* buffer; 118566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 118666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu buffer = kmalloc(user_len + 1, GFP_KERNEL); 118766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (!buffer) 118866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return ERR_PTR(-ENOMEM); 118966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (copy_from_user(buffer, user_buf, user_len) != 0) { 119066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(buffer); 119166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return ERR_PTR(-EFAULT); 119266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 119366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu /* got the string, now strip linefeed. */ 119466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (buffer[user_len - 1] == '\n') 119566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu buffer[user_len - 1] = 0; 119666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu else 119766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu buffer[user_len] = 0; 119866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return buffer; 119966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 120066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 120166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic inline int 120266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_get_uint(char *buf) 120366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 120466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int rc; 120566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 1206e7d2860b690d4f3bed6824757c540579638e3d1eAndré Goddard Rosa buf = skip_spaces(buf); 120766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = simple_strtoul(buf, &buf, 10); 120866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(*buf){ 120966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EINVAL; 121066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 12121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * functions for debug-views 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *********************************** 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 12181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * prints out actual debug level 12211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 122466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_prolog_pages_fn(debug_info_t * id, 12251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct debug_view *view, char *out_buf) 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 122766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return sprintf(out_buf, "%i\n", id->pages_per_area); 122866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 122966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 123066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu/* 123166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * reads new size (number of pages per debug area) 123266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu */ 123366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 123466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 123566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_input_pages_fn(debug_info_t * id, struct debug_view *view, 123666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct file *file, const char __user *user_buf, 123766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_len, loff_t * offset) 123866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 123966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char *str; 124066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int rc,new_pages; 124166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 124266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (user_len > 0x10000) 124366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu user_len = 0x10000; 124466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (*offset != 0){ 124566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EPIPE; 124666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto out; 124766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 124866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu str = debug_get_user_string(user_buf,user_len); 124966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(IS_ERR(str)){ 125066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = PTR_ERR(str); 125166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto out; 125266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 125366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu new_pages = debug_get_uint(str); 125466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(new_pages < 0){ 125566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EINVAL; 125666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto free_str; 125766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 125866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = debug_set_size(id,id->nr_areas, new_pages); 125966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(rc != 0){ 126066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EINVAL; 126166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto free_str; 126266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 126366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = user_len; 126466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufree_str: 126566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(str); 126666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 126766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu *offset += user_len; 126866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu return rc; /* number of input characters */ 126966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu} 127066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 127166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu/* 127266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu * prints out actual debug level 127366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu */ 127466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 127566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 127666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_prolog_level_fn(debug_info_t * id, struct debug_view *view, char *out_buf) 127766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu{ 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = 0; 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 128066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(id->level == DEBUG_OFF_LEVEL) { 128166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = sprintf(out_buf,"-\n"); 128266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 128366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu else { 128466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = sprintf(out_buf, "%i\n", id->level); 128566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * reads new debug level 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 129366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 129466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_input_level_fn(debug_info_t * id, struct debug_view *view, 129566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct file *file, const char __user *user_buf, 129666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_len, loff_t * offset) 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 129866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char *str; 129966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int rc,new_level; 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 130166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (user_len > 0x10000) 130266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu user_len = 0x10000; 130366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (*offset != 0){ 130466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EPIPE; 13051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 130666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 130766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu str = debug_get_user_string(user_buf,user_len); 130866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(IS_ERR(str)){ 130966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = PTR_ERR(str); 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 131266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(str[0] == '-'){ 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_set_level(id, DEBUG_OFF_LEVEL); 131466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = user_len; 131566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu goto free_str; 13161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 131766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu new_level = debug_get_uint(str); 13181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 131966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(new_level < 0) { 1320c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_warning("%s is not a valid level for a debug " 1321c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu "feature\n", str); 132266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EINVAL; 132366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } else { 132466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debug_set_level(id, new_level); 132566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = user_len; 132666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 132766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheufree_str: 132866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu kfree(str); 132966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 133066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu *offset += user_len; 13311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; /* number of input characters */ 13321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * flushes debug areas 13371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13392b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensstatic void debug_flush(debug_info_t* id, int area) 13401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 134266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int i,j; 13431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 134466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if(!id || !id->areas) 13451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 13461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_irqsave(&id->lock,flags); 13471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(area == DEBUG_FLUSH_ALL){ 13481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds id->active_area = 0; 134966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memset(id->active_entries, 0, id->nr_areas * sizeof(int)); 135066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for (i = 0; i < id->nr_areas; i++) { 135166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_pages[i] = 0; 135266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(j = 0; j < id->pages_per_area; j++) { 135366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memset(id->areas[i][j], 0, PAGE_SIZE); 135466a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 135566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 13561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if(area >= 0 && area < id->nr_areas) { 135766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_entries[area] = 0; 135866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu id->active_pages[area] = 0; 135966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu for(i = 0; i < id->pages_per_area; i++) { 136066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu memset(id->areas[area][i],0,PAGE_SIZE); 136166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 13621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock_irqrestore(&id->lock,flags); 13641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 13671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * view function: flushes debug areas 13681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 137066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 137166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_input_flush_fn(debug_info_t * id, struct debug_view *view, 137266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu struct file *file, const char __user *user_buf, 137366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu size_t user_len, loff_t * offset) 13741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char input_buf[1]; 137666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int rc = user_len; 137766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu 137866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (user_len > 0x10000) 137966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu user_len = 0x10000; 138066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu if (*offset != 0){ 138166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu rc = -EPIPE; 13821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 138366a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu } 13841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (copy_from_user(input_buf, user_buf, 1)){ 13851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = -EFAULT; 13861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 13871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(input_buf[0] == '-') { 13891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_flush(id, DEBUG_FLUSH_ALL); 13901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 13911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (isdigit(input_buf[0])) { 13931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int area = ((int) input_buf[0] - (int) '0'); 13941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds debug_flush(id, area); 13951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 13961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 13971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1398c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu pr_info("Flushing debug data failed because %c is not a valid " 1399c5612c1956597687e4bdf59f2649d20d60f5a2b6Michael Holzheu "area\n", input_buf[0]); 14001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 140166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuout: 140266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu *offset += user_len; 14031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; /* number of input characters */ 14041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * prints debug header in raw format 14081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 141166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_raw_header_fn(debug_info_t * id, struct debug_view *view, 141266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu int area, debug_entry_t * entry, char *out_buf) 14131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc; 14151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = sizeof(debug_entry_t); 14171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(out_buf,entry,sizeof(debug_entry_t)); 14181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 14191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * prints debug data in raw format 14231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 142566a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 142666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_raw_format_fn(debug_info_t * id, struct debug_view *view, 14271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *out_buf, const char *in_buf) 14281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc; 14301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = id->buf_size; 14321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(out_buf, in_buf, id->buf_size); 14331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 14341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * prints debug data in hex/ascii format 14381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 144066a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 144166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view, 144266a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char *out_buf, const char *in_buf) 14431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 14441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i, rc = 0; 14451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < id->buf_size; i++) { 14471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc += sprintf(out_buf + rc, "%02x ", 14481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((unsigned char *) in_buf)[i]); 14491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc += sprintf(out_buf + rc, "| "); 14511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < id->buf_size; i++) { 14521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char c = in_buf[i]; 14533ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu if (isascii(c) && isprint(c)) 14541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc += sprintf(out_buf + rc, "%c", c); 14553ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu else 14563ab121ab18669226742891416fe7ecc86dadb047Michael Holzheu rc += sprintf(out_buf + rc, "."); 14571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc += sprintf(out_buf + rc, "\n"); 14591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 14601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * prints header for debug entry 14641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 146666a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheuint 146766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_dflt_header_fn(debug_info_t * id, struct debug_view *view, 14681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int area, debug_entry_t * entry, char *out_buf) 14691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1470942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu struct timespec time_spec; 14711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *except_str; 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long caller; 14731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rc = 0; 14741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int level; 14751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds level = entry->id.fields.level; 1477b592e89ac9af521be164490e45c53c93e89c776fChristof Schmitt stck_to_timespec(entry->id.stck, &time_spec); 14781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (entry->id.fields.exception) 14801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds except_str = "*"; 14811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds except_str = "-"; 14831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN; 14841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ", 1485942eaabd5d77522223a311ed9bddaaa3cefde27dMichael Holzheu area, time_spec.tv_sec, time_spec.tv_nsec / 1000, level, 14861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds except_str, entry->id.fields.cpuid, (void *) caller); 14871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 14881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 14891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 14911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * prints debug data sprintf-formated: 14921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * debug_sprinf_event/exception calls must be used together with this view 14931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUG_SPRINTF_MAX_ARGS 10 14961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 149766a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheustatic int 149866a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheudebug_sprintf_format_fn(debug_info_t * id, struct debug_view *view, 149966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu char *out_buf, debug_sprintf_entry_t *curr_event) 15001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int num_longs, num_used_args = 0,i, rc = 0; 15021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int index[DEBUG_SPRINTF_MAX_ARGS]; 15031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* count of longs fit into one entry */ 15051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds num_longs = id->buf_size / sizeof(long); 15061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(num_longs < 1) 15081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; /* bufsize of entry too small */ 15091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if(num_longs == 1) { 15101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* no args, we use only the string */ 15111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds strcpy(out_buf, curr_event->string); 15121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = strlen(curr_event->string); 15131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto out; 15141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* number of arguments used for sprintf (without the format string) */ 15171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds num_used_args = min(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1)); 15181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(index,0, DEBUG_SPRINTF_MAX_ARGS * sizeof(int)); 15201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i = 0; i < num_used_args; i++) 15221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds index[i] = i; 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds rc = sprintf(out_buf, curr_event->string, curr_event->args[index[0]], 15251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[index[1]], curr_event->args[index[2]], 15261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[index[3]], curr_event->args[index[4]], 15271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[index[5]], curr_event->args[index[6]], 15281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[index[7]], curr_event->args[index[8]], 15291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds curr_event->args[index[9]]); 15301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsout: 15321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return rc; 15341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 15371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * clean up module 15381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 15392b67fc46061b2171fb8fbb55d1ac717abd533569Heiko Carstensstatic void __exit debug_exit(void) 15401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 154166a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheu debugfs_remove(debug_debugfs_root_entry); 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unregister_sysctl_table(s390dbf_sysctl_header); 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 15441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 15451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 15471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * module definitions 15481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 154966a464dbc8e0345b6f972b92bf1118e043d7c987Michael Holzheupostcore_initcall(debug_init); 15501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(debug_exit); 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 15521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_register); 15541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_unregister); 15551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_set_level); 15561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_stop_all); 15571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_register_view); 15581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_unregister_view); 15591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_event_common); 15601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_exception_common); 15611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_hex_ascii_view); 15621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_raw_view); 15631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_dflt_header_fn); 15641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_sprintf_view); 15651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_sprintf_exception); 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(debug_sprintf_event); 1567