cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mtd_test.c (2118B)


      1// SPDX-License-Identifier: GPL-2.0
      2#define pr_fmt(fmt) "mtd_test: " fmt
      3
      4#include <linux/module.h>
      5#include <linux/sched.h>
      6#include <linux/printk.h>
      7
      8#include "mtd_test.h"
      9
     10int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum)
     11{
     12	int err;
     13	struct erase_info ei;
     14	loff_t addr = (loff_t)ebnum * mtd->erasesize;
     15
     16	memset(&ei, 0, sizeof(struct erase_info));
     17	ei.addr = addr;
     18	ei.len  = mtd->erasesize;
     19
     20	err = mtd_erase(mtd, &ei);
     21	if (err) {
     22		pr_info("error %d while erasing EB %d\n", err, ebnum);
     23		return err;
     24	}
     25
     26	return 0;
     27}
     28
     29static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum)
     30{
     31	int ret;
     32	loff_t addr = (loff_t)ebnum * mtd->erasesize;
     33
     34	ret = mtd_block_isbad(mtd, addr);
     35	if (ret)
     36		pr_info("block %d is bad\n", ebnum);
     37
     38	return ret;
     39}
     40
     41int mtdtest_scan_for_bad_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
     42					unsigned int eb, int ebcnt)
     43{
     44	int i, bad = 0;
     45
     46	if (!mtd_can_have_bb(mtd))
     47		return 0;
     48
     49	pr_info("scanning for bad eraseblocks\n");
     50	for (i = 0; i < ebcnt; ++i) {
     51		bbt[i] = is_block_bad(mtd, eb + i) ? 1 : 0;
     52		if (bbt[i])
     53			bad += 1;
     54		cond_resched();
     55	}
     56	pr_info("scanned %d eraseblocks, %d are bad\n", i, bad);
     57
     58	return 0;
     59}
     60
     61int mtdtest_erase_good_eraseblocks(struct mtd_info *mtd, unsigned char *bbt,
     62				unsigned int eb, int ebcnt)
     63{
     64	int err;
     65	unsigned int i;
     66
     67	for (i = 0; i < ebcnt; ++i) {
     68		if (bbt[i])
     69			continue;
     70		err = mtdtest_erase_eraseblock(mtd, eb + i);
     71		if (err)
     72			return err;
     73		cond_resched();
     74	}
     75
     76	return 0;
     77}
     78
     79int mtdtest_read(struct mtd_info *mtd, loff_t addr, size_t size, void *buf)
     80{
     81	size_t read;
     82	int err;
     83
     84	err = mtd_read(mtd, addr, size, &read, buf);
     85	/* Ignore corrected ECC errors */
     86	if (mtd_is_bitflip(err))
     87		err = 0;
     88	if (!err && read != size)
     89		err = -EIO;
     90	if (err)
     91		pr_err("error: read failed at %#llx\n", addr);
     92
     93	return err;
     94}
     95
     96int mtdtest_write(struct mtd_info *mtd, loff_t addr, size_t size,
     97		const void *buf)
     98{
     99	size_t written;
    100	int err;
    101
    102	err = mtd_write(mtd, addr, size, &written, buf);
    103	if (!err && written != size)
    104		err = -EIO;
    105	if (err)
    106		pr_err("error: write failed at %#llx\n", addr);
    107
    108	return err;
    109}