debug.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286
  1. /*
  2. * arch/s390/kernel/debug.c
  3. * S/390 debug facility
  4. *
  5. * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH,
  6. * IBM Corporation
  7. * Author(s): Michael Holzheu (holzheu@de.ibm.com),
  8. * Holger Smolinski (Holger.Smolinski@de.ibm.com)
  9. *
  10. * Bugreports to: <Linux390@de.ibm.com>
  11. */
  12. #include <linux/config.h>
  13. #include <linux/stddef.h>
  14. #include <linux/kernel.h>
  15. #include <linux/errno.h>
  16. #include <linux/slab.h>
  17. #include <linux/ctype.h>
  18. #include <linux/sysctl.h>
  19. #include <asm/uaccess.h>
  20. #include <asm/semaphore.h>
  21. #include <linux/module.h>
  22. #include <linux/init.h>
  23. #include <asm/debug.h>
  24. #define DEBUG_PROLOG_ENTRY -1
  25. /* typedefs */
  26. typedef struct file_private_info {
  27. loff_t offset; /* offset of last read in file */
  28. int act_area; /* number of last formated area */
  29. int act_entry; /* last formated entry (offset */
  30. /* relative to beginning of last */
  31. /* formated area) */
  32. size_t act_entry_offset; /* up to this offset we copied */
  33. /* in last read the last formated */
  34. /* entry to userland */
  35. char temp_buf[2048]; /* buffer for output */
  36. debug_info_t *debug_info_org; /* original debug information */
  37. debug_info_t *debug_info_snap; /* snapshot of debug information */
  38. struct debug_view *view; /* used view of debug info */
  39. } file_private_info_t;
  40. typedef struct
  41. {
  42. char *string;
  43. /*
  44. * This assumes that all args are converted into longs
  45. * on L/390 this is the case for all types of parameter
  46. * except of floats, and long long (32 bit)
  47. *
  48. */
  49. long args[0];
  50. } debug_sprintf_entry_t;
  51. extern void tod_to_timeval(uint64_t todval, struct timeval *xtime);
  52. /* internal function prototyes */
  53. static int debug_init(void);
  54. static ssize_t debug_output(struct file *file, char __user *user_buf,
  55. size_t user_len, loff_t * offset);
  56. static ssize_t debug_input(struct file *file, const char __user *user_buf,
  57. size_t user_len, loff_t * offset);
  58. static int debug_open(struct inode *inode, struct file *file);
  59. static int debug_close(struct inode *inode, struct file *file);
  60. static debug_info_t* debug_info_create(char *name, int page_order, int nr_areas, int buf_size);
  61. static void debug_info_get(debug_info_t *);
  62. static void debug_info_put(debug_info_t *);
  63. static int debug_prolog_level_fn(debug_info_t * id,
  64. struct debug_view *view, char *out_buf);
  65. static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
  66. struct file *file, const char __user *user_buf,
  67. size_t user_buf_size, loff_t * offset);
  68. static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
  69. struct file *file, const char __user *user_buf,
  70. size_t user_buf_size, loff_t * offset);
  71. static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
  72. char *out_buf, const char *in_buf);
  73. static int debug_raw_format_fn(debug_info_t * id,
  74. struct debug_view *view, char *out_buf,
  75. const char *in_buf);
  76. static int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
  77. int area, debug_entry_t * entry, char *out_buf);
  78. static int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
  79. char *out_buf, debug_sprintf_entry_t *curr_event);
  80. /* globals */
  81. struct debug_view debug_raw_view = {
  82. "raw",
  83. NULL,
  84. &debug_raw_header_fn,
  85. &debug_raw_format_fn,
  86. NULL,
  87. NULL
  88. };
  89. struct debug_view debug_hex_ascii_view = {
  90. "hex_ascii",
  91. NULL,
  92. &debug_dflt_header_fn,
  93. &debug_hex_ascii_format_fn,
  94. NULL,
  95. NULL
  96. };
  97. struct debug_view debug_level_view = {
  98. "level",
  99. &debug_prolog_level_fn,
  100. NULL,
  101. NULL,
  102. &debug_input_level_fn,
  103. NULL
  104. };
  105. struct debug_view debug_flush_view = {
  106. "flush",
  107. NULL,
  108. NULL,
  109. NULL,
  110. &debug_input_flush_fn,
  111. NULL
  112. };
  113. struct debug_view debug_sprintf_view = {
  114. "sprintf",
  115. NULL,
  116. &debug_dflt_header_fn,
  117. (debug_format_proc_t*)&debug_sprintf_format_fn,
  118. NULL,
  119. NULL
  120. };
  121. unsigned int debug_feature_version = __DEBUG_FEATURE_VERSION;
  122. /* static globals */
  123. static debug_info_t *debug_area_first = NULL;
  124. static debug_info_t *debug_area_last = NULL;
  125. DECLARE_MUTEX(debug_lock);
  126. static int initialized;
  127. static struct file_operations debug_file_ops = {
  128. .owner = THIS_MODULE,
  129. .read = debug_output,
  130. .write = debug_input,
  131. .open = debug_open,
  132. .release = debug_close,
  133. };
  134. static struct proc_dir_entry *debug_proc_root_entry;
  135. /* functions */
  136. /*
  137. * debug_info_alloc
  138. * - alloc new debug-info
  139. */
  140. static debug_info_t* debug_info_alloc(char *name, int page_order,
  141. int nr_areas, int buf_size)
  142. {
  143. debug_info_t* rc;
  144. int i;
  145. /* alloc everything */
  146. rc = (debug_info_t*) kmalloc(sizeof(debug_info_t), GFP_ATOMIC);
  147. if(!rc)
  148. goto fail_malloc_rc;
  149. rc->active_entry = (int*)kmalloc(nr_areas * sizeof(int), GFP_ATOMIC);
  150. if(!rc->active_entry)
  151. goto fail_malloc_active_entry;
  152. memset(rc->active_entry, 0, nr_areas * sizeof(int));
  153. rc->areas = (debug_entry_t **) kmalloc(nr_areas *
  154. sizeof(debug_entry_t *),
  155. GFP_ATOMIC);
  156. if (!rc->areas)
  157. goto fail_malloc_areas;
  158. for (i = 0; i < nr_areas; i++) {
  159. rc->areas[i] = (debug_entry_t *) __get_free_pages(GFP_ATOMIC,
  160. page_order);
  161. if (!rc->areas[i]) {
  162. for (i--; i >= 0; i--) {
  163. free_pages((unsigned long) rc->areas[i],
  164. page_order);
  165. }
  166. goto fail_malloc_areas2;
  167. } else {
  168. memset(rc->areas[i], 0, PAGE_SIZE << page_order);
  169. }
  170. }
  171. /* initialize members */
  172. spin_lock_init(&rc->lock);
  173. rc->page_order = page_order;
  174. rc->nr_areas = nr_areas;
  175. rc->active_area = 0;
  176. rc->level = DEBUG_DEFAULT_LEVEL;
  177. rc->buf_size = buf_size;
  178. rc->entry_size = sizeof(debug_entry_t) + buf_size;
  179. strlcpy(rc->name, name, sizeof(rc->name));
  180. memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *));
  181. #ifdef CONFIG_PROC_FS
  182. memset(rc->proc_entries, 0 ,DEBUG_MAX_VIEWS *
  183. sizeof(struct proc_dir_entry*));
  184. #endif /* CONFIG_PROC_FS */
  185. atomic_set(&(rc->ref_count), 0);
  186. return rc;
  187. fail_malloc_areas2:
  188. kfree(rc->areas);
  189. fail_malloc_areas:
  190. kfree(rc->active_entry);
  191. fail_malloc_active_entry:
  192. kfree(rc);
  193. fail_malloc_rc:
  194. return NULL;
  195. }
  196. /*
  197. * debug_info_free
  198. * - free memory debug-info
  199. */
  200. static void debug_info_free(debug_info_t* db_info){
  201. int i;
  202. for (i = 0; i < db_info->nr_areas; i++) {
  203. free_pages((unsigned long) db_info->areas[i],
  204. db_info->page_order);
  205. }
  206. kfree(db_info->areas);
  207. kfree(db_info->active_entry);
  208. kfree(db_info);
  209. }
  210. /*
  211. * debug_info_create
  212. * - create new debug-info
  213. */
  214. static debug_info_t* debug_info_create(char *name, int page_order,
  215. int nr_areas, int buf_size)
  216. {
  217. debug_info_t* rc;
  218. rc = debug_info_alloc(name, page_order, nr_areas, buf_size);
  219. if(!rc)
  220. goto out;
  221. /* create proc rood directory */
  222. rc->proc_root_entry = proc_mkdir(rc->name, debug_proc_root_entry);
  223. /* append new element to linked list */
  224. if (debug_area_first == NULL) {
  225. /* first element in list */
  226. debug_area_first = rc;
  227. rc->prev = NULL;
  228. } else {
  229. /* append element to end of list */
  230. debug_area_last->next = rc;
  231. rc->prev = debug_area_last;
  232. }
  233. debug_area_last = rc;
  234. rc->next = NULL;
  235. debug_info_get(rc);
  236. out:
  237. return rc;
  238. }
  239. /*
  240. * debug_info_copy
  241. * - copy debug-info
  242. */
  243. static debug_info_t* debug_info_copy(debug_info_t* in)
  244. {
  245. int i;
  246. debug_info_t* rc;
  247. rc = debug_info_alloc(in->name, in->page_order,
  248. in->nr_areas, in->buf_size);
  249. if(!rc)
  250. goto out;
  251. for(i = 0; i < in->nr_areas; i++){
  252. memcpy(rc->areas[i],in->areas[i], PAGE_SIZE << in->page_order);
  253. }
  254. out:
  255. return rc;
  256. }
  257. /*
  258. * debug_info_get
  259. * - increments reference count for debug-info
  260. */
  261. static void debug_info_get(debug_info_t * db_info)
  262. {
  263. if (db_info)
  264. atomic_inc(&db_info->ref_count);
  265. }
  266. /*
  267. * debug_info_put:
  268. * - decreases reference count for debug-info and frees it if necessary
  269. */
  270. static void debug_info_put(debug_info_t *db_info)
  271. {
  272. int i;
  273. if (!db_info)
  274. return;
  275. if (atomic_dec_and_test(&db_info->ref_count)) {
  276. #ifdef DEBUG
  277. printk(KERN_INFO "debug: freeing debug area %p (%s)\n",
  278. db_info, db_info->name);
  279. #endif
  280. for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
  281. if (db_info->views[i] == NULL)
  282. continue;
  283. #ifdef CONFIG_PROC_FS
  284. remove_proc_entry(db_info->proc_entries[i]->name,
  285. db_info->proc_root_entry);
  286. #endif
  287. }
  288. #ifdef CONFIG_PROC_FS
  289. remove_proc_entry(db_info->proc_root_entry->name,
  290. debug_proc_root_entry);
  291. #endif
  292. if(db_info == debug_area_first)
  293. debug_area_first = db_info->next;
  294. if(db_info == debug_area_last)
  295. debug_area_last = db_info->prev;
  296. if(db_info->prev) db_info->prev->next = db_info->next;
  297. if(db_info->next) db_info->next->prev = db_info->prev;
  298. debug_info_free(db_info);
  299. }
  300. }
  301. /*
  302. * debug_format_entry:
  303. * - format one debug entry and return size of formated data
  304. */
  305. static int debug_format_entry(file_private_info_t *p_info)
  306. {
  307. debug_info_t *id_org = p_info->debug_info_org;
  308. debug_info_t *id_snap = p_info->debug_info_snap;
  309. struct debug_view *view = p_info->view;
  310. debug_entry_t *act_entry;
  311. size_t len = 0;
  312. if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
  313. /* print prolog */
  314. if (view->prolog_proc)
  315. len += view->prolog_proc(id_org, view,p_info->temp_buf);
  316. goto out;
  317. }
  318. act_entry = (debug_entry_t *) ((char*)id_snap->areas[p_info->act_area] +
  319. p_info->act_entry);
  320. if (act_entry->id.stck == 0LL)
  321. goto out; /* empty entry */
  322. if (view->header_proc)
  323. len += view->header_proc(id_org, view, p_info->act_area,
  324. act_entry, p_info->temp_buf + len);
  325. if (view->format_proc)
  326. len += view->format_proc(id_org, view, p_info->temp_buf + len,
  327. DEBUG_DATA(act_entry));
  328. out:
  329. return len;
  330. }
  331. /*
  332. * debug_next_entry:
  333. * - goto next entry in p_info
  334. */
  335. extern inline int debug_next_entry(file_private_info_t *p_info)
  336. {
  337. debug_info_t *id = p_info->debug_info_snap;
  338. if(p_info->act_entry == DEBUG_PROLOG_ENTRY){
  339. p_info->act_entry = 0;
  340. goto out;
  341. }
  342. if ((p_info->act_entry += id->entry_size)
  343. > ((PAGE_SIZE << (id->page_order))
  344. - id->entry_size)){
  345. /* next area */
  346. p_info->act_entry = 0;
  347. p_info->act_area++;
  348. if(p_info->act_area >= id->nr_areas)
  349. return 1;
  350. }
  351. out:
  352. return 0;
  353. }
  354. /*
  355. * debug_output:
  356. * - called for user read()
  357. * - copies formated debug entries to the user buffer
  358. */
  359. static ssize_t debug_output(struct file *file, /* file descriptor */
  360. char __user *user_buf, /* user buffer */
  361. size_t len, /* length of buffer */
  362. loff_t *offset) /* offset in the file */
  363. {
  364. size_t count = 0;
  365. size_t entry_offset, size = 0;
  366. file_private_info_t *p_info;
  367. p_info = ((file_private_info_t *) file->private_data);
  368. if (*offset != p_info->offset)
  369. return -EPIPE;
  370. if(p_info->act_area >= p_info->debug_info_snap->nr_areas)
  371. return 0;
  372. entry_offset = p_info->act_entry_offset;
  373. while(count < len){
  374. size = debug_format_entry(p_info);
  375. size = min((len - count), (size - entry_offset));
  376. if(size){
  377. if (copy_to_user(user_buf + count,
  378. p_info->temp_buf + entry_offset, size))
  379. return -EFAULT;
  380. }
  381. count += size;
  382. entry_offset = 0;
  383. if(count != len)
  384. if(debug_next_entry(p_info))
  385. goto out;
  386. }
  387. out:
  388. p_info->offset = *offset + count;
  389. p_info->act_entry_offset = size;
  390. *offset = p_info->offset;
  391. return count;
  392. }
  393. /*
  394. * debug_input:
  395. * - called for user write()
  396. * - calls input function of view
  397. */
  398. static ssize_t debug_input(struct file *file,
  399. const char __user *user_buf, size_t length,
  400. loff_t *offset)
  401. {
  402. int rc = 0;
  403. file_private_info_t *p_info;
  404. down(&debug_lock);
  405. p_info = ((file_private_info_t *) file->private_data);
  406. if (p_info->view->input_proc)
  407. rc = p_info->view->input_proc(p_info->debug_info_org,
  408. p_info->view, file, user_buf,
  409. length, offset);
  410. else
  411. rc = -EPERM;
  412. up(&debug_lock);
  413. return rc; /* number of input characters */
  414. }
  415. /*
  416. * debug_open:
  417. * - called for user open()
  418. * - copies formated output to private_data area of the file
  419. * handle
  420. */
  421. static int debug_open(struct inode *inode, struct file *file)
  422. {
  423. int i = 0, rc = 0;
  424. file_private_info_t *p_info;
  425. debug_info_t *debug_info, *debug_info_snapshot;
  426. #ifdef DEBUG
  427. printk("debug_open\n");
  428. #endif
  429. down(&debug_lock);
  430. /* find debug log and view */
  431. debug_info = debug_area_first;
  432. while(debug_info != NULL){
  433. for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
  434. if (debug_info->views[i] == NULL)
  435. continue;
  436. else if (debug_info->proc_entries[i] ==
  437. PDE(file->f_dentry->d_inode)) {
  438. goto found; /* found view ! */
  439. }
  440. }
  441. debug_info = debug_info->next;
  442. }
  443. /* no entry found */
  444. rc = -EINVAL;
  445. goto out;
  446. found:
  447. /* make snapshot of current debug areas to get it consistent */
  448. debug_info_snapshot = debug_info_copy(debug_info);
  449. if(!debug_info_snapshot){
  450. #ifdef DEBUG
  451. printk(KERN_ERR "debug_open: debug_info_copy failed (out of mem)\n");
  452. #endif
  453. rc = -ENOMEM;
  454. goto out;
  455. }
  456. if ((file->private_data =
  457. kmalloc(sizeof(file_private_info_t), GFP_ATOMIC)) == 0) {
  458. #ifdef DEBUG
  459. printk(KERN_ERR "debug_open: kmalloc failed\n");
  460. #endif
  461. debug_info_free(debug_info_snapshot);
  462. rc = -ENOMEM;
  463. goto out;
  464. }
  465. p_info = (file_private_info_t *) file->private_data;
  466. p_info->offset = 0;
  467. p_info->debug_info_snap = debug_info_snapshot;
  468. p_info->debug_info_org = debug_info;
  469. p_info->view = debug_info->views[i];
  470. p_info->act_area = 0;
  471. p_info->act_entry = DEBUG_PROLOG_ENTRY;
  472. p_info->act_entry_offset = 0;
  473. debug_info_get(debug_info);
  474. out:
  475. up(&debug_lock);
  476. return rc;
  477. }
  478. /*
  479. * debug_close:
  480. * - called for user close()
  481. * - deletes private_data area of the file handle
  482. */
  483. static int debug_close(struct inode *inode, struct file *file)
  484. {
  485. file_private_info_t *p_info;
  486. #ifdef DEBUG
  487. printk("debug_close\n");
  488. #endif
  489. p_info = (file_private_info_t *) file->private_data;
  490. debug_info_free(p_info->debug_info_snap);
  491. debug_info_put(p_info->debug_info_org);
  492. kfree(file->private_data);
  493. return 0; /* success */
  494. }
  495. /*
  496. * debug_register:
  497. * - creates and initializes debug area for the caller
  498. * - returns handle for debug area
  499. */
  500. debug_info_t *debug_register
  501. (char *name, int page_order, int nr_areas, int buf_size)
  502. {
  503. debug_info_t *rc = NULL;
  504. if (!initialized)
  505. BUG();
  506. down(&debug_lock);
  507. /* create new debug_info */
  508. rc = debug_info_create(name, page_order, nr_areas, buf_size);
  509. if(!rc)
  510. goto out;
  511. debug_register_view(rc, &debug_level_view);
  512. debug_register_view(rc, &debug_flush_view);
  513. #ifdef DEBUG
  514. printk(KERN_INFO
  515. "debug: reserved %d areas of %d pages for debugging %s\n",
  516. nr_areas, 1 << page_order, rc->name);
  517. #endif
  518. out:
  519. if (rc == NULL){
  520. printk(KERN_ERR "debug: debug_register failed for %s\n",name);
  521. }
  522. up(&debug_lock);
  523. return rc;
  524. }
  525. /*
  526. * debug_unregister:
  527. * - give back debug area
  528. */
  529. void debug_unregister(debug_info_t * id)
  530. {
  531. if (!id)
  532. goto out;
  533. down(&debug_lock);
  534. #ifdef DEBUG
  535. printk(KERN_INFO "debug: unregistering %s\n", id->name);
  536. #endif
  537. debug_info_put(id);
  538. up(&debug_lock);
  539. out:
  540. return;
  541. }
  542. /*
  543. * debug_set_level:
  544. * - set actual debug level
  545. */
  546. void debug_set_level(debug_info_t* id, int new_level)
  547. {
  548. unsigned long flags;
  549. if(!id)
  550. return;
  551. spin_lock_irqsave(&id->lock,flags);
  552. if(new_level == DEBUG_OFF_LEVEL){
  553. id->level = DEBUG_OFF_LEVEL;
  554. printk(KERN_INFO "debug: %s: switched off\n",id->name);
  555. } else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) {
  556. printk(KERN_INFO
  557. "debug: %s: level %i is out of range (%i - %i)\n",
  558. id->name, new_level, 0, DEBUG_MAX_LEVEL);
  559. } else {
  560. id->level = new_level;
  561. #ifdef DEBUG
  562. printk(KERN_INFO
  563. "debug: %s: new level %i\n",id->name,id->level);
  564. #endif
  565. }
  566. spin_unlock_irqrestore(&id->lock,flags);
  567. }
  568. /*
  569. * proceed_active_entry:
  570. * - set active entry to next in the ring buffer
  571. */
  572. extern inline void proceed_active_entry(debug_info_t * id)
  573. {
  574. if ((id->active_entry[id->active_area] += id->entry_size)
  575. > ((PAGE_SIZE << (id->page_order)) - id->entry_size))
  576. id->active_entry[id->active_area] = 0;
  577. }
  578. /*
  579. * proceed_active_area:
  580. * - set active area to next in the ring buffer
  581. */
  582. extern inline void proceed_active_area(debug_info_t * id)
  583. {
  584. id->active_area++;
  585. id->active_area = id->active_area % id->nr_areas;
  586. }
  587. /*
  588. * get_active_entry:
  589. */
  590. extern inline debug_entry_t *get_active_entry(debug_info_t * id)
  591. {
  592. return (debug_entry_t *) ((char *) id->areas[id->active_area] +
  593. id->active_entry[id->active_area]);
  594. }
  595. /*
  596. * debug_finish_entry:
  597. * - set timestamp, caller address, cpu number etc.
  598. */
  599. extern inline void debug_finish_entry(debug_info_t * id, debug_entry_t* active,
  600. int level, int exception)
  601. {
  602. STCK(active->id.stck);
  603. active->id.fields.cpuid = smp_processor_id();
  604. active->caller = __builtin_return_address(0);
  605. active->id.fields.exception = exception;
  606. active->id.fields.level = level;
  607. proceed_active_entry(id);
  608. if(exception)
  609. proceed_active_area(id);
  610. }
  611. static int debug_stoppable=1;
  612. static int debug_active=1;
  613. #define CTL_S390DBF 5677
  614. #define CTL_S390DBF_STOPPABLE 5678
  615. #define CTL_S390DBF_ACTIVE 5679
  616. /*
  617. * proc handler for the running debug_active sysctl
  618. * always allow read, allow write only if debug_stoppable is set or
  619. * if debug_active is already off
  620. */
  621. static int s390dbf_procactive(ctl_table *table, int write, struct file *filp,
  622. void __user *buffer, size_t *lenp, loff_t *ppos)
  623. {
  624. if (!write || debug_stoppable || !debug_active)
  625. return proc_dointvec(table, write, filp, buffer, lenp, ppos);
  626. else
  627. return 0;
  628. }
  629. static struct ctl_table s390dbf_table[] = {
  630. {
  631. .ctl_name = CTL_S390DBF_STOPPABLE,
  632. .procname = "debug_stoppable",
  633. .data = &debug_stoppable,
  634. .maxlen = sizeof(int),
  635. .mode = S_IRUGO | S_IWUSR,
  636. .proc_handler = &proc_dointvec,
  637. .strategy = &sysctl_intvec,
  638. },
  639. {
  640. .ctl_name = CTL_S390DBF_ACTIVE,
  641. .procname = "debug_active",
  642. .data = &debug_active,
  643. .maxlen = sizeof(int),
  644. .mode = S_IRUGO | S_IWUSR,
  645. .proc_handler = &s390dbf_procactive,
  646. .strategy = &sysctl_intvec,
  647. },
  648. { .ctl_name = 0 }
  649. };
  650. static struct ctl_table s390dbf_dir_table[] = {
  651. {
  652. .ctl_name = CTL_S390DBF,
  653. .procname = "s390dbf",
  654. .maxlen = 0,
  655. .mode = S_IRUGO | S_IXUGO,
  656. .child = s390dbf_table,
  657. },
  658. { .ctl_name = 0 }
  659. };
  660. struct ctl_table_header *s390dbf_sysctl_header;
  661. void debug_stop_all(void)
  662. {
  663. if (debug_stoppable)
  664. debug_active = 0;
  665. }
  666. /*
  667. * debug_event_common:
  668. * - write debug entry with given size
  669. */
  670. debug_entry_t *debug_event_common(debug_info_t * id, int level, const void *buf,
  671. int len)
  672. {
  673. unsigned long flags;
  674. debug_entry_t *active;
  675. if (!debug_active)
  676. return NULL;
  677. spin_lock_irqsave(&id->lock, flags);
  678. active = get_active_entry(id);
  679. memset(DEBUG_DATA(active), 0, id->buf_size);
  680. memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
  681. debug_finish_entry(id, active, level, 0);
  682. spin_unlock_irqrestore(&id->lock, flags);
  683. return active;
  684. }
  685. /*
  686. * debug_exception_common:
  687. * - write debug entry with given size and switch to next debug area
  688. */
  689. debug_entry_t *debug_exception_common(debug_info_t * id, int level,
  690. const void *buf, int len)
  691. {
  692. unsigned long flags;
  693. debug_entry_t *active;
  694. if (!debug_active)
  695. return NULL;
  696. spin_lock_irqsave(&id->lock, flags);
  697. active = get_active_entry(id);
  698. memset(DEBUG_DATA(active), 0, id->buf_size);
  699. memcpy(DEBUG_DATA(active), buf, min(len, id->buf_size));
  700. debug_finish_entry(id, active, level, 1);
  701. spin_unlock_irqrestore(&id->lock, flags);
  702. return active;
  703. }
  704. /*
  705. * counts arguments in format string for sprintf view
  706. */
  707. extern inline int debug_count_numargs(char *string)
  708. {
  709. int numargs=0;
  710. while(*string) {
  711. if(*string++=='%')
  712. numargs++;
  713. }
  714. return(numargs);
  715. }
  716. /*
  717. * debug_sprintf_event:
  718. */
  719. debug_entry_t *debug_sprintf_event(debug_info_t* id,
  720. int level,char *string,...)
  721. {
  722. va_list ap;
  723. int numargs,idx;
  724. unsigned long flags;
  725. debug_sprintf_entry_t *curr_event;
  726. debug_entry_t *active;
  727. if((!id) || (level > id->level))
  728. return NULL;
  729. if (!debug_active)
  730. return NULL;
  731. numargs=debug_count_numargs(string);
  732. spin_lock_irqsave(&id->lock, flags);
  733. active = get_active_entry(id);
  734. curr_event=(debug_sprintf_entry_t *) DEBUG_DATA(active);
  735. va_start(ap,string);
  736. curr_event->string=string;
  737. for(idx=0;idx<min(numargs,(int)(id->buf_size / sizeof(long))-1);idx++)
  738. curr_event->args[idx]=va_arg(ap,long);
  739. va_end(ap);
  740. debug_finish_entry(id, active, level, 0);
  741. spin_unlock_irqrestore(&id->lock, flags);
  742. return active;
  743. }
  744. /*
  745. * debug_sprintf_exception:
  746. */
  747. debug_entry_t *debug_sprintf_exception(debug_info_t* id,
  748. int level,char *string,...)
  749. {
  750. va_list ap;
  751. int numargs,idx;
  752. unsigned long flags;
  753. debug_sprintf_entry_t *curr_event;
  754. debug_entry_t *active;
  755. if((!id) || (level > id->level))
  756. return NULL;
  757. if (!debug_active)
  758. return NULL;
  759. numargs=debug_count_numargs(string);
  760. spin_lock_irqsave(&id->lock, flags);
  761. active = get_active_entry(id);
  762. curr_event=(debug_sprintf_entry_t *)DEBUG_DATA(active);
  763. va_start(ap,string);
  764. curr_event->string=string;
  765. for(idx=0;idx<min(numargs,(int)(id->buf_size / sizeof(long))-1);idx++)
  766. curr_event->args[idx]=va_arg(ap,long);
  767. va_end(ap);
  768. debug_finish_entry(id, active, level, 1);
  769. spin_unlock_irqrestore(&id->lock, flags);
  770. return active;
  771. }
  772. /*
  773. * debug_init:
  774. * - is called exactly once to initialize the debug feature
  775. */
  776. static int __init debug_init(void)
  777. {
  778. int rc = 0;
  779. s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table, 1);
  780. down(&debug_lock);
  781. #ifdef CONFIG_PROC_FS
  782. debug_proc_root_entry = proc_mkdir(DEBUG_DIR_ROOT, NULL);
  783. #endif /* CONFIG_PROC_FS */
  784. printk(KERN_INFO "debug: Initialization complete\n");
  785. initialized = 1;
  786. up(&debug_lock);
  787. return rc;
  788. }
  789. /*
  790. * debug_register_view:
  791. */
  792. int debug_register_view(debug_info_t * id, struct debug_view *view)
  793. {
  794. int rc = 0;
  795. int i;
  796. unsigned long flags;
  797. mode_t mode = S_IFREG;
  798. struct proc_dir_entry *pde;
  799. if (!id)
  800. goto out;
  801. if (view->prolog_proc || view->format_proc || view->header_proc)
  802. mode |= S_IRUSR;
  803. if (view->input_proc)
  804. mode |= S_IWUSR;
  805. pde = create_proc_entry(view->name, mode, id->proc_root_entry);
  806. if (!pde){
  807. printk(KERN_WARNING "debug: create_proc_entry() failed! Cannot register view %s/%s\n", id->name,view->name);
  808. rc = -1;
  809. goto out;
  810. }
  811. spin_lock_irqsave(&id->lock, flags);
  812. for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
  813. if (id->views[i] == NULL)
  814. break;
  815. }
  816. if (i == DEBUG_MAX_VIEWS) {
  817. printk(KERN_WARNING "debug: cannot register view %s/%s\n",
  818. id->name,view->name);
  819. printk(KERN_WARNING
  820. "debug: maximum number of views reached (%i)!\n", i);
  821. remove_proc_entry(pde->name, id->proc_root_entry);
  822. rc = -1;
  823. }
  824. else {
  825. id->views[i] = view;
  826. pde->proc_fops = &debug_file_ops;
  827. id->proc_entries[i] = pde;
  828. }
  829. spin_unlock_irqrestore(&id->lock, flags);
  830. out:
  831. return rc;
  832. }
  833. /*
  834. * debug_unregister_view:
  835. */
  836. int debug_unregister_view(debug_info_t * id, struct debug_view *view)
  837. {
  838. int rc = 0;
  839. int i;
  840. unsigned long flags;
  841. if (!id)
  842. goto out;
  843. spin_lock_irqsave(&id->lock, flags);
  844. for (i = 0; i < DEBUG_MAX_VIEWS; i++) {
  845. if (id->views[i] == view)
  846. break;
  847. }
  848. if (i == DEBUG_MAX_VIEWS)
  849. rc = -1;
  850. else {
  851. #ifdef CONFIG_PROC_FS
  852. remove_proc_entry(id->proc_entries[i]->name,
  853. id->proc_root_entry);
  854. #endif
  855. id->views[i] = NULL;
  856. rc = 0;
  857. }
  858. spin_unlock_irqrestore(&id->lock, flags);
  859. out:
  860. return rc;
  861. }
  862. /*
  863. * functions for debug-views
  864. ***********************************
  865. */
  866. /*
  867. * prints out actual debug level
  868. */
  869. static int debug_prolog_level_fn(debug_info_t * id,
  870. struct debug_view *view, char *out_buf)
  871. {
  872. int rc = 0;
  873. if(id->level == -1) rc = sprintf(out_buf,"-\n");
  874. else rc = sprintf(out_buf, "%i\n", id->level);
  875. return rc;
  876. }
  877. /*
  878. * reads new debug level
  879. */
  880. static int debug_input_level_fn(debug_info_t * id, struct debug_view *view,
  881. struct file *file, const char __user *user_buf,
  882. size_t in_buf_size, loff_t * offset)
  883. {
  884. char input_buf[1];
  885. int rc = in_buf_size;
  886. if (*offset != 0)
  887. goto out;
  888. if (copy_from_user(input_buf, user_buf, 1)){
  889. rc = -EFAULT;
  890. goto out;
  891. }
  892. if (isdigit(input_buf[0])) {
  893. int new_level = ((int) input_buf[0] - (int) '0');
  894. debug_set_level(id, new_level);
  895. } else if(input_buf[0] == '-') {
  896. debug_set_level(id, DEBUG_OFF_LEVEL);
  897. } else {
  898. printk(KERN_INFO "debug: level `%c` is not valid\n",
  899. input_buf[0]);
  900. }
  901. out:
  902. *offset += in_buf_size;
  903. return rc; /* number of input characters */
  904. }
  905. /*
  906. * flushes debug areas
  907. */
  908. void debug_flush(debug_info_t* id, int area)
  909. {
  910. unsigned long flags;
  911. int i;
  912. if(!id)
  913. return;
  914. spin_lock_irqsave(&id->lock,flags);
  915. if(area == DEBUG_FLUSH_ALL){
  916. id->active_area = 0;
  917. memset(id->active_entry, 0, id->nr_areas * sizeof(int));
  918. for (i = 0; i < id->nr_areas; i++)
  919. memset(id->areas[i], 0, PAGE_SIZE << id->page_order);
  920. printk(KERN_INFO "debug: %s: all areas flushed\n",id->name);
  921. } else if(area >= 0 && area < id->nr_areas) {
  922. id->active_entry[area] = 0;
  923. memset(id->areas[area], 0, PAGE_SIZE << id->page_order);
  924. printk(KERN_INFO
  925. "debug: %s: area %i has been flushed\n",
  926. id->name, area);
  927. } else {
  928. printk(KERN_INFO
  929. "debug: %s: area %i cannot be flushed (range: %i - %i)\n",
  930. id->name, area, 0, id->nr_areas-1);
  931. }
  932. spin_unlock_irqrestore(&id->lock,flags);
  933. }
  934. /*
  935. * view function: flushes debug areas
  936. */
  937. static int debug_input_flush_fn(debug_info_t * id, struct debug_view *view,
  938. struct file *file, const char __user *user_buf,
  939. size_t in_buf_size, loff_t * offset)
  940. {
  941. char input_buf[1];
  942. int rc = in_buf_size;
  943. if (*offset != 0)
  944. goto out;
  945. if (copy_from_user(input_buf, user_buf, 1)){
  946. rc = -EFAULT;
  947. goto out;
  948. }
  949. if(input_buf[0] == '-') {
  950. debug_flush(id, DEBUG_FLUSH_ALL);
  951. goto out;
  952. }
  953. if (isdigit(input_buf[0])) {
  954. int area = ((int) input_buf[0] - (int) '0');
  955. debug_flush(id, area);
  956. goto out;
  957. }
  958. printk(KERN_INFO "debug: area `%c` is not valid\n", input_buf[0]);
  959. out:
  960. *offset += in_buf_size;
  961. return rc; /* number of input characters */
  962. }
  963. /*
  964. * prints debug header in raw format
  965. */
  966. int debug_raw_header_fn(debug_info_t * id, struct debug_view *view,
  967. int area, debug_entry_t * entry, char *out_buf)
  968. {
  969. int rc;
  970. rc = sizeof(debug_entry_t);
  971. memcpy(out_buf,entry,sizeof(debug_entry_t));
  972. return rc;
  973. }
  974. /*
  975. * prints debug data in raw format
  976. */
  977. static int debug_raw_format_fn(debug_info_t * id, struct debug_view *view,
  978. char *out_buf, const char *in_buf)
  979. {
  980. int rc;
  981. rc = id->buf_size;
  982. memcpy(out_buf, in_buf, id->buf_size);
  983. return rc;
  984. }
  985. /*
  986. * prints debug data in hex/ascii format
  987. */
  988. static int debug_hex_ascii_format_fn(debug_info_t * id, struct debug_view *view,
  989. char *out_buf, const char *in_buf)
  990. {
  991. int i, rc = 0;
  992. for (i = 0; i < id->buf_size; i++) {
  993. rc += sprintf(out_buf + rc, "%02x ",
  994. ((unsigned char *) in_buf)[i]);
  995. }
  996. rc += sprintf(out_buf + rc, "| ");
  997. for (i = 0; i < id->buf_size; i++) {
  998. unsigned char c = in_buf[i];
  999. if (!isprint(c))
  1000. rc += sprintf(out_buf + rc, ".");
  1001. else
  1002. rc += sprintf(out_buf + rc, "%c", c);
  1003. }
  1004. rc += sprintf(out_buf + rc, "\n");
  1005. return rc;
  1006. }
  1007. /*
  1008. * prints header for debug entry
  1009. */
  1010. int debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
  1011. int area, debug_entry_t * entry, char *out_buf)
  1012. {
  1013. struct timeval time_val;
  1014. unsigned long long time;
  1015. char *except_str;
  1016. unsigned long caller;
  1017. int rc = 0;
  1018. unsigned int level;
  1019. level = entry->id.fields.level;
  1020. time = entry->id.stck;
  1021. /* adjust todclock to 1970 */
  1022. time -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
  1023. tod_to_timeval(time, &time_val);
  1024. if (entry->id.fields.exception)
  1025. except_str = "*";
  1026. else
  1027. except_str = "-";
  1028. caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN;
  1029. rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ",
  1030. area, time_val.tv_sec, time_val.tv_usec, level,
  1031. except_str, entry->id.fields.cpuid, (void *) caller);
  1032. return rc;
  1033. }
  1034. /*
  1035. * prints debug data sprintf-formated:
  1036. * debug_sprinf_event/exception calls must be used together with this view
  1037. */
  1038. #define DEBUG_SPRINTF_MAX_ARGS 10
  1039. int debug_sprintf_format_fn(debug_info_t * id, struct debug_view *view,
  1040. char *out_buf, debug_sprintf_entry_t *curr_event)
  1041. {
  1042. int num_longs, num_used_args = 0,i, rc = 0;
  1043. int index[DEBUG_SPRINTF_MAX_ARGS];
  1044. /* count of longs fit into one entry */
  1045. num_longs = id->buf_size / sizeof(long);
  1046. if(num_longs < 1)
  1047. goto out; /* bufsize of entry too small */
  1048. if(num_longs == 1) {
  1049. /* no args, we use only the string */
  1050. strcpy(out_buf, curr_event->string);
  1051. rc = strlen(curr_event->string);
  1052. goto out;
  1053. }
  1054. /* number of arguments used for sprintf (without the format string) */
  1055. num_used_args = min(DEBUG_SPRINTF_MAX_ARGS, (num_longs - 1));
  1056. memset(index,0, DEBUG_SPRINTF_MAX_ARGS * sizeof(int));
  1057. for(i = 0; i < num_used_args; i++)
  1058. index[i] = i;
  1059. rc = sprintf(out_buf, curr_event->string, curr_event->args[index[0]],
  1060. curr_event->args[index[1]], curr_event->args[index[2]],
  1061. curr_event->args[index[3]], curr_event->args[index[4]],
  1062. curr_event->args[index[5]], curr_event->args[index[6]],
  1063. curr_event->args[index[7]], curr_event->args[index[8]],
  1064. curr_event->args[index[9]]);
  1065. out:
  1066. return rc;
  1067. }
  1068. /*
  1069. * clean up module
  1070. */
  1071. void __exit debug_exit(void)
  1072. {
  1073. #ifdef DEBUG
  1074. printk("debug_cleanup_module: \n");
  1075. #endif
  1076. #ifdef CONFIG_PROC_FS
  1077. remove_proc_entry(debug_proc_root_entry->name, NULL);
  1078. #endif /* CONFIG_PROC_FS */
  1079. unregister_sysctl_table(s390dbf_sysctl_header);
  1080. return;
  1081. }
  1082. /*
  1083. * module definitions
  1084. */
  1085. core_initcall(debug_init);
  1086. module_exit(debug_exit);
  1087. MODULE_LICENSE("GPL");
  1088. EXPORT_SYMBOL(debug_register);
  1089. EXPORT_SYMBOL(debug_unregister);
  1090. EXPORT_SYMBOL(debug_set_level);
  1091. EXPORT_SYMBOL(debug_stop_all);
  1092. EXPORT_SYMBOL(debug_register_view);
  1093. EXPORT_SYMBOL(debug_unregister_view);
  1094. EXPORT_SYMBOL(debug_event_common);
  1095. EXPORT_SYMBOL(debug_exception_common);
  1096. EXPORT_SYMBOL(debug_hex_ascii_view);
  1097. EXPORT_SYMBOL(debug_raw_view);
  1098. EXPORT_SYMBOL(debug_dflt_header_fn);
  1099. EXPORT_SYMBOL(debug_sprintf_view);
  1100. EXPORT_SYMBOL(debug_sprintf_exception);
  1101. EXPORT_SYMBOL(debug_sprintf_event);