]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.31/patches.arch/ppc64-xmon-dmesg-printing.patch
Merge branch 'master' into next
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / ppc64-xmon-dmesg-printing.patch
CommitLineData
2cb7cef9
BS
1Subject: [PATCH] add syslog printing to xmon debugger.
2From: Linas Vepstas <linas@austin.ibm.com>
3
4
5This patch 'dmesg'/printk log buffer printing to xmon. I find this
6useful because crashes are almost always preceeded by interesting
7printk's. This patch is simple & straightforward, except for one
8possibly controversial aspect: it embeds a small snippet in
9kernel/printk.c to return the location of the syslog. This is
10needed because kallsyms and even CONFIG_KALLSYMS_ALL is not enough
11to reveal the location of log_buf. This code is about 90%
12cut-n-paste of earlier code from Keith Owens.
13
14Signed-off-by: Olaf Hering <olh@suse.de>
15
16 arch/powerpc/xmon/xmon.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
17 kernel/printk.c | 15 ++++++++++++
18 2 files changed, 72 insertions(+)
19
20--- a/arch/powerpc/xmon/xmon.c
21+++ b/arch/powerpc/xmon/xmon.c
22@@ -136,6 +136,7 @@ static struct bpt *in_breakpoint_table(u
23 static int do_step(struct pt_regs *);
24 static void bpt_cmds(void);
25 static void cacheflush(void);
26+static void xmon_show_dmesg(void);
27 static int cpu_cmd(void);
28 static void csum(void);
29 static void bootcmds(void);
30@@ -194,6 +195,7 @@ Commands:\n\
31 #endif
32 "\
33 C checksum\n\
34+ D show dmesg (printk) buffer\n\
35 d dump bytes\n\
36 di dump instructions\n\
37 df dump float values\n\
38@@ -808,6 +810,9 @@ cmds(struct pt_regs *excp)
39 case 'd':
40 dump();
41 break;
42+ case 'D':
43+ xmon_show_dmesg();
44+ break;
45 case 'l':
46 symbol_lookup();
47 break;
48@@ -2522,6 +2527,58 @@ static void xmon_print_symbol(unsigned l
49 printf("%s", after);
50 }
51
52+extern void debugger_syslog_data(char *syslog_data[4]);
53+#define SYSLOG_WRAP(p) if (p < syslog_data[0]) p = syslog_data[1]-1; \
54+ else if (p >= syslog_data[1]) p = syslog_data[0];
55+
56+static void xmon_show_dmesg(void)
57+{
58+ char *syslog_data[4], *start, *end, c;
59+ int logsize;
60+
61+ /* syslog_data[0,1] physical start, end+1.
62+ * syslog_data[2,3] logical start, end+1.
63+ */
64+ debugger_syslog_data(syslog_data);
65+ if (syslog_data[2] == syslog_data[3])
66+ return;
67+ logsize = syslog_data[1] - syslog_data[0];
68+ start = syslog_data[0] + (syslog_data[2] - syslog_data[0]) % logsize;
69+ end = syslog_data[0] + (syslog_data[3] - syslog_data[0]) % logsize;
70+
71+ /* Do a line at a time (max 200 chars) to reduce overhead */
72+ c = '\0';
73+ while(1) {
74+ char *p;
75+ int chars = 0;
76+ if (!*start) {
77+ while (!*start) {
78+ ++start;
79+ SYSLOG_WRAP(start);
80+ if (start == end)
81+ break;
82+ }
83+ if (start == end)
84+ break;
85+ }
86+ p = start;
87+ while (*start && chars < 200) {
88+ c = *start;
89+ ++chars;
90+ ++start;
91+ SYSLOG_WRAP(start);
92+ if (start == end || c == '\n')
93+ break;
94+ }
95+ if (chars)
96+ printf("%.*s", chars, p);
97+ if (start == end)
98+ break;
99+ }
100+ if (c != '\n')
101+ printf("\n");
102+}
103+
104 #ifdef CONFIG_PPC64
105 static void dump_slb(void)
106 {
107--- a/kernel/printk.c
108+++ b/kernel/printk.c
109@@ -426,6 +426,21 @@ asmlinkage long sys_syslog(int type, cha
110 return do_syslog(type, buf, len);
111 }
112
113+#ifdef CONFIG_DEBUG_KERNEL
114+/* Its very handy to be able to view the syslog buffer during debug.
115+ * But do_syslog() uses locks so it cannot be used during debugging.
116+ * Instead, provide the start and end of the physical and logical logs.
117+ * This is equivalent to do_syslog(3).
118+ */
119+void debugger_syslog_data(char *syslog_data[4])
120+{
121+ syslog_data[0] = log_buf;
122+ syslog_data[1] = log_buf + log_buf_len;
123+ syslog_data[2] = log_buf + log_end - (logged_chars < log_buf_len ? logged_chars : log_buf_len);
124+ syslog_data[3] = log_buf + log_end;
125+}
126+#endif /* CONFIG_DEBUG_KERNEL */
127+
128 /*
129 * Call the console drivers on a range of log_buf
130 */