VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
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);