Commit 1749c00f authored by Akinobu Mita's avatar Akinobu Mita Committed by David Woodhouse

mtd: mtd_nandecctest: ensure alignment requirement for bitops

Currently the data blocks which is used to test single bit error
correction is allocated statically and injecting single bit error is
implemented by using __change_bit() which must operate on the memory
aligned to the size of an "unsigned long".  But there is no such
guarantee for statically allocated array.

This fix the issue by allocating the data block dynamically by
kmalloc().  It also allocate the ecc code dynamically instead of
allocating statically on stack.

The reason to allocate the ecc code dynamically is that later change
will add tests which inject bit errors into the ecc code by bitops.
Signed-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent c5b8384a
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/random.h> #include <linux/random.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/mtd/nand_ecc.h> #include <linux/mtd/nand_ecc.h>
#if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE)
...@@ -31,16 +32,24 @@ static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data, ...@@ -31,16 +32,24 @@ static void dump_data_ecc(void *error_data, void *error_ecc, void *correct_data,
DUMP_PREFIX_NONE, 16, 1, correct_ecc, 3, false); DUMP_PREFIX_NONE, 16, 1, correct_ecc, 3, false);
} }
static unsigned char correct_data[512];
static unsigned char error_data[512];
static int nand_ecc_test(const size_t size) static int nand_ecc_test(const size_t size)
{ {
unsigned char correct_ecc[3]; int err = 0;
unsigned char error_ecc[3]; void *error_data;
void *error_ecc;
void *correct_data;
void *correct_ecc;
char testname[30]; char testname[30];
BUG_ON(sizeof(correct_data) < size); error_data = kmalloc(size, GFP_KERNEL);
error_ecc = kmalloc(3, GFP_KERNEL);
correct_data = kmalloc(size, GFP_KERNEL);
correct_ecc = kmalloc(3, GFP_KERNEL);
if (!error_data || !error_ecc || !correct_data || !correct_ecc) {
err = -ENOMEM;
goto error;
}
sprintf(testname, "nand-ecc-%zu", size); sprintf(testname, "nand-ecc-%zu", size);
...@@ -53,15 +62,21 @@ static int nand_ecc_test(const size_t size) ...@@ -53,15 +62,21 @@ static int nand_ecc_test(const size_t size)
__nand_calculate_ecc(error_data, size, error_ecc); __nand_calculate_ecc(error_data, size, error_ecc);
__nand_correct_data(error_data, correct_ecc, error_ecc, size); __nand_correct_data(error_data, correct_ecc, error_ecc, size);
if (!memcmp(correct_data, error_data, size)) { if (memcmp(correct_data, error_data, size)) {
pr_info("mtd_nandecctest: ok - %s\n", testname); pr_err("mtd_nandecctest: not ok - %s\n", testname);
return 0; dump_data_ecc(error_data, error_ecc, correct_data, correct_ecc,
size);
err = -EINVAL;
goto error;
} }
pr_info("mtd_nandecctest: ok - %s\n", testname);
pr_err("mtd_nandecctest: not ok - %s\n", testname); error:
dump_data_ecc(error_data, error_ecc, correct_data, correct_ecc, size); kfree(error_data);
kfree(error_ecc);
return -EINVAL; kfree(correct_data);
kfree(correct_ecc);
return err;
} }
#else #else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment