Skip to content

Commit 7cd8d1f

Browse files
ZhaoLong Wangrichardweinberger
authored andcommitted
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>
1 parent e30948f commit 7cd8d1f

4 files changed

Lines changed: 287 additions & 21 deletions

File tree

drivers/mtd/ubi/debug.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,33 @@
1313
#include <linux/fault-inject.h>
1414

1515
#ifdef CONFIG_MTD_UBI_FAULT_INJECTION
16+
static DECLARE_FAULT_ATTR(fault_eccerr_attr);
1617
static DECLARE_FAULT_ATTR(fault_bitflips_attr);
18+
static DECLARE_FAULT_ATTR(fault_read_failure_attr);
1719
static DECLARE_FAULT_ATTR(fault_write_failure_attr);
1820
static DECLARE_FAULT_ATTR(fault_erase_failure_attr);
1921
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);
2026

2127
#define FAIL_ACTION(name, fault_attr) \
2228
bool should_fail_##name(void) \
2329
{ \
2430
return should_fail(&fault_attr, 1); \
2531
}
2632

33+
FAIL_ACTION(eccerr, fault_eccerr_attr)
2734
FAIL_ACTION(bitflips, fault_bitflips_attr)
35+
FAIL_ACTION(read_failure, fault_read_failure_attr)
2836
FAIL_ACTION(write_failure, fault_write_failure_attr)
2937
FAIL_ACTION(erase_failure, fault_erase_failure_attr)
3038
FAIL_ACTION(power_cut, fault_power_cut_attr)
39+
FAIL_ACTION(io_ff, fault_io_ff_attr)
40+
FAIL_ACTION(io_ff_bitflips, fault_io_ff_bitflips_attr)
41+
FAIL_ACTION(bad_hdr, fault_bad_hdr_attr)
42+
FAIL_ACTION(bad_hdr_ebadmsg, fault_bad_hdr_ebadmsg_attr)
3143
#endif
3244

3345
/**
@@ -244,6 +256,12 @@ static void dfs_create_fault_entry(struct dentry *parent)
244256
return;
245257
}
246258

259+
fault_create_debugfs_attr("emulate_eccerr", dir,
260+
&fault_eccerr_attr);
261+
262+
fault_create_debugfs_attr("emulate_read_failure", dir,
263+
&fault_read_failure_attr);
264+
247265
fault_create_debugfs_attr("emulate_bitflips", dir,
248266
&fault_bitflips_attr);
249267

@@ -255,6 +273,18 @@ static void dfs_create_fault_entry(struct dentry *parent)
255273

256274
fault_create_debugfs_attr("emulate_power_cut", dir,
257275
&fault_power_cut_attr);
276+
277+
fault_create_debugfs_attr("emulate_io_ff", dir,
278+
&fault_io_ff_attr);
279+
280+
fault_create_debugfs_attr("emulate_io_ff_bitflips", dir,
281+
&fault_io_ff_bitflips_attr);
282+
283+
fault_create_debugfs_attr("emulate_bad_hdr", dir,
284+
&fault_bad_hdr_attr);
285+
286+
fault_create_debugfs_attr("emulate_bad_hdr_ebadmsg", dir,
287+
&fault_bad_hdr_ebadmsg_attr);
258288
}
259289
#endif
260290

drivers/mtd/ubi/debug.h

Lines changed: 166 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,45 @@ static inline int ubi_dbg_erase_failure(const struct ubi_device *ubi)
8787
/* Emulate a power cut when writing EC/VID header */
8888
#define MASK_POWER_CUT_EC (1 << 0)
8989
#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)
90116

91117
#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)
97118

119+
extern bool should_fail_eccerr(void);
98120
extern bool should_fail_bitflips(void);
121+
extern bool should_fail_read_failure(void);
99122
extern bool should_fail_write_failure(void);
100123
extern bool should_fail_erase_failure(void);
101124
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);
102129

103130
static inline bool ubi_dbg_fail_bitflip(const struct ubi_device *ubi)
104131
{
@@ -122,19 +149,72 @@ static inline bool ubi_dbg_fail_erase(const struct ubi_device *ubi)
122149
}
123150

124151
static inline bool ubi_dbg_fail_power_cut(const struct ubi_device *ubi,
125-
unsigned int caller)
152+
unsigned int caller)
126153
{
127154
if (ubi->dbg.emulate_failures & caller)
128155
return should_fail_power_cut();
129156
return false;
130157
}
131158

