540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 1) // SPDX-License-Identifier: GPL-2.0
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 2) // error-inject.c: Function-level error injection table
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 3) #include <linux/error-injection.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 4) #include <linux/debugfs.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 5) #include <linux/kallsyms.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 6) #include <linux/kprobes.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 7) #include <linux/module.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 8) #include <linux/mutex.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 9) #include <linux/list.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 10) #include <linux/slab.h>
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 11)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 12) /* Whitelist of symbols that can be overridden for error injection. */
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 13) static LIST_HEAD(error_injection_list);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 14) static DEFINE_MUTEX(ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 15) struct ei_entry {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 16) struct list_head list;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 17) unsigned long start_addr;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 18) unsigned long end_addr;
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 19) int etype;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 20) void *priv;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 21) };
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 22)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 23) bool within_error_injection_list(unsigned long addr)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 24) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 25) struct ei_entry *ent;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 26) bool ret = false;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 27)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 28) mutex_lock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 29) list_for_each_entry(ent, &error_injection_list, list) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 30) if (addr >= ent->start_addr && addr < ent->end_addr) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 31) ret = true;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 32) break;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 33) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 34) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 35) mutex_unlock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 36) return ret;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 37) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 38)
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 39) int get_injectable_error_type(unsigned long addr)
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 40) {
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 41) struct ei_entry *ent;
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 42)
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 43) list_for_each_entry(ent, &error_injection_list, list) {
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 44) if (addr >= ent->start_addr && addr < ent->end_addr)
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 45) return ent->etype;
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 46) }
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 47) return EI_ETYPE_NONE;
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 48) }
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 49)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 50) /*
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 51) * Lookup and populate the error_injection_list.
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 52) *
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 53) * For safety reasons we only allow certain functions to be overridden with
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 54) * bpf_error_injection, so we need to populate the list of the symbols that have
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 55) * been marked as safe for overriding.
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 56) */
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 57) static void populate_error_injection_list(struct error_injection_entry *start,
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 58) struct error_injection_entry *end,
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 59) void *priv)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 60) {
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 61) struct error_injection_entry *iter;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 62) struct ei_entry *ent;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 63) unsigned long entry, offset = 0, size = 0;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 64)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 65) mutex_lock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 66) for (iter = start; iter < end; iter++) {
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 67) entry = arch_deref_entry_point((void *)iter->addr);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 68)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 69) if (!kernel_text_address(entry) ||
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 70) !kallsyms_lookup_size_offset(entry, &size, &offset)) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 71) pr_err("Failed to find error inject entry at %p\n",
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 72) (void *)entry);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 73) continue;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 74) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 75)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 76) ent = kmalloc(sizeof(*ent), GFP_KERNEL);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 77) if (!ent)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 78) break;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 79) ent->start_addr = entry;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 80) ent->end_addr = entry + size;
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 81) ent->etype = iter->etype;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 82) ent->priv = priv;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 83) INIT_LIST_HEAD(&ent->list);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 84) list_add_tail(&ent->list, &error_injection_list);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 85) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 86) mutex_unlock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 87) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 88)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 89) /* Markers of the _error_inject_whitelist section */
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 90) extern struct error_injection_entry __start_error_injection_whitelist[];
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 91) extern struct error_injection_entry __stop_error_injection_whitelist[];
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 92)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 93) static void __init populate_kernel_ei_list(void)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 94) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 95) populate_error_injection_list(__start_error_injection_whitelist,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 96) __stop_error_injection_whitelist,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 97) NULL);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 98) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 99)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 100) #ifdef CONFIG_MODULES
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 101) static void module_load_ei_list(struct module *mod)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 102) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 103) if (!mod->num_ei_funcs)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 104) return;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 105)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 106) populate_error_injection_list(mod->ei_funcs,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 107) mod->ei_funcs + mod->num_ei_funcs, mod);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 108) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 109)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 110) static void module_unload_ei_list(struct module *mod)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 111) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 112) struct ei_entry *ent, *n;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 113)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 114) if (!mod->num_ei_funcs)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 115) return;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 116)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 117) mutex_lock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 118) list_for_each_entry_safe(ent, n, &error_injection_list, list) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 119) if (ent->priv == mod) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 120) list_del_init(&ent->list);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 121) kfree(ent);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 122) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 123) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 124) mutex_unlock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 125) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 126)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 127) /* Module notifier call back, checking error injection table on the module */
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 128) static int ei_module_callback(struct notifier_block *nb,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 129) unsigned long val, void *data)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 130) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 131) struct module *mod = data;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 132)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 133) if (val == MODULE_STATE_COMING)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 134) module_load_ei_list(mod);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 135) else if (val == MODULE_STATE_GOING)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 136) module_unload_ei_list(mod);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 137)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 138) return NOTIFY_DONE;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 139) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 140)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 141) static struct notifier_block ei_module_nb = {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 142) .notifier_call = ei_module_callback,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 143) .priority = 0
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 144) };
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 145)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 146) static __init int module_ei_init(void)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 147) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 148) return register_module_notifier(&ei_module_nb);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 149) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 150) #else /* !CONFIG_MODULES */
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 151) #define module_ei_init() (0)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 152) #endif
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 153)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 154) /*
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 155) * error_injection/whitelist -- shows which functions can be overridden for
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 156) * error injection.
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 157) */
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 158) static void *ei_seq_start(struct seq_file *m, loff_t *pos)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 159) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 160) mutex_lock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 161) return seq_list_start(&error_injection_list, *pos);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 162) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 163)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 164) static void ei_seq_stop(struct seq_file *m, void *v)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 165) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 166) mutex_unlock(&ei_mutex);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 167) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 168)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 169) static void *ei_seq_next(struct seq_file *m, void *v, loff_t *pos)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 170) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 171) return seq_list_next(v, &error_injection_list, pos);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 172) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 173)
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 174) static const char *error_type_string(int etype)
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 175) {
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 176) switch (etype) {
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 177) case EI_ETYPE_NULL:
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 178) return "NULL";
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 179) case EI_ETYPE_ERRNO:
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 180) return "ERRNO";
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 181) case EI_ETYPE_ERRNO_NULL:
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 182) return "ERRNO_NULL";
537cd89484ab5 (Barnabás Pőcze 2020-12-15 20:47:10 -0800 183) case EI_ETYPE_TRUE:
537cd89484ab5 (Barnabás Pőcze 2020-12-15 20:47:10 -0800 184) return "TRUE";
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 185) default:
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 186) return "(unknown)";
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 187) }
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 188) }
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 189)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 190) static int ei_seq_show(struct seq_file *m, void *v)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 191) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 192) struct ei_entry *ent = list_entry(v, struct ei_entry, list);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 193)
d75f773c86a2b (Sakari Ailus 2019-03-25 21:32:28 +0200 194) seq_printf(m, "%ps\t%s\n", (void *)ent->start_addr,
663faf9f7beea (Masami Hiramatsu 2018-01-13 02:55:33 +0900 195) error_type_string(ent->etype));
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 196) return 0;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 197) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 198)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 199) static const struct seq_operations ei_seq_ops = {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 200) .start = ei_seq_start,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 201) .next = ei_seq_next,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 202) .stop = ei_seq_stop,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 203) .show = ei_seq_show,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 204) };
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 205)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 206) static int ei_open(struct inode *inode, struct file *filp)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 207) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 208) return seq_open(filp, &ei_seq_ops);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 209) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 210)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 211) static const struct file_operations debugfs_ei_ops = {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 212) .open = ei_open,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 213) .read = seq_read,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 214) .llseek = seq_lseek,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 215) .release = seq_release,
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 216) };
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 217)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 218) static int __init ei_debugfs_init(void)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 219) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 220) struct dentry *dir, *file;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 221)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 222) dir = debugfs_create_dir("error_injection", NULL);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 223) if (!dir)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 224) return -ENOMEM;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 225)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 226) file = debugfs_create_file("list", 0444, dir, NULL, &debugfs_ei_ops);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 227) if (!file) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 228) debugfs_remove(dir);
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 229) return -ENOMEM;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 230) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 231)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 232) return 0;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 233) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 234)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 235) static int __init init_error_injection(void)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 236) {
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 237) populate_kernel_ei_list();
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 238)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 239) if (!module_ei_init())
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 240) ei_debugfs_init();
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 241)
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 242) return 0;
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 243) }
540adea3809f6 (Masami Hiramatsu 2018-01-13 02:55:03 +0900 244) late_initcall(init_error_injection);