Skip to content

Commit 0451d14

Browse files
Aravind Gopalakrishnansuryasaimadhu
authored andcommitted
EDAC, mce_amd_inj: Modify flags attribute to use string arguments
Use strings such as "hw" or "sw" to indicate the type of error injection to be performed. Current flags attribute derives the meanings of values that can be programmed into it from asm/mce.h. Moving to defined strings for the attribute allows this module to be self-sufficient and removes the dependency. Also, we can introduce new flags as and when needed without having to worry about conflicting with the flags already defined in asm/mce.h. Also, modify do_inject() to use the newly defined injection_type enum to figure out the injection mechanism we need to use Suggested-by: Borislav Petkov <[email protected]> Signed-off-by: Aravind Gopalakrishnan <[email protected]> Cc: linux-edac <[email protected]> Cc: [email protected] Cc: x86-ml <[email protected]> Link: http://lkml.kernel.org/r/[email protected] [ Use strstrip() return value. ] Signed-off-by: Borislav Petkov <[email protected]>
1 parent 685d46d commit 0451d14

File tree

1 file changed

+71
-10
lines changed

1 file changed

+71
-10
lines changed

drivers/edac/mce_amd_inj.c

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#include <linux/device.h>
1616
#include <linux/module.h>
1717
#include <linux/cpu.h>
18+
#include <linux/string.h>
19+
#include <linux/uaccess.h>
1820
#include <asm/mce.h>
1921

2022
#include "mce_amd.h"
@@ -27,6 +29,23 @@ static struct dentry *dfs_inj;
2729

2830
static u8 n_banks;
2931

32+
#define MAX_FLAG_OPT_SIZE 3
33+
34+
enum injection_type {
35+
SW_INJ = 0, /* SW injection, simply decode the error */
36+
HW_INJ, /* Trigger a #MC */
37+
N_INJ_TYPES,
38+
};
39+
40+
static const char * const flags_options[] = {
41+
[SW_INJ] = "sw",
42+
[HW_INJ] = "hw",
43+
NULL
44+
};
45+
46+
/* Set default injection to SW_INJ */
47+
enum injection_type inj_type = SW_INJ;
48+
3049
#define MCE_INJECT_SET(reg) \
3150
static int inj_##reg##_set(void *data, u64 val) \
3251
{ \
@@ -81,24 +100,66 @@ static int toggle_hw_mce_inject(unsigned int cpu, bool enable)
81100
return err;
82101
}
83102

84-
static int flags_get(void *data, u64 *val)
103+
static int __set_inj(const char *buf)
85104
{
86-
struct mce *m = (struct mce *)data;
105+
int i;
87106

88-
*val = m->inject_flags;
107+
for (i = 0; i < N_INJ_TYPES; i++) {
108+
if (!strncmp(flags_options[i], buf, strlen(flags_options[i]))) {
109+
inj_type = i;
110+
return 0;
111+
}
112+
}
113+
return -EINVAL;
114+
}
89115

90-
return 0;
116+
static ssize_t flags_read(struct file *filp, char __user *ubuf,
117+
size_t cnt, loff_t *ppos)
118+
{
119+
char buf[MAX_FLAG_OPT_SIZE];
120+
int n;
121+
122+
n = sprintf(buf, "%s\n", flags_options[inj_type]);
123+
124+
return simple_read_from_buffer(ubuf, cnt, ppos, buf, n);
91125
}
92126

93-
static int flags_set(void *data, u64 val)
127+
static ssize_t flags_write(struct file *filp, const char __user *ubuf,
128+
size_t cnt, loff_t *ppos)
94129
{
95-
struct mce *m = (struct mce *)data;
130+
char buf[MAX_FLAG_OPT_SIZE], *__buf;
131+
int err;
132+
size_t ret;
96133

97-
m->inject_flags = (u8)val;
98-
return 0;
134+
if (cnt > MAX_FLAG_OPT_SIZE)
135+
cnt = MAX_FLAG_OPT_SIZE;
136+
137+
ret = cnt;
138+
139+
if (copy_from_user(&buf, ubuf, cnt))
140+
return -EFAULT;
141+
142+
buf[cnt - 1] = 0;
143+
144+
/* strip whitespace */
145+
__buf = strstrip(buf);
146+
147+
err = __set_inj(__buf);
148+
if (err) {
149+
pr_err("%s: Invalid flags value: %s\n", __func__, __buf);
150+
return err;
151+
}
152+
153+
*ppos += ret;
154+
155+
return ret;
99156
}
100157

101-
DEFINE_SIMPLE_ATTRIBUTE(flags_fops, flags_get, flags_set, "%llu\n");
158+
static const struct file_operations flags_fops = {
159+
.read = flags_read,
160+
.write = flags_write,
161+
.llseek = generic_file_llseek,
162+
};
102163

103164
/*
104165
* On which CPU to inject?
@@ -130,7 +191,7 @@ static void do_inject(void)
130191
unsigned int cpu = i_mce.extcpu;
131192
u8 b = i_mce.bank;
132193

133-
if (!(i_mce.inject_flags & MCJ_EXCEPTION)) {
194+
if (inj_type == SW_INJ) {
134195
amd_decode_mce(NULL, 0, &i_mce);
135196
return;
136197
}

0 commit comments

Comments
 (0)