159+
static inline bool ubi_dbg_fail_read(const struct ubi_device *ubi,
160+
unsigned int caller)
161+
{
162+
if (ubi->dbg.emulate_failures & caller)
163+
return should_fail_read_failure();
164+
return false;
165+
}
166+
167+
static inline bool ubi_dbg_fail_eccerr(const struct ubi_device *ubi)
168+
{
169+
if (ubi->dbg.emulate_failures & MASK_ECCERR)
170+
return should_fail_eccerr();
171+
return false;
172+
}
173+
174+
static inline bool ubi_dbg_fail_ff(const struct ubi_device *ubi,
175+
unsigned int caller)
176+
{
177+
if (ubi->dbg.emulate_failures & caller)
178+
return should_fail_io_ff();
179+
return false;
180+
}
181+
182+
static inline bool ubi_dbg_fail_ff_bitflips(const struct ubi_device *ubi,
183+
unsigned int caller)
184+
{
185+
if (ubi->dbg.emulate_failures & caller)
186+
return should_fail_io_ff_bitflips();
187+
return false;
188+
}
189+
190+
static inline bool ubi_dbg_fail_bad_hdr(const struct ubi_device *ubi,
191+
unsigned int caller)
192+
{
193+
if (ubi->dbg.emulate_failures & caller)
194+
return should_fail_bad_hdr();
195+
return false;
196+
}
197+
198+
static inline bool ubi_dbg_fail_bad_hdr_ebadmsg(const struct ubi_device *ubi,
199+
unsigned int caller)
200+
{
201+
if (ubi->dbg.emulate_failures & caller)
202+
return should_fail_bad_hdr_ebadmsg();
203+
return false;
204+
}
132205
#else /* CONFIG_MTD_UBI_FAULT_INJECTION */
133206

134207
#define ubi_dbg_fail_bitflip(u) false
135208
#define ubi_dbg_fail_write(u) false
136209
#define ubi_dbg_fail_erase(u) false
137210
#define ubi_dbg_fail_power_cut(u, c) false
211+
#define ubi_dbg_fail_read(u, c) false
212+
#define ubi_dbg_fail_eccerr(u) false
213+
#define ubi_dbg_fail_ff(u, c) false
214+
#define ubi_dbg_fail_ff_bitflips(u, v) false
215+
#define ubi_dbg_fail_bad_hdr(u, c) false
216+
#define ubi_dbg_fail_bad_hdr_ebadmsg(u, c) false
217+
138218
#endif
139219

