.. | .. |
---|
2 | 2 | /* |
---|
3 | 3 | * S/390 debug facility |
---|
4 | 4 | * |
---|
5 | | - * Copyright IBM Corp. 1999, 2012 |
---|
| 5 | + * Copyright IBM Corp. 1999, 2020 |
---|
6 | 6 | * |
---|
7 | 7 | * Author(s): Michael Holzheu (holzheu@de.ibm.com), |
---|
8 | 8 | * Holger Smolinski (Holger.Smolinski@de.ibm.com) |
---|
.. | .. |
---|
24 | 24 | #include <linux/export.h> |
---|
25 | 25 | #include <linux/init.h> |
---|
26 | 26 | #include <linux/fs.h> |
---|
| 27 | +#include <linux/minmax.h> |
---|
27 | 28 | #include <linux/debugfs.h> |
---|
28 | 29 | |
---|
29 | 30 | #include <asm/debug.h> |
---|
.. | .. |
---|
90 | 91 | size_t user_buf_size, loff_t *offset); |
---|
91 | 92 | static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, |
---|
92 | 93 | char *out_buf, const char *in_buf); |
---|
93 | | -static int debug_raw_format_fn(debug_info_t *id, |
---|
94 | | - struct debug_view *view, char *out_buf, |
---|
95 | | - const char *in_buf); |
---|
96 | | -static int debug_raw_header_fn(debug_info_t *id, struct debug_view *view, |
---|
97 | | - int area, debug_entry_t *entry, char *out_buf); |
---|
98 | | - |
---|
99 | 94 | static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, |
---|
100 | 95 | char *out_buf, debug_sprintf_entry_t *curr_event); |
---|
| 96 | +static void debug_areas_swap(debug_info_t *a, debug_info_t *b); |
---|
| 97 | +static void debug_events_append(debug_info_t *dest, debug_info_t *src); |
---|
101 | 98 | |
---|
102 | 99 | /* globals */ |
---|
103 | | - |
---|
104 | | -struct debug_view debug_raw_view = { |
---|
105 | | - "raw", |
---|
106 | | - NULL, |
---|
107 | | - &debug_raw_header_fn, |
---|
108 | | - &debug_raw_format_fn, |
---|
109 | | - NULL, |
---|
110 | | - NULL |
---|
111 | | -}; |
---|
112 | | -EXPORT_SYMBOL(debug_raw_view); |
---|
113 | 100 | |
---|
114 | 101 | struct debug_view debug_hex_ascii_view = { |
---|
115 | 102 | "hex_ascii", |
---|
.. | .. |
---|
327 | 314 | goto out; |
---|
328 | 315 | |
---|
329 | 316 | rc->mode = mode & ~S_IFMT; |
---|
330 | | - |
---|
331 | | - /* create root directory */ |
---|
332 | | - rc->debugfs_root_entry = debugfs_create_dir(rc->name, |
---|
333 | | - debug_debugfs_root_entry); |
---|
334 | | - |
---|
335 | | - /* append new element to linked list */ |
---|
336 | | - if (!debug_area_first) { |
---|
337 | | - /* first element in list */ |
---|
338 | | - debug_area_first = rc; |
---|
339 | | - rc->prev = NULL; |
---|
340 | | - } else { |
---|
341 | | - /* append element to end of list */ |
---|
342 | | - debug_area_last->next = rc; |
---|
343 | | - rc->prev = debug_area_last; |
---|
344 | | - } |
---|
345 | | - debug_area_last = rc; |
---|
346 | | - rc->next = NULL; |
---|
347 | | - |
---|
348 | 317 | refcount_set(&rc->ref_count, 1); |
---|
349 | 318 | out: |
---|
350 | 319 | return rc; |
---|
.. | .. |
---|
404 | 373 | */ |
---|
405 | 374 | static void debug_info_put(debug_info_t *db_info) |
---|
406 | 375 | { |
---|
407 | | - int i; |
---|
408 | | - |
---|
409 | 376 | if (!db_info) |
---|
410 | 377 | return; |
---|
411 | | - if (refcount_dec_and_test(&db_info->ref_count)) { |
---|
412 | | - for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
---|
413 | | - if (!db_info->views[i]) |
---|
414 | | - continue; |
---|
415 | | - debugfs_remove(db_info->debugfs_entries[i]); |
---|
416 | | - } |
---|
417 | | - debugfs_remove(db_info->debugfs_root_entry); |
---|
418 | | - if (db_info == debug_area_first) |
---|
419 | | - debug_area_first = db_info->next; |
---|
420 | | - if (db_info == debug_area_last) |
---|
421 | | - debug_area_last = db_info->prev; |
---|
422 | | - if (db_info->prev) |
---|
423 | | - db_info->prev->next = db_info->next; |
---|
424 | | - if (db_info->next) |
---|
425 | | - db_info->next->prev = db_info->prev; |
---|
| 378 | + if (refcount_dec_and_test(&db_info->ref_count)) |
---|
426 | 379 | debug_info_free(db_info); |
---|
427 | | - } |
---|
428 | 380 | } |
---|
429 | 381 | |
---|
430 | 382 | /* |
---|
.. | .. |
---|
449 | 401 | act_entry = (debug_entry_t *) ((char *)id_snap->areas[p_info->act_area] |
---|
450 | 402 | [p_info->act_page] + p_info->act_entry); |
---|
451 | 403 | |
---|
452 | | - if (act_entry->id.stck == 0LL) |
---|
| 404 | + if (act_entry->clock == 0LL) |
---|
453 | 405 | goto out; /* empty entry */ |
---|
454 | 406 | if (view->header_proc) |
---|
455 | 407 | len += view->header_proc(id_snap, view, p_info->act_area, |
---|
.. | .. |
---|
648 | 600 | return 0; /* success */ |
---|
649 | 601 | } |
---|
650 | 602 | |
---|
651 | | -/* |
---|
652 | | - * debug_register_mode: |
---|
653 | | - * - Creates and initializes debug area for the caller |
---|
654 | | - * The mode parameter allows to specify access rights for the s390dbf files |
---|
655 | | - * - Returns handle for debug area |
---|
| 603 | +/* Create debugfs entries and add to internal list. */ |
---|
| 604 | +static void _debug_register(debug_info_t *id) |
---|
| 605 | +{ |
---|
| 606 | + /* create root directory */ |
---|
| 607 | + id->debugfs_root_entry = debugfs_create_dir(id->name, |
---|
| 608 | + debug_debugfs_root_entry); |
---|
| 609 | + |
---|
| 610 | + /* append new element to linked list */ |
---|
| 611 | + if (!debug_area_first) { |
---|
| 612 | + /* first element in list */ |
---|
| 613 | + debug_area_first = id; |
---|
| 614 | + id->prev = NULL; |
---|
| 615 | + } else { |
---|
| 616 | + /* append element to end of list */ |
---|
| 617 | + debug_area_last->next = id; |
---|
| 618 | + id->prev = debug_area_last; |
---|
| 619 | + } |
---|
| 620 | + debug_area_last = id; |
---|
| 621 | + id->next = NULL; |
---|
| 622 | + |
---|
| 623 | + debug_register_view(id, &debug_level_view); |
---|
| 624 | + debug_register_view(id, &debug_flush_view); |
---|
| 625 | + debug_register_view(id, &debug_pages_view); |
---|
| 626 | +} |
---|
| 627 | + |
---|
| 628 | +/** |
---|
| 629 | + * debug_register_mode() - creates and initializes debug area. |
---|
| 630 | + * |
---|
| 631 | + * @name: Name of debug log (e.g. used for debugfs entry) |
---|
| 632 | + * @pages_per_area: Number of pages, which will be allocated per area |
---|
| 633 | + * @nr_areas: Number of debug areas |
---|
| 634 | + * @buf_size: Size of data area in each debug entry |
---|
| 635 | + * @mode: File mode for debugfs files. E.g. S_IRWXUGO |
---|
| 636 | + * @uid: User ID for debugfs files. Currently only 0 is supported. |
---|
| 637 | + * @gid: Group ID for debugfs files. Currently only 0 is supported. |
---|
| 638 | + * |
---|
| 639 | + * Return: |
---|
| 640 | + * - Handle for generated debug area |
---|
| 641 | + * - %NULL if register failed |
---|
| 642 | + * |
---|
| 643 | + * Allocates memory for a debug log. |
---|
| 644 | + * Must not be called within an interrupt handler. |
---|
656 | 645 | */ |
---|
657 | 646 | debug_info_t *debug_register_mode(const char *name, int pages_per_area, |
---|
658 | 647 | int nr_areas, int buf_size, umode_t mode, |
---|
.. | .. |
---|
665 | 654 | if ((uid != 0) || (gid != 0)) |
---|
666 | 655 | pr_warn("Root becomes the owner of all s390dbf files in sysfs\n"); |
---|
667 | 656 | BUG_ON(!initialized); |
---|
668 | | - mutex_lock(&debug_mutex); |
---|
669 | 657 | |
---|
670 | 658 | /* create new debug_info */ |
---|
671 | 659 | rc = debug_info_create(name, pages_per_area, nr_areas, buf_size, mode); |
---|
672 | | - if (!rc) |
---|
673 | | - goto out; |
---|
674 | | - debug_register_view(rc, &debug_level_view); |
---|
675 | | - debug_register_view(rc, &debug_flush_view); |
---|
676 | | - debug_register_view(rc, &debug_pages_view); |
---|
677 | | -out: |
---|
678 | | - if (!rc) |
---|
| 660 | + if (rc) { |
---|
| 661 | + mutex_lock(&debug_mutex); |
---|
| 662 | + _debug_register(rc); |
---|
| 663 | + mutex_unlock(&debug_mutex); |
---|
| 664 | + } else { |
---|
679 | 665 | pr_err("Registering debug feature %s failed\n", name); |
---|
680 | | - mutex_unlock(&debug_mutex); |
---|
| 666 | + } |
---|
681 | 667 | return rc; |
---|
682 | 668 | } |
---|
683 | 669 | EXPORT_SYMBOL(debug_register_mode); |
---|
684 | 670 | |
---|
685 | | -/* |
---|
686 | | - * debug_register: |
---|
687 | | - * - creates and initializes debug area for the caller |
---|
688 | | - * - returns handle for debug area |
---|
| 671 | +/** |
---|
| 672 | + * debug_register() - creates and initializes debug area with default file mode. |
---|
| 673 | + * |
---|
| 674 | + * @name: Name of debug log (e.g. used for debugfs entry) |
---|
| 675 | + * @pages_per_area: Number of pages, which will be allocated per area |
---|
| 676 | + * @nr_areas: Number of debug areas |
---|
| 677 | + * @buf_size: Size of data area in each debug entry |
---|
| 678 | + * |
---|
| 679 | + * Return: |
---|
| 680 | + * - Handle for generated debug area |
---|
| 681 | + * - %NULL if register failed |
---|
| 682 | + * |
---|
| 683 | + * Allocates memory for a debug log. |
---|
| 684 | + * The debugfs file mode access permissions are read and write for user. |
---|
| 685 | + * Must not be called within an interrupt handler. |
---|
689 | 686 | */ |
---|
690 | 687 | debug_info_t *debug_register(const char *name, int pages_per_area, |
---|
691 | 688 | int nr_areas, int buf_size) |
---|
.. | .. |
---|
695 | 692 | } |
---|
696 | 693 | EXPORT_SYMBOL(debug_register); |
---|
697 | 694 | |
---|
698 | | -/* |
---|
699 | | - * debug_unregister: |
---|
700 | | - * - give back debug area |
---|
| 695 | +/* Remove debugfs entries and remove from internal list. */ |
---|
| 696 | +static void _debug_unregister(debug_info_t *id) |
---|
| 697 | +{ |
---|
| 698 | + int i; |
---|
| 699 | + |
---|
| 700 | + for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
---|
| 701 | + if (!id->views[i]) |
---|
| 702 | + continue; |
---|
| 703 | + debugfs_remove(id->debugfs_entries[i]); |
---|
| 704 | + } |
---|
| 705 | + debugfs_remove(id->debugfs_root_entry); |
---|
| 706 | + if (id == debug_area_first) |
---|
| 707 | + debug_area_first = id->next; |
---|
| 708 | + if (id == debug_area_last) |
---|
| 709 | + debug_area_last = id->prev; |
---|
| 710 | + if (id->prev) |
---|
| 711 | + id->prev->next = id->next; |
---|
| 712 | + if (id->next) |
---|
| 713 | + id->next->prev = id->prev; |
---|
| 714 | +} |
---|
| 715 | + |
---|
| 716 | +/** |
---|
| 717 | + * debug_unregister() - give back debug area. |
---|
| 718 | + * |
---|
| 719 | + * @id: handle for debug log |
---|
| 720 | + * |
---|
| 721 | + * Return: |
---|
| 722 | + * none |
---|
701 | 723 | */ |
---|
702 | 724 | void debug_unregister(debug_info_t *id) |
---|
703 | 725 | { |
---|
704 | 726 | if (!id) |
---|
705 | 727 | return; |
---|
706 | 728 | mutex_lock(&debug_mutex); |
---|
707 | | - debug_info_put(id); |
---|
| 729 | + _debug_unregister(id); |
---|
708 | 730 | mutex_unlock(&debug_mutex); |
---|
| 731 | + |
---|
| 732 | + debug_info_put(id); |
---|
709 | 733 | } |
---|
710 | 734 | EXPORT_SYMBOL(debug_unregister); |
---|
711 | 735 | |
---|
.. | .. |
---|
715 | 739 | */ |
---|
716 | 740 | static int debug_set_size(debug_info_t *id, int nr_areas, int pages_per_area) |
---|
717 | 741 | { |
---|
718 | | - debug_entry_t ***new_areas; |
---|
| 742 | + debug_info_t *new_id; |
---|
719 | 743 | unsigned long flags; |
---|
720 | | - int rc = 0; |
---|
721 | 744 | |
---|
722 | 745 | if (!id || (nr_areas <= 0) || (pages_per_area < 0)) |
---|
723 | 746 | return -EINVAL; |
---|
724 | | - if (pages_per_area > 0) { |
---|
725 | | - new_areas = debug_areas_alloc(pages_per_area, nr_areas); |
---|
726 | | - if (!new_areas) { |
---|
727 | | - pr_info("Allocating memory for %i pages failed\n", |
---|
728 | | - pages_per_area); |
---|
729 | | - rc = -ENOMEM; |
---|
730 | | - goto out; |
---|
731 | | - } |
---|
732 | | - } else { |
---|
733 | | - new_areas = NULL; |
---|
| 747 | + |
---|
| 748 | + new_id = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size, |
---|
| 749 | + id->level, ALL_AREAS); |
---|
| 750 | + if (!new_id) { |
---|
| 751 | + pr_info("Allocating memory for %i pages failed\n", |
---|
| 752 | + pages_per_area); |
---|
| 753 | + return -ENOMEM; |
---|
734 | 754 | } |
---|
| 755 | + |
---|
735 | 756 | spin_lock_irqsave(&id->lock, flags); |
---|
736 | | - debug_areas_free(id); |
---|
737 | | - id->areas = new_areas; |
---|
738 | | - id->nr_areas = nr_areas; |
---|
739 | | - id->pages_per_area = pages_per_area; |
---|
740 | | - id->active_area = 0; |
---|
741 | | - memset(id->active_entries, 0, sizeof(int)*id->nr_areas); |
---|
742 | | - memset(id->active_pages, 0, sizeof(int)*id->nr_areas); |
---|
| 757 | + debug_events_append(new_id, id); |
---|
| 758 | + debug_areas_swap(new_id, id); |
---|
| 759 | + debug_info_free(new_id); |
---|
743 | 760 | spin_unlock_irqrestore(&id->lock, flags); |
---|
744 | 761 | pr_info("%s: set new size (%i pages)\n", id->name, pages_per_area); |
---|
745 | | -out: |
---|
746 | | - return rc; |
---|
| 762 | + |
---|
| 763 | + return 0; |
---|
747 | 764 | } |
---|
748 | 765 | |
---|
749 | | -/* |
---|
750 | | - * debug_set_level: |
---|
751 | | - * - set actual debug level |
---|
| 766 | +/** |
---|
| 767 | + * debug_set_level() - Sets new actual debug level if new_level is valid. |
---|
| 768 | + * |
---|
| 769 | + * @id: handle for debug log |
---|
| 770 | + * @new_level: new debug level |
---|
| 771 | + * |
---|
| 772 | + * Return: |
---|
| 773 | + * none |
---|
752 | 774 | */ |
---|
753 | 775 | void debug_set_level(debug_info_t *id, int new_level) |
---|
754 | 776 | { |
---|
.. | .. |
---|
805 | 827 | id->active_entries[id->active_area]); |
---|
806 | 828 | } |
---|
807 | 829 | |
---|
| 830 | +/* Swap debug areas of a and b. */ |
---|
| 831 | +static void debug_areas_swap(debug_info_t *a, debug_info_t *b) |
---|
| 832 | +{ |
---|
| 833 | + swap(a->nr_areas, b->nr_areas); |
---|
| 834 | + swap(a->pages_per_area, b->pages_per_area); |
---|
| 835 | + swap(a->areas, b->areas); |
---|
| 836 | + swap(a->active_area, b->active_area); |
---|
| 837 | + swap(a->active_pages, b->active_pages); |
---|
| 838 | + swap(a->active_entries, b->active_entries); |
---|
| 839 | +} |
---|
| 840 | + |
---|
| 841 | +/* Append all debug events in active area from source to destination log. */ |
---|
| 842 | +static void debug_events_append(debug_info_t *dest, debug_info_t *src) |
---|
| 843 | +{ |
---|
| 844 | + debug_entry_t *from, *to, *last; |
---|
| 845 | + |
---|
| 846 | + if (!src->areas || !dest->areas) |
---|
| 847 | + return; |
---|
| 848 | + |
---|
| 849 | + /* Loop over all entries in src, starting with oldest. */ |
---|
| 850 | + from = get_active_entry(src); |
---|
| 851 | + last = from; |
---|
| 852 | + do { |
---|
| 853 | + if (from->clock != 0LL) { |
---|
| 854 | + to = get_active_entry(dest); |
---|
| 855 | + memset(to, 0, dest->entry_size); |
---|
| 856 | + memcpy(to, from, min(src->entry_size, |
---|
| 857 | + dest->entry_size)); |
---|
| 858 | + proceed_active_entry(dest); |
---|
| 859 | + } |
---|
| 860 | + |
---|
| 861 | + proceed_active_entry(src); |
---|
| 862 | + from = get_active_entry(src); |
---|
| 863 | + } while (from != last); |
---|
| 864 | +} |
---|
| 865 | + |
---|
808 | 866 | /* |
---|
809 | 867 | * debug_finish_entry: |
---|
810 | 868 | * - set timestamp, caller address, cpu number etc. |
---|
.. | .. |
---|
813 | 871 | static inline void debug_finish_entry(debug_info_t *id, debug_entry_t *active, |
---|
814 | 872 | int level, int exception) |
---|
815 | 873 | { |
---|
816 | | - active->id.stck = get_tod_clock_fast() - |
---|
817 | | - *(unsigned long long *) &tod_clock_base[1]; |
---|
818 | | - active->id.fields.cpuid = smp_processor_id(); |
---|
| 874 | + unsigned char clk[STORE_CLOCK_EXT_SIZE]; |
---|
| 875 | + unsigned long timestamp; |
---|
| 876 | + |
---|
| 877 | + get_tod_clock_ext(clk); |
---|
| 878 | + timestamp = *(unsigned long *) &clk[0] >> 4; |
---|
| 879 | + timestamp -= TOD_UNIX_EPOCH >> 12; |
---|
| 880 | + active->clock = timestamp; |
---|
| 881 | + active->cpu = smp_processor_id(); |
---|
819 | 882 | active->caller = __builtin_return_address(0); |
---|
820 | | - active->id.fields.exception = exception; |
---|
821 | | - active->id.fields.level = level; |
---|
| 883 | + active->exception = exception; |
---|
| 884 | + active->level = level; |
---|
822 | 885 | proceed_active_entry(id); |
---|
823 | 886 | if (exception) |
---|
824 | 887 | proceed_active_area(id); |
---|
.. | .. |
---|
836 | 899 | * if debug_active is already off |
---|
837 | 900 | */ |
---|
838 | 901 | static int s390dbf_procactive(struct ctl_table *table, int write, |
---|
839 | | - void __user *buffer, size_t *lenp, loff_t *ppos) |
---|
| 902 | + void *buffer, size_t *lenp, loff_t *ppos) |
---|
840 | 903 | { |
---|
841 | 904 | if (!write || debug_stoppable || !debug_active) |
---|
842 | 905 | return proc_dointvec(table, write, buffer, lenp, ppos); |
---|
.. | .. |
---|
874 | 937 | |
---|
875 | 938 | static struct ctl_table_header *s390dbf_sysctl_header; |
---|
876 | 939 | |
---|
| 940 | +/** |
---|
| 941 | + * debug_stop_all() - stops the debug feature if stopping is allowed. |
---|
| 942 | + * |
---|
| 943 | + * Return: |
---|
| 944 | + * - none |
---|
| 945 | + * |
---|
| 946 | + * Currently used in case of a kernel oops. |
---|
| 947 | + */ |
---|
877 | 948 | void debug_stop_all(void) |
---|
878 | 949 | { |
---|
879 | 950 | if (debug_stoppable) |
---|
.. | .. |
---|
881 | 952 | } |
---|
882 | 953 | EXPORT_SYMBOL(debug_stop_all); |
---|
883 | 954 | |
---|
| 955 | +/** |
---|
| 956 | + * debug_set_critical() - event/exception functions try lock instead of spin. |
---|
| 957 | + * |
---|
| 958 | + * Return: |
---|
| 959 | + * - none |
---|
| 960 | + * |
---|
| 961 | + * Currently used in case of stopping all CPUs but the current one. |
---|
| 962 | + * Once in this state, functions to write a debug entry for an |
---|
| 963 | + * event or exception no longer spin on the debug area lock, |
---|
| 964 | + * but only try to get it and fail if they do not get the lock. |
---|
| 965 | + */ |
---|
884 | 966 | void debug_set_critical(void) |
---|
885 | 967 | { |
---|
886 | 968 | debug_critical = 1; |
---|
.. | .. |
---|
1037 | 1119 | } |
---|
1038 | 1120 | EXPORT_SYMBOL(__debug_sprintf_exception); |
---|
1039 | 1121 | |
---|
1040 | | -/* |
---|
1041 | | - * debug_register_view: |
---|
| 1122 | +/** |
---|
| 1123 | + * debug_register_view() - registers new debug view and creates debugfs |
---|
| 1124 | + * dir entry |
---|
| 1125 | + * |
---|
| 1126 | + * @id: handle for debug log |
---|
| 1127 | + * @view: pointer to debug view struct |
---|
| 1128 | + * |
---|
| 1129 | + * Return: |
---|
| 1130 | + * - 0 : ok |
---|
| 1131 | + * - < 0: Error |
---|
1042 | 1132 | */ |
---|
1043 | 1133 | int debug_register_view(debug_info_t *id, struct debug_view *view) |
---|
1044 | 1134 | { |
---|
.. | .. |
---|
1057 | 1147 | mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); |
---|
1058 | 1148 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, |
---|
1059 | 1149 | id, &debug_file_ops); |
---|
1060 | | - if (!pde) { |
---|
1061 | | - pr_err("Registering view %s/%s failed due to out of " |
---|
1062 | | - "memory\n", id->name, view->name); |
---|
1063 | | - rc = -1; |
---|
1064 | | - goto out; |
---|
1065 | | - } |
---|
1066 | 1150 | spin_lock_irqsave(&id->lock, flags); |
---|
1067 | 1151 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
---|
1068 | 1152 | if (!id->views[i]) |
---|
.. | .. |
---|
1084 | 1168 | } |
---|
1085 | 1169 | EXPORT_SYMBOL(debug_register_view); |
---|
1086 | 1170 | |
---|
1087 | | -/* |
---|
1088 | | - * debug_unregister_view: |
---|
| 1171 | +/** |
---|
| 1172 | + * debug_unregister_view() - unregisters debug view and removes debugfs |
---|
| 1173 | + * dir entry |
---|
| 1174 | + * |
---|
| 1175 | + * @id: handle for debug log |
---|
| 1176 | + * @view: pointer to debug view struct |
---|
| 1177 | + * |
---|
| 1178 | + * Return: |
---|
| 1179 | + * - 0 : ok |
---|
| 1180 | + * - < 0: Error |
---|
1089 | 1181 | */ |
---|
1090 | 1182 | int debug_unregister_view(debug_info_t *id, struct debug_view *view) |
---|
1091 | 1183 | { |
---|
.. | .. |
---|
1325 | 1417 | } |
---|
1326 | 1418 | |
---|
1327 | 1419 | /* |
---|
1328 | | - * prints debug header in raw format |
---|
1329 | | - */ |
---|
1330 | | -static int debug_raw_header_fn(debug_info_t *id, struct debug_view *view, |
---|
1331 | | - int area, debug_entry_t *entry, char *out_buf) |
---|
1332 | | -{ |
---|
1333 | | - int rc; |
---|
1334 | | - |
---|
1335 | | - rc = sizeof(debug_entry_t); |
---|
1336 | | - memcpy(out_buf, entry, sizeof(debug_entry_t)); |
---|
1337 | | - return rc; |
---|
1338 | | -} |
---|
1339 | | - |
---|
1340 | | -/* |
---|
1341 | | - * prints debug data in raw format |
---|
1342 | | - */ |
---|
1343 | | -static int debug_raw_format_fn(debug_info_t *id, struct debug_view *view, |
---|
1344 | | - char *out_buf, const char *in_buf) |
---|
1345 | | -{ |
---|
1346 | | - int rc; |
---|
1347 | | - |
---|
1348 | | - rc = id->buf_size; |
---|
1349 | | - memcpy(out_buf, in_buf, id->buf_size); |
---|
1350 | | - return rc; |
---|
1351 | | -} |
---|
1352 | | - |
---|
1353 | | -/* |
---|
1354 | 1420 | * prints debug data in hex/ascii format |
---|
1355 | 1421 | */ |
---|
1356 | 1422 | static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, |
---|
.. | .. |
---|
1379 | 1445 | int debug_dflt_header_fn(debug_info_t *id, struct debug_view *view, |
---|
1380 | 1446 | int area, debug_entry_t *entry, char *out_buf) |
---|
1381 | 1447 | { |
---|
1382 | | - unsigned long base, sec, usec; |
---|
| 1448 | + unsigned long sec, usec; |
---|
1383 | 1449 | unsigned long caller; |
---|
1384 | 1450 | unsigned int level; |
---|
1385 | 1451 | char *except_str; |
---|
1386 | 1452 | int rc = 0; |
---|
1387 | 1453 | |
---|
1388 | | - level = entry->id.fields.level; |
---|
1389 | | - base = (*(unsigned long *) &tod_clock_base[0]) >> 4; |
---|
1390 | | - sec = (entry->id.stck >> 12) + base - (TOD_UNIX_EPOCH >> 12); |
---|
| 1454 | + level = entry->level; |
---|
| 1455 | + sec = entry->clock; |
---|
1391 | 1456 | usec = do_div(sec, USEC_PER_SEC); |
---|
1392 | 1457 | |
---|
1393 | | - if (entry->id.fields.exception) |
---|
| 1458 | + if (entry->exception) |
---|
1394 | 1459 | except_str = "*"; |
---|
1395 | 1460 | else |
---|
1396 | 1461 | except_str = "-"; |
---|
1397 | 1462 | caller = (unsigned long) entry->caller; |
---|
1398 | | - rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %02i %pK ", |
---|
| 1463 | + rc += sprintf(out_buf, "%02i %011ld:%06lu %1u %1s %04u %pK ", |
---|
1399 | 1464 | area, sec, usec, level, except_str, |
---|
1400 | | - entry->id.fields.cpuid, (void *)caller); |
---|
| 1465 | + entry->cpu, (void *)caller); |
---|
1401 | 1466 | return rc; |
---|
1402 | 1467 | } |
---|
1403 | 1468 | EXPORT_SYMBOL(debug_dflt_header_fn); |
---|