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