diff options
Diffstat (limited to 'drivers/mtd/ubi/io.c')
-rw-r--r-- | drivers/mtd/ubi/io.c | 145 |
1 files changed, 104 insertions, 41 deletions
diff --git a/drivers/mtd/ubi/io.c b/drivers/mtd/ubi/io.c index 811775aa8ee8..aaa6e1e83b29 100644 --- a/drivers/mtd/ubi/io.c +++ b/drivers/mtd/ubi/io.c | |||
@@ -91,7 +91,7 @@ | |||
91 | #include <linux/slab.h> | 91 | #include <linux/slab.h> |
92 | #include "ubi.h" | 92 | #include "ubi.h" |
93 | 93 | ||
94 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 94 | #ifdef CONFIG_MTD_UBI_DEBUG |
95 | static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); | 95 | static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum); |
96 | static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); | 96 | static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum); |
97 | static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | 97 | static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, |
@@ -146,6 +146,28 @@ int ubi_io_read(const struct ubi_device *ubi, void *buf, int pnum, int offset, | |||
146 | if (err) | 146 | if (err) |
147 | return err; | 147 | return err; |
148 | 148 | ||
149 | /* | ||
150 | * Deliberately corrupt the buffer to improve robustness. Indeed, if we | ||
151 | * do not do this, the following may happen: | ||
152 | * 1. The buffer contains data from previous operation, e.g., read from | ||
153 | * another PEB previously. The data looks like expected, e.g., if we | ||
154 | * just do not read anything and return - the caller would not | ||
155 | * notice this. E.g., if we are reading a VID header, the buffer may | ||
156 | * contain a valid VID header from another PEB. | ||
157 | * 2. The driver is buggy and returns us success or -EBADMSG or | ||
158 | * -EUCLEAN, but it does not actually put any data to the buffer. | ||
159 | * | ||
160 | * This may confuse UBI or upper layers - they may think the buffer | ||
161 | * contains valid data while in fact it is just old data. This is | ||
162 | * especially possible because UBI (and UBIFS) relies on CRC, and | ||
163 | * treats data as correct even in case of ECC errors if the CRC is | ||
164 | * correct. | ||
165 | * | ||
166 | * Try to prevent this situation by changing the first byte of the | ||
167 | * buffer. | ||
168 | */ | ||
169 | *((uint8_t *)buf) ^= 0xFF; | ||
170 | |||
149 | addr = (loff_t)pnum * ubi->peb_size + offset; | 171 | addr = (loff_t)pnum * ubi->peb_size + offset; |
150 | retry: | 172 | retry: |
151 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); | 173 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); |
@@ -166,7 +188,7 @@ retry: | |||
166 | return UBI_IO_BITFLIPS; | 188 | return UBI_IO_BITFLIPS; |
167 | } | 189 | } |
168 | 190 | ||
169 | if (read != len && retries++ < UBI_IO_RETRIES) { | 191 | if (retries++ < UBI_IO_RETRIES) { |
170 | dbg_io("error %d%s while reading %d bytes from PEB %d:%d," | 192 | dbg_io("error %d%s while reading %d bytes from PEB %d:%d," |
171 | " read only %zd bytes, retry", | 193 | " read only %zd bytes, retry", |
172 | err, errstr, len, pnum, offset, read); | 194 | err, errstr, len, pnum, offset, read); |
@@ -480,6 +502,13 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | |||
480 | size_t written; | 502 | size_t written; |
481 | loff_t addr; | 503 | loff_t addr; |
482 | uint32_t data = 0; | 504 | uint32_t data = 0; |
505 | /* | ||
506 | * Note, we cannot generally define VID header buffers on stack, | ||
507 | * because of the way we deal with these buffers (see the header | ||
508 | * comment in this file). But we know this is a NOR-specific piece of | ||
509 | * code, so we can do this. But yes, this is error-prone and we should | ||
510 | * (pre-)allocate VID header buffer instead. | ||
511 | */ | ||
483 | struct ubi_vid_hdr vid_hdr; | 512 | struct ubi_vid_hdr vid_hdr; |
484 | 513 | ||
485 | /* | 514 | /* |
@@ -507,11 +536,13 @@ static int nor_erase_prepare(struct ubi_device *ubi, int pnum) | |||
507 | * PEB. | 536 | * PEB. |
508 | */ | 537 | */ |
509 | err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); | 538 | err1 = ubi_io_read_vid_hdr(ubi, pnum, &vid_hdr, 0); |
510 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) { | 539 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || |
540 | err1 == UBI_IO_FF) { | ||
511 | struct ubi_ec_hdr ec_hdr; | 541 | struct ubi_ec_hdr ec_hdr; |
512 | 542 | ||
513 | err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); | 543 | err1 = ubi_io_read_ec_hdr(ubi, pnum, &ec_hdr, 0); |
514 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR) | 544 | if (err1 == UBI_IO_BAD_HDR_EBADMSG || err1 == UBI_IO_BAD_HDR || |
545 | err1 == UBI_IO_FF) | ||
515 | /* | 546 | /* |
516 | * Both VID and EC headers are corrupted, so we can | 547 | * Both VID and EC headers are corrupted, so we can |
517 | * safely erase this PEB and not afraid that it will be | 548 | * safely erase this PEB and not afraid that it will be |
@@ -752,9 +783,8 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
752 | if (verbose) | 783 | if (verbose) |
753 | ubi_warn("no EC header found at PEB %d, " | 784 | ubi_warn("no EC header found at PEB %d, " |
754 | "only 0xFF bytes", pnum); | 785 | "only 0xFF bytes", pnum); |
755 | else if (UBI_IO_DEBUG) | 786 | dbg_bld("no EC header found at PEB %d, " |
756 | dbg_msg("no EC header found at PEB %d, " | 787 | "only 0xFF bytes", pnum); |
757 | "only 0xFF bytes", pnum); | ||
758 | if (!read_err) | 788 | if (!read_err) |
759 | return UBI_IO_FF; | 789 | return UBI_IO_FF; |
760 | else | 790 | else |
@@ -769,9 +799,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
769 | ubi_warn("bad magic number at PEB %d: %08x instead of " | 799 | ubi_warn("bad magic number at PEB %d: %08x instead of " |
770 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); | 800 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); |
771 | ubi_dbg_dump_ec_hdr(ec_hdr); | 801 | ubi_dbg_dump_ec_hdr(ec_hdr); |
772 | } else if (UBI_IO_DEBUG) | 802 | } |
773 | dbg_msg("bad magic number at PEB %d: %08x instead of " | 803 | dbg_bld("bad magic number at PEB %d: %08x instead of " |
774 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); | 804 | "%08x", pnum, magic, UBI_EC_HDR_MAGIC); |
775 | return UBI_IO_BAD_HDR; | 805 | return UBI_IO_BAD_HDR; |
776 | } | 806 | } |
777 | 807 | ||
@@ -783,9 +813,9 @@ int ubi_io_read_ec_hdr(struct ubi_device *ubi, int pnum, | |||
783 | ubi_warn("bad EC header CRC at PEB %d, calculated " | 813 | ubi_warn("bad EC header CRC at PEB %d, calculated " |
784 | "%#08x, read %#08x", pnum, crc, hdr_crc); | 814 | "%#08x, read %#08x", pnum, crc, hdr_crc); |
785 | ubi_dbg_dump_ec_hdr(ec_hdr); | 815 | ubi_dbg_dump_ec_hdr(ec_hdr); |
786 | } else if (UBI_IO_DEBUG) | 816 | } |
787 | dbg_msg("bad EC header CRC at PEB %d, calculated " | 817 | dbg_bld("bad EC header CRC at PEB %d, calculated " |
788 | "%#08x, read %#08x", pnum, crc, hdr_crc); | 818 | "%#08x, read %#08x", pnum, crc, hdr_crc); |
789 | 819 | ||
790 | if (!read_err) | 820 | if (!read_err) |
791 | return UBI_IO_BAD_HDR; | 821 | return UBI_IO_BAD_HDR; |
@@ -1008,9 +1038,8 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1008 | if (verbose) | 1038 | if (verbose) |
1009 | ubi_warn("no VID header found at PEB %d, " | 1039 | ubi_warn("no VID header found at PEB %d, " |
1010 | "only 0xFF bytes", pnum); | 1040 | "only 0xFF bytes", pnum); |
1011 | else if (UBI_IO_DEBUG) | 1041 | dbg_bld("no VID header found at PEB %d, " |
1012 | dbg_msg("no VID header found at PEB %d, " | 1042 | "only 0xFF bytes", pnum); |
1013 | "only 0xFF bytes", pnum); | ||
1014 | if (!read_err) | 1043 | if (!read_err) |
1015 | return UBI_IO_FF; | 1044 | return UBI_IO_FF; |
1016 | else | 1045 | else |
@@ -1021,9 +1050,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1021 | ubi_warn("bad magic number at PEB %d: %08x instead of " | 1050 | ubi_warn("bad magic number at PEB %d: %08x instead of " |
1022 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); | 1051 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); |
1023 | ubi_dbg_dump_vid_hdr(vid_hdr); | 1052 | ubi_dbg_dump_vid_hdr(vid_hdr); |
1024 | } else if (UBI_IO_DEBUG) | 1053 | } |
1025 | dbg_msg("bad magic number at PEB %d: %08x instead of " | 1054 | dbg_bld("bad magic number at PEB %d: %08x instead of " |
1026 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); | 1055 | "%08x", pnum, magic, UBI_VID_HDR_MAGIC); |
1027 | return UBI_IO_BAD_HDR; | 1056 | return UBI_IO_BAD_HDR; |
1028 | } | 1057 | } |
1029 | 1058 | ||
@@ -1035,9 +1064,9 @@ int ubi_io_read_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1035 | ubi_warn("bad CRC at PEB %d, calculated %#08x, " | 1064 | ubi_warn("bad CRC at PEB %d, calculated %#08x, " |
1036 | "read %#08x", pnum, crc, hdr_crc); | 1065 | "read %#08x", pnum, crc, hdr_crc); |
1037 | ubi_dbg_dump_vid_hdr(vid_hdr); | 1066 | ubi_dbg_dump_vid_hdr(vid_hdr); |
1038 | } else if (UBI_IO_DEBUG) | 1067 | } |
1039 | dbg_msg("bad CRC at PEB %d, calculated %#08x, " | 1068 | dbg_bld("bad CRC at PEB %d, calculated %#08x, " |
1040 | "read %#08x", pnum, crc, hdr_crc); | 1069 | "read %#08x", pnum, crc, hdr_crc); |
1041 | if (!read_err) | 1070 | if (!read_err) |
1042 | return UBI_IO_BAD_HDR; | 1071 | return UBI_IO_BAD_HDR; |
1043 | else | 1072 | else |
@@ -1097,7 +1126,7 @@ int ubi_io_write_vid_hdr(struct ubi_device *ubi, int pnum, | |||
1097 | return err; | 1126 | return err; |
1098 | } | 1127 | } |
1099 | 1128 | ||
1100 | #ifdef CONFIG_MTD_UBI_DEBUG_PARANOID | 1129 | #ifdef CONFIG_MTD_UBI_DEBUG |
1101 | 1130 | ||
1102 | /** | 1131 | /** |
1103 | * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. | 1132 | * paranoid_check_not_bad - ensure that a physical eraseblock is not bad. |
@@ -1111,6 +1140,9 @@ static int paranoid_check_not_bad(const struct ubi_device *ubi, int pnum) | |||
1111 | { | 1140 | { |
1112 | int err; | 1141 | int err; |
1113 | 1142 | ||
1143 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1144 | return 0; | ||
1145 | |||
1114 | err = ubi_io_is_bad(ubi, pnum); | 1146 | err = ubi_io_is_bad(ubi, pnum); |
1115 | if (!err) | 1147 | if (!err) |
1116 | return err; | 1148 | return err; |
@@ -1135,6 +1167,9 @@ static int paranoid_check_ec_hdr(const struct ubi_device *ubi, int pnum, | |||
1135 | int err; | 1167 | int err; |
1136 | uint32_t magic; | 1168 | uint32_t magic; |
1137 | 1169 | ||
1170 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1171 | return 0; | ||
1172 | |||
1138 | magic = be32_to_cpu(ec_hdr->magic); | 1173 | magic = be32_to_cpu(ec_hdr->magic); |
1139 | if (magic != UBI_EC_HDR_MAGIC) { | 1174 | if (magic != UBI_EC_HDR_MAGIC) { |
1140 | ubi_err("bad magic %#08x, must be %#08x", | 1175 | ubi_err("bad magic %#08x, must be %#08x", |
@@ -1170,6 +1205,9 @@ static int paranoid_check_peb_ec_hdr(const struct ubi_device *ubi, int pnum) | |||
1170 | uint32_t crc, hdr_crc; | 1205 | uint32_t crc, hdr_crc; |
1171 | struct ubi_ec_hdr *ec_hdr; | 1206 | struct ubi_ec_hdr *ec_hdr; |
1172 | 1207 | ||
1208 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1209 | return 0; | ||
1210 | |||
1173 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); | 1211 | ec_hdr = kzalloc(ubi->ec_hdr_alsize, GFP_NOFS); |
1174 | if (!ec_hdr) | 1212 | if (!ec_hdr) |
1175 | return -ENOMEM; | 1213 | return -ENOMEM; |
@@ -1211,6 +1249,9 @@ static int paranoid_check_vid_hdr(const struct ubi_device *ubi, int pnum, | |||
1211 | int err; | 1249 | int err; |
1212 | uint32_t magic; | 1250 | uint32_t magic; |
1213 | 1251 | ||
1252 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1253 | return 0; | ||
1254 | |||
1214 | magic = be32_to_cpu(vid_hdr->magic); | 1255 | magic = be32_to_cpu(vid_hdr->magic); |
1215 | if (magic != UBI_VID_HDR_MAGIC) { | 1256 | if (magic != UBI_VID_HDR_MAGIC) { |
1216 | ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", | 1257 | ubi_err("bad VID header magic %#08x at PEB %d, must be %#08x", |
@@ -1249,6 +1290,9 @@ static int paranoid_check_peb_vid_hdr(const struct ubi_device *ubi, int pnum) | |||
1249 | struct ubi_vid_hdr *vid_hdr; | 1290 | struct ubi_vid_hdr *vid_hdr; |
1250 | void *p; | 1291 | void *p; |
1251 | 1292 | ||
1293 | if (!(ubi_chk_flags & UBI_CHK_IO)) | ||
1294 | return 0; | ||
1295 | |||
1252 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); | 1296 | vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS); |
1253 | if (!vid_hdr) | 1297 | if (!vid_hdr) |
1254 | return -ENOMEM; | 1298 | return -ENOMEM; |
@@ -1294,15 +1338,26 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
1294 | int offset, int len) | 1338 | int offset, int len) |
1295 | { | 1339 | { |
1296 | int err, i; | 1340 | int err, i; |
1341 | size_t read; | ||
1342 | void *buf1; | ||
1343 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | ||
1297 | 1344 | ||
1298 | mutex_lock(&ubi->dbg_buf_mutex); | 1345 | if (!(ubi_chk_flags & UBI_CHK_IO)) |
1299 | err = ubi_io_read(ubi, ubi->dbg_peb_buf, pnum, offset, len); | 1346 | return 0; |
1300 | if (err) | 1347 | |
1301 | goto out_unlock; | 1348 | buf1 = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); |
1349 | if (!buf1) { | ||
1350 | ubi_err("cannot allocate memory to check writes"); | ||
1351 | return 0; | ||
1352 | } | ||
1353 | |||
1354 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf1); | ||
1355 | if (err && err != -EUCLEAN) | ||
1356 | goto out_free; | ||
1302 | 1357 | ||
1303 | for (i = 0; i < len; i++) { | 1358 | for (i = 0; i < len; i++) { |
1304 | uint8_t c = ((uint8_t *)buf)[i]; | 1359 | uint8_t c = ((uint8_t *)buf)[i]; |
1305 | uint8_t c1 = ((uint8_t *)ubi->dbg_peb_buf)[i]; | 1360 | uint8_t c1 = ((uint8_t *)buf1)[i]; |
1306 | int dump_len; | 1361 | int dump_len; |
1307 | 1362 | ||
1308 | if (c == c1) | 1363 | if (c == c1) |
@@ -1319,17 +1374,17 @@ int ubi_dbg_check_write(struct ubi_device *ubi, const void *buf, int pnum, | |||
1319 | ubi_msg("hex dump of the read buffer from %d to %d", | 1374 | ubi_msg("hex dump of the read buffer from %d to %d", |
1320 | i, i + dump_len); | 1375 | i, i + dump_len); |
1321 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | 1376 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, |
1322 | ubi->dbg_peb_buf + i, dump_len, 1); | 1377 | buf1 + i, dump_len, 1); |
1323 | ubi_dbg_dump_stack(); | 1378 | ubi_dbg_dump_stack(); |
1324 | err = -EINVAL; | 1379 | err = -EINVAL; |
1325 | goto out_unlock; | 1380 | goto out_free; |
1326 | } | 1381 | } |
1327 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1328 | 1382 | ||
1383 | vfree(buf1); | ||
1329 | return 0; | 1384 | return 0; |
1330 | 1385 | ||
1331 | out_unlock: | 1386 | out_free: |
1332 | mutex_unlock(&ubi->dbg_buf_mutex); | 1387 | vfree(buf1); |
1333 | return err; | 1388 | return err; |
1334 | } | 1389 | } |
1335 | 1390 | ||
@@ -1348,36 +1403,44 @@ int ubi_dbg_check_all_ff(struct ubi_device *ubi, int pnum, int offset, int len) | |||
1348 | { | 1403 | { |
1349 | size_t read; | 1404 | size_t read; |
1350 | int err; | 1405 | int err; |
1406 | void *buf; | ||
1351 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; | 1407 | loff_t addr = (loff_t)pnum * ubi->peb_size + offset; |
1352 | 1408 | ||
1353 | mutex_lock(&ubi->dbg_buf_mutex); | 1409 | if (!(ubi_chk_flags & UBI_CHK_IO)) |
1354 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, ubi->dbg_peb_buf); | 1410 | return 0; |
1411 | |||
1412 | buf = __vmalloc(len, GFP_KERNEL | GFP_NOFS, PAGE_KERNEL); | ||
1413 | if (!buf) { | ||
1414 | ubi_err("cannot allocate memory to check for 0xFFs"); | ||
1415 | return 0; | ||
1416 | } | ||
1417 | |||
1418 | err = ubi->mtd->read(ubi->mtd, addr, len, &read, buf); | ||
1355 | if (err && err != -EUCLEAN) { | 1419 | if (err && err != -EUCLEAN) { |
1356 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " | 1420 | ubi_err("error %d while reading %d bytes from PEB %d:%d, " |
1357 | "read %zd bytes", err, len, pnum, offset, read); | 1421 | "read %zd bytes", err, len, pnum, offset, read); |
1358 | goto error; | 1422 | goto error; |
1359 | } | 1423 | } |
1360 | 1424 | ||
1361 | err = ubi_check_pattern(ubi->dbg_peb_buf, 0xFF, len); | 1425 | err = ubi_check_pattern(buf, 0xFF, len); |
1362 | if (err == 0) { | 1426 | if (err == 0) { |
1363 | ubi_err("flash region at PEB %d:%d, length %d does not " | 1427 | ubi_err("flash region at PEB %d:%d, length %d does not " |
1364 | "contain all 0xFF bytes", pnum, offset, len); | 1428 | "contain all 0xFF bytes", pnum, offset, len); |
1365 | goto fail; | 1429 | goto fail; |
1366 | } | 1430 | } |
1367 | mutex_unlock(&ubi->dbg_buf_mutex); | ||
1368 | 1431 | ||
1432 | vfree(buf); | ||
1369 | return 0; | 1433 | return 0; |
1370 | 1434 | ||
1371 | fail: | 1435 | fail: |
1372 | ubi_err("paranoid check failed for PEB %d", pnum); | 1436 | ubi_err("paranoid check failed for PEB %d", pnum); |
1373 | ubi_msg("hex dump of the %d-%d region", offset, offset + len); | 1437 | ubi_msg("hex dump of the %d-%d region", offset, offset + len); |
1374 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, | 1438 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 1, buf, len, 1); |
1375 | ubi->dbg_peb_buf, len, 1); | ||
1376 | err = -EINVAL; | 1439 | err = -EINVAL; |
1377 | error: | 1440 | error: |
1378 | ubi_dbg_dump_stack(); | 1441 | ubi_dbg_dump_stack(); |
1379 | mutex_unlock(&ubi->dbg_buf_mutex); | 1442 | vfree(buf); |
1380 | return err; | 1443 | return err; |
1381 | } | 1444 | } |
1382 | 1445 | ||
1383 | #endif /* CONFIG_MTD_UBI_DEBUG_PARANOID */ | 1446 | #endif /* CONFIG_MTD_UBI_DEBUG */ |