aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorHuang Ying <ying.huang@intel.com>2009-05-27 15:56:57 -0400
committerH. Peter Anvin <hpa@zytor.com>2009-06-03 17:45:34 -0400
commit4611a6fa4b37cf6b8b6066ed0d605c994c62a1a0 (patch)
tree5a653d42248914cb38ab6b1f3b319abe39f4e2cd /arch/x86
parented7290d0ee8f81aa78bfe816f01b012f208cafc5 (diff)
x86, mce: export MCE severities coverage via debugfs
The MCE severity judgement code is data-driven, so code coverage tools such as gcov can not be used for measuring coverage. Instead a dedicated coverage mechanism is implemented. The kernel keeps track of rules executed and reports them in debugfs. This is useful for increasing coverage of the mce-test testsuite. Right now it's unconditionally enabled because it's very little code. Signed-off-by: Huang Ying <ying.huang@intel.com> Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce-severity.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c
index 4f4d2caf4043..ff0807f97056 100644
--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
+++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
@@ -10,6 +10,9 @@
10 * Author: Andi Kleen 10 * Author: Andi Kleen
11 */ 11 */
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/seq_file.h>
14#include <linux/init.h>
15#include <linux/debugfs.h>
13#include <asm/mce.h> 16#include <asm/mce.h>
14 17
15#include "mce-internal.h" 18#include "mce-internal.h"
@@ -37,6 +40,7 @@ static struct severity {
37 unsigned char mcgres; 40 unsigned char mcgres;
38 unsigned char ser; 41 unsigned char ser;
39 unsigned char context; 42 unsigned char context;
43 unsigned char covered;
40 char *msg; 44 char *msg;
41} severities[] = { 45} severities[] = {
42#define KERNEL .context = IN_KERNEL 46#define KERNEL .context = IN_KERNEL
@@ -126,6 +130,7 @@ int mce_severity(struct mce *a, int tolerant, char **msg)
126 continue; 130 continue;
127 if (msg) 131 if (msg)
128 *msg = s->msg; 132 *msg = s->msg;
133 s->covered = 1;
129 if (s->sev >= MCE_UC_SEVERITY && ctx == IN_KERNEL) { 134 if (s->sev >= MCE_UC_SEVERITY && ctx == IN_KERNEL) {
130 if (panic_on_oops || tolerant < 1) 135 if (panic_on_oops || tolerant < 1)
131 return MCE_PANIC_SEVERITY; 136 return MCE_PANIC_SEVERITY;
@@ -133,3 +138,81 @@ int mce_severity(struct mce *a, int tolerant, char **msg)
133 return s->sev; 138 return s->sev;
134 } 139 }
135} 140}
141
142static void *s_start(struct seq_file *f, loff_t *pos)
143{
144 if (*pos >= ARRAY_SIZE(severities))
145 return NULL;
146 return &severities[*pos];
147}
148
149static void *s_next(struct seq_file *f, void *data, loff_t *pos)
150{
151 if (++(*pos) >= ARRAY_SIZE(severities))
152 return NULL;
153 return &severities[*pos];
154}
155
156static void s_stop(struct seq_file *f, void *data)
157{
158}
159
160static int s_show(struct seq_file *f, void *data)
161{
162 struct severity *ser = data;
163 seq_printf(f, "%d\t%s\n", ser->covered, ser->msg);
164 return 0;
165}
166
167static const struct seq_operations severities_seq_ops = {
168 .start = s_start,
169 .next = s_next,
170 .stop = s_stop,
171 .show = s_show,
172};
173
174static int severities_coverage_open(struct inode *inode, struct file *file)
175{
176 return seq_open(file, &severities_seq_ops);
177}
178
179static ssize_t severities_coverage_write(struct file *file,
180 const char __user *ubuf,
181 size_t count, loff_t *ppos)
182{
183 int i;
184 for (i = 0; i < ARRAY_SIZE(severities); i++)
185 severities[i].covered = 0;
186 return count;
187}
188
189static const struct file_operations severities_coverage_fops = {
190 .open = severities_coverage_open,
191 .release = seq_release,
192 .read = seq_read,
193 .write = severities_coverage_write,
194};
195
196static int __init severities_debugfs_init(void)
197{
198 struct dentry *dmce = NULL, *fseverities_coverage = NULL;
199
200 dmce = debugfs_create_dir("mce", NULL);
201 if (dmce == NULL)
202 goto err_out;
203 fseverities_coverage = debugfs_create_file("severities-coverage",
204 0444, dmce, NULL,
205 &severities_coverage_fops);
206 if (fseverities_coverage == NULL)
207 goto err_out;
208
209 return 0;
210
211err_out:
212 if (fseverities_coverage)
213 debugfs_remove(fseverities_coverage);
214 if (dmce)
215 debugfs_remove(dmce);
216 return -ENOMEM;
217}
218late_initcall(severities_debugfs_init);