aboutsummaryrefslogtreecommitdiffstats
path: root/lib/error-inject.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/error-inject.c')
-rw-r--r--lib/error-inject.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/lib/error-inject.c b/lib/error-inject.c
index bccadcf3c981..c0d4600f4896 100644
--- a/lib/error-inject.c
+++ b/lib/error-inject.c
@@ -16,6 +16,7 @@ struct ei_entry {
16 struct list_head list; 16 struct list_head list;
17 unsigned long start_addr; 17 unsigned long start_addr;
18 unsigned long end_addr; 18 unsigned long end_addr;
19 int etype;
19 void *priv; 20 void *priv;
20}; 21};
21 22
@@ -35,6 +36,17 @@ bool within_error_injection_list(unsigned long addr)
35 return ret; 36 return ret;
36} 37}
37 38
39int get_injectable_error_type(unsigned long addr)
40{
41 struct ei_entry *ent;
42
43 list_for_each_entry(ent, &error_injection_list, list) {
44 if (addr >= ent->start_addr && addr < ent->end_addr)
45 return ent->etype;
46 }
47 return EI_ETYPE_NONE;
48}
49
38/* 50/*
39 * Lookup and populate the error_injection_list. 51 * Lookup and populate the error_injection_list.
40 * 52 *
@@ -42,16 +54,17 @@ bool within_error_injection_list(unsigned long addr)
42 * bpf_error_injection, so we need to populate the list of the symbols that have 54 * bpf_error_injection, so we need to populate the list of the symbols that have
43 * been marked as safe for overriding. 55 * been marked as safe for overriding.
44 */ 56 */
45static void populate_error_injection_list(unsigned long *start, 57static void populate_error_injection_list(struct error_injection_entry *start,
46 unsigned long *end, void *priv) 58 struct error_injection_entry *end,
59 void *priv)
47{ 60{
48 unsigned long *iter; 61 struct error_injection_entry *iter;
49 struct ei_entry *ent; 62 struct ei_entry *ent;
50 unsigned long entry, offset = 0, size = 0; 63 unsigned long entry, offset = 0, size = 0;
51 64
52 mutex_lock(&ei_mutex); 65 mutex_lock(&ei_mutex);
53 for (iter = start; iter < end; iter++) { 66 for (iter = start; iter < end; iter++) {
54 entry = arch_deref_entry_point((void *)*iter); 67 entry = arch_deref_entry_point((void *)iter->addr);
55 68
56 if (!kernel_text_address(entry) || 69 if (!kernel_text_address(entry) ||
57 !kallsyms_lookup_size_offset(entry, &size, &offset)) { 70 !kallsyms_lookup_size_offset(entry, &size, &offset)) {
@@ -65,6 +78,7 @@ static void populate_error_injection_list(unsigned long *start,
65 break; 78 break;
66 ent->start_addr = entry; 79 ent->start_addr = entry;
67 ent->end_addr = entry + size; 80 ent->end_addr = entry + size;
81 ent->etype = iter->etype;
68 ent->priv = priv; 82 ent->priv = priv;
69 INIT_LIST_HEAD(&ent->list); 83 INIT_LIST_HEAD(&ent->list);
70 list_add_tail(&ent->list, &error_injection_list); 84 list_add_tail(&ent->list, &error_injection_list);
@@ -73,8 +87,8 @@ static void populate_error_injection_list(unsigned long *start,
73} 87}
74 88
75/* Markers of the _error_inject_whitelist section */ 89/* Markers of the _error_inject_whitelist section */
76extern unsigned long __start_error_injection_whitelist[]; 90extern struct error_injection_entry __start_error_injection_whitelist[];
77extern unsigned long __stop_error_injection_whitelist[]; 91extern struct error_injection_entry __stop_error_injection_whitelist[];
78 92
79static void __init populate_kernel_ei_list(void) 93static void __init populate_kernel_ei_list(void)
80{ 94{
@@ -157,11 +171,26 @@ static void *ei_seq_next(struct seq_file *m, void *v, loff_t *pos)
157 return seq_list_next(v, &error_injection_list, pos); 171 return seq_list_next(v, &error_injection_list, pos);
158} 172}
159 173
174static const char *error_type_string(int etype)
175{
176 switch (etype) {
177 case EI_ETYPE_NULL:
178 return "NULL";
179 case EI_ETYPE_ERRNO:
180 return "ERRNO";
181 case EI_ETYPE_ERRNO_NULL:
182 return "ERRNO_NULL";
183 default:
184 return "(unknown)";
185 }
186}
187
160static int ei_seq_show(struct seq_file *m, void *v) 188static int ei_seq_show(struct seq_file *m, void *v)
161{ 189{
162 struct ei_entry *ent = list_entry(v, struct ei_entry, list); 190 struct ei_entry *ent = list_entry(v, struct ei_entry, list);
163 191
164 seq_printf(m, "%pf\n", (void *)ent->start_addr); 192 seq_printf(m, "%pf\t%s\n", (void *)ent->start_addr,
193 error_type_string(ent->etype));
165 return 0; 194 return 0;
166} 195}
167 196