140220
/**
@@ -192,6 +272,86 @@ static inline bool ubi_dbg_is_erase_failure(const struct ubi_device *ubi)
192272
return ubi_dbg_fail_erase(ubi);
193273
}
194274

275+
/**
276+
* ubi_dbg_is_eccerr - if it is time to emulate ECC error.
277+
* @ubi: UBI device description object
278+
*
279+
* Returns true if a ECC error should be emulated, otherwise returns false.
280+
*/
281+
static inline bool ubi_dbg_is_eccerr(const struct ubi_device *ubi)
282+
{
283+
return ubi_dbg_fail_eccerr(ubi);
284+
}
285+
286+
/**
287+
* ubi_dbg_is_read_failure - if it is time to emulate a read failure.
288+
* @ubi: UBI device description object
289+
*
290+
* Returns true if a read failure should be emulated, otherwise returns
291+
* false.
292+
*/
293+
static inline bool ubi_dbg_is_read_failure(const struct ubi_device *ubi,
294+
unsigned int caller)
295+
{
296+
return ubi_dbg_fail_read(ubi, caller);
297+
}
298+
299+
/**
300+
* ubi_dbg_is_ff - if it is time to emulate that read region is only 0xFF.
301+
* @ubi: UBI device description object
302+
*
303+
* Returns true if read region should be emulated 0xFF, otherwise
304+
* returns false.
305+
*/
306+
static inline bool ubi_dbg_is_ff(const struct ubi_device *ubi,
307+
unsigned int caller)
308+
{
309+
return ubi_dbg_fail_ff(ubi, caller);
310+
}
311+
312+
/**
313+
* ubi_dbg_is_ff_bitflips - if it is time to emulate that read region is only 0xFF
314+
* with error reported by the MTD driver
315+
*
316+
* @ubi: UBI device description object
317+
*
318+
* Returns true if read region should be emulated 0xFF and error
319+
* reported by the MTD driver, otherwise returns false.
320+
*/
321+
static inline bool ubi_dbg_is_ff_bitflips(const struct ubi_device *ubi,
322+
unsigned int caller)
323+
{
324+
return ubi_dbg_fail_ff_bitflips(ubi, caller);
325+
}
326+
327+
/**
328+
* ubi_dbg_is_bad_hdr - if it is time to emulate a bad header
329+
* @ubi: UBI device description object
330+
*
331+
* Returns true if a bad header error should be emulated, otherwise
332+
* returns false.
333+
*/
334+
static inline bool ubi_dbg_is_bad_hdr(const struct ubi_device *ubi,
335+
unsigned int caller)
336+
{
337+
return ubi_dbg_fail_bad_hdr(ubi, caller);
338+
}
339+
340+
/**
341+
* ubi_dbg_is_bad_hdr_ebadmsg - if it is time to emulate a bad header with
342+
* ECC error.
343+
*
344+
* @ubi: UBI device description object
345+
*
346+
* Returns true if a bad header with ECC error should be emulated, otherwise
347+
* returns false.
348+
*/
349+
static inline bool ubi_dbg_is_bad_hdr_ebadmsg(const struct ubi_device *ubi,
350+
unsigned int caller)
351+
{
352+
return ubi_dbg_fail_bad_hdr_ebadmsg(ubi, caller);
353+
}
354+
195355
/**
196356
* ubi_dbg_is_bgt_disabled - if the background thread is disabled.
197357
* @ubi: UBI device description object

drivers/mtd/ubi/io.c

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,19 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset,
195195

196196
if (ubi_dbg_is_bitflip(ubi)) {
197197
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;
199211
}
200212
}
201213

@@ -782,7 +794,36 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum,
782794
* If there was %-EBADMSG, but the header CRC is still OK, report about
783795
* a bit-flip to force scrubbing on this PEB.
784796
*/
785-
return read_err ? UBI_IO_BITFLIPS : 0;
797+
if (read_err)
798+
return UBI_IO_BITFLIPS;
799+
800+
if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_EC)) {
801+
ubi_warn(ubi, "cannot read EC header from PEB %d (emulated)",
802+
pnum);
803+
return -EIO;
804+
}
805+
806+
if (ubi_dbg_is_ff(ubi, MASK_IO_FF_EC)) {
807+
ubi_warn(ubi, "bit-all-ff (emulated)");
808+
return UBI_IO_FF;
809+
}
810+
811+
if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_EC)) {
812+
ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)");
813+
return UBI_IO_FF_BITFLIPS;
814+
}
815+
816+
if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_EC)) {
817+
ubi_warn(ubi, "bad_hdr (emulated)");
818+
return UBI_IO_BAD_HDR;
819+
}
820+
821+
if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_EC)) {
822+
ubi_warn(ubi, "bad_hdr with ECC error (emulated)");
823+
return UBI_IO_BAD_HDR_EBADMSG;
824+
}
825+
826+
return 0;
786827
}
787828

788829
/**
@@ -1032,7 +1073,36 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum,
10321073
return -EINVAL;
10331074
}
10341075

1035-
return read_err ? UBI_IO_BITFLIPS : 0;
1076+
if (read_err)
1077+
return UBI_IO_BITFLIPS;
1078+
1079+
if (ubi_dbg_is_read_failure(ubi, MASK_READ_FAILURE_VID)) {
1080+
ubi_warn(ubi, "cannot read VID header from PEB %d (emulated)",
1081+
pnum);
1082+
return -EIO;
1083+
}
1084+
1085+
if (ubi_dbg_is_ff(ubi, MASK_IO_FF_VID)) {
1086+
ubi_warn(ubi, "bit-all-ff (emulated)");
1087+
return UBI_IO_FF;
1088+
}
1089+
1090+
if (ubi_dbg_is_ff_bitflips(ubi, MASK_IO_FF_BITFLIPS_VID)) {
1091+
ubi_warn(ubi, "bit-all-ff with error reported by MTD driver (emulated)");
1092+
return UBI_IO_FF_BITFLIPS;
1093+
}
1094+
1095+
if (ubi_dbg_is_bad_hdr(ubi, MASK_BAD_HDR_VID)) {
1096+
ubi_warn(ubi, "bad_hdr (emulated)");
1097+
return UBI_IO_BAD_HDR;
1098+
}
1099+
1100+
if (ubi_dbg_is_bad_hdr_ebadmsg(ubi, MASK_BAD_HDR_EBADMSG_VID)) {
1101+
ubi_warn(ubi, "bad_hdr with ECC error (emulated)");
1102+
return UBI_IO_BAD_HDR_EBADMSG;
1103+
}
1104+
1105+
return 0;
10361106
}
10371107

10381108
/**

0 commit comments

Comments
 (0)