Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ubi: Add six fault injection type for testing

This commit adds six fault injection type for testing to cover the
abnormal path of the UBI driver.

Inject the following faults when the UBI reads the LEB:
+----------------------------+-----------------------------------+
| Interface name | emulate behavior |
+----------------------------+-----------------------------------+
| emulate_eccerr | ECC error |
+----------------------------+-----------------------------------+
| emulate_read_failure | read failure |
|----------------------------+-----------------------------------+
| emulate_io_ff | read content as all FF |
|----------------------------+-----------------------------------+
| emulate_io_ff_bitflips | content FF with MTD err reported |
+----------------------------+-----------------------------------+
| emulate_bad_hdr | bad leb header |
|----------------------------+-----------------------------------+
| emulate_bad_hdr_ebadmsg | bad header with ECC err |
+----------------------------+-----------------------------------+

Signed-off-by: ZhaoLong Wang <wangzhaolong1@huawei.com>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Richard Weinberger <richard@nod.at>

authored by

ZhaoLong Wang and committed by
Richard Weinberger
7cd8d1f8 e30948f7

+287 -21
+30
drivers/mtd/ubi/debug.c
··· 13 13 #include <linux/fault-inject.h> 14 14 15 15 #ifdef CONFIG_MTD_UBI_FAULT_INJECTION 16 + static DECLARE_FAULT_ATTR(fault_eccerr_attr); 16 17 static DECLARE_FAULT_ATTR(fault_bitflips_attr); 18 + static DECLARE_FAULT_ATTR(fault_read_failure_attr); 17 19 static DECLARE_FAULT_ATTR(fault_write_failure_attr); 18 20 static DECLARE_FAULT_ATTR(fault_erase_failure_attr); 19 21 static DECLARE_FAULT_ATTR(fault_power_cut_attr); 22 + static DECLARE_FAULT_ATTR(fault_io_ff_attr); 23 + static DECLARE_FAULT_ATTR(fault_io_ff_bitflips_attr); 24 + static DECLARE_FAULT_ATTR(fault_bad_hdr_attr); 25 + static DECLARE_FAULT_ATTR(fault_bad_hdr_ebadmsg_attr); 20 26 21 27 #define FAIL_ACTION(name, fault_attr) \ 22 28 bool should_fail_##name(void) \ ··· 30 24 return should_fail(&fault_attr, 1); \ 31 25 } 32 26 27 + FAIL_ACTION(eccerr, fault_eccerr_attr) 33 28 FAIL_ACTION(bitflips, fault_bitflips_attr) 29 + FAIL_ACTION(read_failure, fault_read_failure_attr) 34 30 FAIL_ACTION(write_failure, fault_write_failure_attr) 35 31 FAIL_ACTION(erase_failure, fault_erase_failure_attr) 36 32 FAIL_ACTION(power_cut, fault_power_cut_attr) 33 + FAIL_ACTION(io_ff, fault_io_ff_attr) 34 + FAIL_ACTION(io_ff_bitflips, fault_io_ff_bitflips_attr) 35 + FAIL_ACTION(bad_hdr, fault_bad_hdr_attr) 36 + FAIL_ACTION(bad_hdr_ebadmsg, fault_bad_hdr_ebadmsg_attr) 37 37 #endif 38 38 39 39 /** ··· 256 244 return; 257 245 } 258 246 247 + fault_create_debugfs_attr("emulate_eccerr", dir, 248 + &fault_eccerr_attr); 249 + 250 + fault_create_debugfs_attr("emulate_read_failure", dir, 251 + &fault_read_failure_attr); 252 + 259 253 fault_create_debugfs_attr("emulate_bitflips", dir, 260 254 &fault_bitflips_attr); 261 255 ··· 273 255 274 256 fault_create_debugfs_attr("emulate_power_cut", dir, 275 257 &fault_power_cut_attr); 258 + 259 + fault_create_debugfs_attr("emulate_io_ff", dir, 260 + &fault_io_ff_attr); 261 + 262 + fault_create_debugfs_attr("emulate_io_ff_bitflips", dir, 263 + &fault_io_ff_bitflips_attr); 264 + 265 + fault_create_debugfs_attr("emulate_bad_hdr", dir, 266 + &fault_bad_hdr_attr); 267 + 268 + fault_create_debugfs_attr("emulate_bad_hdr_ebadmsg", dir, 269 + &fault_bad_hdr_ebadmsg_attr); 276 270 } 277 271 #endif 278 272
+166 -6
drivers/mtd/ubi/debug.h
··· 87 87 /* Emulate a power cut when writing EC/VID header */ 88 88 #define MASK_POWER_CUT_EC (1 << 0) 89 89 #define MASK_POWER_CUT_VID (1 << 1) 90 + /* Emulate a power cut when writing data*/ 91 + #define MASK_POWER_CUT_DATA (1 << 2) 92 + /* Emulate bit-flips */ 93 + #define MASK_BITFLIPS (1 << 3) 94 + /* Emulate ecc error */ 95 + #define MASK_ECCERR (1 << 4) 96 + /* Emulates -EIO during data read */ 97 + #define MASK_READ_FAILURE (1 << 5) 98 + #define MASK_READ_FAILURE_EC (1 << 6) 99 + #define MASK_READ_FAILURE_VID (1 << 7) 100 + /* Emulates -EIO during data write */ 101 + #define MASK_WRITE_FAILURE (1 << 8) 102 + /* Emulates -EIO during erase a PEB*/ 103 + #define MASK_ERASE_FAILURE (1 << 9) 104 + /* Return UBI_IO_FF when reading EC/VID header */ 105 + #define MASK_IO_FF_EC (1 << 10) 106 + #define MASK_IO_FF_VID (1 << 11) 107 + /* Return UBI_IO_FF_BITFLIPS when reading EC/VID header */ 108 + #define MASK_IO_FF_BITFLIPS_EC (1 << 12) 109 + #define MASK_IO_FF_BITFLIPS_VID (1 << 13) 110 + /* Return UBI_IO_BAD_HDR when reading EC/VID header */ 111 + #define MASK_BAD_HDR_EC (1 << 14) 112 + #define MASK_BAD_HDR_VID (1 << 15) 113 + /* Return UBI_IO_BAD_HDR_EBADMSG when reading EC/VID header */ 114 + #define MASK_BAD_HDR_EBADMSG_EC (1 << 16) 115 + #define MASK_BAD_HDR_EBADMSG_VID (1 << 17) 90 116 91 117 #ifdef CONFIG_MTD_UBI_FAULT_INJECTION 92 - /* Emulate bit-flips */ 93 - #define MASK_BITFLIPS (1 << 2) 94 - /* Emulates -EIO during write/erase */ 95 - #define MASK_WRITE_FAILURE (1 << 3) 96 - #define MASK_ERASE_FAILURE (1 << 4) 97 118 119 + extern bool should_fail_eccerr(void); 98 120 extern bool should_fail_bitflips(void); 121 + extern bool should_fail_read_failure(void); 99 122 extern bool should_fail_write_failure(void); 100 123 extern bool should_fail_erase_failure(void); 101 124 extern bool should_fail_power_cut(void); 125 + extern bool should_fail_io_ff(void); 126 + extern bool should_fail_io_ff_bitflips(void); 127 + extern bool should_fail_bad_hdr(void); 128 + extern bool should_fail_bad_hdr_ebadmsg(void); 102 129 103 130 static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi) 104 131 { ··· 149 122 } 150 123 151 124 static inline bool ubi_dbg_fail_power_cut(const struct ubi_device *ubi, 152 - unsigned int caller) 125 + unsigned int caller) 153 126 { 154 127 if (ubi->dbg.emulate_failures & caller) 155 128 return should_fail_power_cut(); 156 129 return false; 157 130 } 158 131 132 + static inline bool ubi_dbg_fail_read(const struct ubi_device *ubi, 133 + unsigned int caller) 134 + { 135 + if (ubi->dbg.emulate_failures & caller) 136 + return should_fail_read_failure(); 137 + return false; 138 + } 139 + 140 + static inline bool ubi_dbg_fail_eccerr(const struct ubi_device *ubi) 141 + { 142 + if (ubi->dbg.emulate_failures & MASK_ECCERR) 143 + return should_fail_eccerr(); 144 + return false; 145 + } 146 + 147 + static inline bool ubi_dbg_fail_ff(const struct ubi_device *ubi, 148 + unsigned int caller) 149 + { 150 + if (ubi->dbg.emulate_failures & caller) 151 + return should_fail_io_ff(); 152 + return false; 153 + } 154 + 155 + static inline bool ubi_dbg_fail_ff_bitflips(const struct ubi_device *ubi, 156 + unsigned int caller) 157 + { 158 + if (ubi->dbg.emulate_failures & caller) 159 + return should_fail_io_ff_bitflips(); 160 + return false; 161 + } 162 + 163 + static inline bool ubi_dbg_fail_bad_hdr(const struct ubi_device *ubi, 164 + unsigned int caller) 165 + { 166 + if (ubi->dbg.emulate_failures & caller) 167 + return should_fail_bad_hdr(); 168 + return false; 169 + } 170 + 171 + static inline bool ubi_dbg_fail_bad_hdr_ebadmsg(const struct ubi_device *ubi, 172 + unsigned int caller) 173 + { 174 + if (ubi->dbg.emulate_failures & caller) 175 + return should_fail_bad_hdr_ebadmsg(); 176 + return false; 177 + } 159 178 #else /* CONFIG_MTD_UBI_FAULT_INJECTION */ 160 179 161 180 #define ubi_dbg_fail_bitflip(u) false 162 181 #define ubi_dbg_fail_write(u) false 163 182 #define ubi_dbg_fail_erase(u) false 164 183 #define ubi_dbg_fail_power_cut(u, c) false 184 + #define ubi_dbg_fail_read(u, c) false 185 + #define ubi_dbg_fail_eccerr(u) false 186 + #define ubi_dbg_fail_ff(u, c) false 187 + #define ubi_dbg_fail_ff_bitflips(u, v) false 188 + #define ubi_dbg_fail_bad_hdr(u, c) false 189 + #define ubi_dbg_fail_bad_hdr_ebadmsg(u, c) false 190 + 165 191 #endif 166 192 167 193 /** ··· 270 190 if (ubi_dbg_erase_failure(ubi)) 271 191 return true; 272 192 return ubi_dbg_fail_erase(ubi); 193 + } 194 + 195 + /** 196 + * ubi_dbg_is_eccerr - if it is time to emulate ECC error. 197 + * @ubi: UBI device description object 198 + * 199 + * Returns true if a ECC error should be emulated, otherwise returns false. 200 + */ 201 + static inline bool ubi_dbg_is_eccerr(const struct ubi_device *ubi) 202 + { 203 + return ubi_dbg_fail_eccerr(ubi); 204 + } 205 + 206 + /** 207 + * ubi_dbg_is_read_failure - if it is time to emulate a read failure. 208 + * @ubi: UBI device description object 209 + * 210 + * Returns true if a read failure should be emulated, otherwise returns 211 + * false. 212 + */ 213 + static inline bool ubi_dbg_is_read_failure(const struct ubi_device *ubi, 214 + unsigned int caller) 215 + { 216 + return ubi_dbg_fail_read(ubi, caller); 217 + } 218 + 219 + /** 220 + * ubi_dbg_is_ff - if it is time to emulate that read region is only 0xFF. 221 + * @ubi: UBI device description object 222 + * 223 + * Returns true if read region should be emulated 0xFF, otherwise 224 + * returns false. 225 + */ 226 + static inline bool ubi_dbg_is_ff(const struct ubi_device *ubi, 227 + unsigned int caller) 228 + { 229 + return ubi_dbg_fail_ff(ubi, caller); 230 + } 231 + 232 + /** 233 + * ubi_dbg_is_ff_bitflips - if it is time to emulate that read region is only 0xFF 234 + * with error reported by the MTD driver 235 + * 236 + * @ubi: UBI device description object 237 + * 238 + * Returns true if read region should be emulated 0xFF and error 239 + * reported by the MTD driver, otherwise returns false. 240 + */ 241 + static inline bool ubi_dbg_is_ff_bitflips(const struct ubi_device *ubi, 242 + unsigned int caller) 243 + { 244 + return ubi_dbg_fail_ff_bitflips(ubi, caller); 245 + } 246 + 247 + /** 248 + * ubi_dbg_is_bad_hdr - if it is time to emulate a bad header 249 + * @ubi: UBI device description object 250 + * 251 + * Returns true if a bad header error should be emulated, otherwise 252 + * returns false. 253 + */ 254 + static inline bool ubi_dbg_is_bad_hdr(const struct ubi_device *ubi, 255 + unsigned int caller) 256 + { 257 + return ubi_dbg_fail_bad_hdr(ubi, caller); 258 + } 259 + 260 + /** 261 + * ubi_dbg_is_bad_hdr_ebadmsg - if it is time to emulate a bad header with 262 + * ECC error. 263 + * 264 + * @ubi: UBI device description object 265 + * 266 + * Returns true if a bad header with ECC error should be emulated, otherwise 267 + * returns false. 268 + */ 269 + static inline bool ubi_dbg_is_bad_hdr_ebadmsg(const struct ubi_device *ubi, 270 + unsigned int caller) 271 + { 272 + return ubi_dbg_fail_bad_hdr_ebadmsg(ubi, caller); 273 273 } 274 274 275 275 /**
+73 -3
drivers/mtd/ubi/io.c
··· 195 195 196 196 if (ubi_dbg_is_bitflip(ubi)) { 197 197 dbg_gen("bit-flip (emulated)"); 198 - err = UBI_IO_BITFLIPS; 198 + return UBI_IO_BITFLIPS; 199 + } 200 + 201 + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE)) { 202 + ubi_warn(ubi, "cannot read %d bytes from PEB %d:%d (emulated)", 203 + len, pnum, offset); 204 + return -EIO; 205 + } 206 + 207 + if (ubi_dbg_is_eccerr(ubi)) { 208 + ubi_warn(ubi, "ECC error (emulated) while reading %d bytes from PEB %d:%d, read %zd bytes", 209 + len, pnum, offset, read); 210 + return -EBADMSG; 199 211 } 200 212 } 201 213 ··· 794 782 * If there was %-EBADMSG, but the header CRC is still OK, report about 795 783 * a bit-flip to force scrubbing on this PEB. 796 784 */ 797 - return read_err ? UBI_IO_BITFLIPS : 0; 785 + if (read_err) 786 + return UBI_IO_BITFLIPS; 787 + 788 + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_EC)) { 789 + ubi_warn(ubi, "cannot read EC header from PEB %d (emulated)", 790 + pnum); 791 + return -EIO; 792 + } 793 + 794 + if (ubi_dbg_is_ff(ubi, MASK_IO_FF_EC)) { 795 + ubi_warn(ubi, "bit-all-ff (emulated)"); 796 + return UBI_IO_FF; 797 + } 798 + 799 + if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_EC)) { 800 + ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)"); 801 + return UBI_IO_FF_BITFLIPS; 802 + } 803 + 804 + if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_EC)) { 805 + ubi_warn(ubi, "bad_hdr (emulated)"); 806 + return UBI_IO_BAD_HDR; 807 + } 808 + 809 + if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_EC)) { 810 + ubi_warn(ubi, "bad_hdr with ECC error (emulated)"); 811 + return UBI_IO_BAD_HDR_EBADMSG; 812 + } 813 + 814 + return 0; 798 815 } 799 816 800 817 /** ··· 1073 1032 return -EINVAL; 1074 1033 } 1075 1034 1076 - return read_err ? UBI_IO_BITFLIPS : 0; 1035 + if (read_err) 1036 + return UBI_IO_BITFLIPS; 1037 + 1038 + if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_VID)) { 1039 + ubi_warn(ubi, "cannot read VID header from PEB %d (emulated)", 1040 + pnum); 1041 + return -EIO; 1042 + } 1043 + 1044 + if (ubi_dbg_is_ff(ubi, MASK_IO_FF_VID)) { 1045 + ubi_warn(ubi, "bit-all-ff (emulated)"); 1046 + return UBI_IO_FF; 1047 + } 1048 + 1049 + if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_VID)) { 1050 + ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)"); 1051 + return UBI_IO_FF_BITFLIPS; 1052 + } 1053 + 1054 + if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_VID)) { 1055 + ubi_warn(ubi, "bad_hdr (emulated)"); 1056 + return UBI_IO_BAD_HDR; 1057 + } 1058 + 1059 + if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_VID)) { 1060 + ubi_warn(ubi, "bad_hdr with ECC error (emulated)"); 1061 + return UBI_IO_BAD_HDR_EBADMSG; 1062 + } 1063 + 1064 + return 0; 1077 1065 } 1078 1066 1079 1067 /**
+18 -12
drivers/mtd/ubi/ubi.h
··· 1123 1123 return vidb->hdr; 1124 1124 } 1125 1125 1126 + /** 1127 + * ubi_ro_mode - switch to read-only mode. 1128 + * @ubi: UBI device description object 1129 + */ 1130 + static inline void ubi_ro_mode(struct ubi_device *ubi) 1131 + { 1132 + if (!ubi->ro_mode) { 1133 + ubi->ro_mode = 1; 1134 + ubi_warn(ubi, "switch to read-only mode"); 1135 + dump_stack(); 1136 + } 1137 + } 1138 + 1126 1139 /* 1127 1140 * This function is equivalent to 'ubi_io_read()', but @offset is relative to 1128 1141 * the beginning of the logical eraseblock, not to the beginning of the ··· 1157 1144 int pnum, int offset, int len) 1158 1145 { 1159 1146 ubi_assert(offset >= 0); 1160 - return ubi_io_write(ubi, buf, pnum, offset + ubi->leb_start, len); 1161 - } 1162 1147 1163 - /** 1164 - * ubi_ro_mode - switch to read-only mode. 1165 - * @ubi: UBI device description object 1166 - */ 1167 - static inline void ubi_ro_mode(struct ubi_device *ubi) 1168 - { 1169 - if (!ubi->ro_mode) { 1170 - ubi->ro_mode = 1; 1171 - ubi_warn(ubi, "switch to read-only mode"); 1172 - dump_stack(); 1148 + if (ubi_dbg_power_cut(ubi, MASK_POWER_CUT_DATA)) { 1149 + ubi_warn(ubi, "XXXXX emulating a power cut when writing data XXXXX"); 1150 + ubi_ro_mode(ubi); 1151 + return -EROFS; 1173 1152 } 1153 + return ubi_io_write(ubi, buf, pnum, offset + ubi->leb_start, len); 1174 1154 } 1175 1155 1176 1156 /**