static int interval_tree_test_init(void) { int i, j; unsigned long results; cycles_t time1, time2, _time; printk(KERN_ALERT "interval tree insert/remove"); prandom_seed_state(&rnd, 3141592653589793238ULL); init(); time1 = get_cycles(); for (i = 0; i < PERF_LOOPS; i++) { for (j = 0; j < NODES; j++) interval_tree_insert(nodes + j, &root); for (j = 0; j < NODES; j++) interval_tree_remove(nodes + j, &root); } time2 = get_cycles(); _time = time2 - time1; _time = div_u64(_time, PERF_LOOPS); printk(" -> %llu cycles\n", (unsigned long long)time); printk(KERN_ALERT "interval tree search"); for (j = 0; j < NODES; j++) interval_tree_insert(nodes + j, &root); time1 = get_cycles(); results = 0; for (i = 0; i < SEARCH_LOOPS; i++) for (j = 0; j < SEARCHES; j++) results += search(queries[j], &root); time2 = get_cycles(); _time = time2 - time1; _time = div_u64(_time, SEARCH_LOOPS); results = div_u64(results, SEARCH_LOOPS); printk(" -> %llu cycles (%lu results)\n", (unsigned long long)time, results); return -EAGAIN; /* Fail will directly unload the module */ }
static int __init mtd_subpagetest_init(void) { int err = 0; uint32_t i; uint64_t tmp; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); if (dev < 0) { pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } pr_info("MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); pr_err("error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { pr_info("this test requires NAND flash\n"); goto out; } subpgsize = mtd->writesize >> mtd->subpage_sft; tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; pr_info("MTD device size %llu, eraseblock size %u, " "page size %u, subpage size %u, count of eraseblocks %u, " "pages per eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, mtd->writesize, subpgsize, ebcnt, pgcnt, mtd->oobsize); err = -ENOMEM; bufsize = subpgsize * 32; writebuf = kmalloc(bufsize, GFP_KERNEL); if (!writebuf) goto out; readbuf = kmalloc(bufsize, GFP_KERNEL); if (!readbuf) goto out; bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) goto out; err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; pr_info("writing whole device\n"); prandom_seed_state(&rnd_state, 1); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock(i); if (unlikely(err)) goto out; if (i % 256 == 0) pr_info("written up to eraseblock %u\n", i); cond_resched(); } pr_info("written %u eraseblocks\n", i); prandom_seed_state(&rnd_state, 1); pr_info("verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock(i); if (unlikely(err)) goto out; if (i % 256 == 0) pr_info("verified up to eraseblock %u\n", i); cond_resched(); } pr_info("verified %u eraseblocks\n", i); err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; err = verify_all_eraseblocks_ff(); if (err) goto out; /* Write all eraseblocks */ prandom_seed_state(&rnd_state, 3); pr_info("writing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = write_eraseblock2(i); if (unlikely(err)) goto out; if (i % 256 == 0) pr_info("written up to eraseblock %u\n", i); cond_resched(); } pr_info("written %u eraseblocks\n", i); /* Check all eraseblocks */ prandom_seed_state(&rnd_state, 3); pr_info("verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock2(i); if (unlikely(err)) goto out; if (i % 256 == 0) pr_info("verified up to eraseblock %u\n", i); cond_resched(); } pr_info("verified %u eraseblocks\n", i); err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; err = verify_all_eraseblocks_ff(); if (err) goto out; pr_info("finished with %d errors\n", errcnt); out: kfree(bbt); kfree(readbuf); kfree(writebuf); put_mtd_device(mtd); if (err) pr_info("error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
static int __init nandflash_ecctest_init(void) { unsigned int read_len = 0; int err = 0; loff_t offset = 0; unsigned int j = 0; struct rnd_state rnd_state; unsigned int corrected_num = 0; unsigned char *oobbuf_w = NULL; unsigned char *oobbuf_r = NULL; unsigned char *pagebuf_r = NULL; unsigned char *pagebuf_w = NULL; unsigned char *pagebuf_v = NULL; struct mtd_ecc_stats stats = {0}; struct mtd_part *mtd_part = NULL; printk("\n"); pr_info("--------------------------------------------------------------------------\n"); /*prepare work*/ mtd = get_mtd_device(NULL, 4); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); pr_err("Cannot get MTD device\n"); return err; } mtd_part = (struct mtd_part *)mtd; if(!mtd->_block_isbad || !mtd->_block_markbad || !mtd->_read_oob || !mtd->_write_oob || !mtd->_read || !mtd->_write) { pr_err("Some mtd's method may be NULL!"); goto out; } pagebuf_r = vmalloc(mtd->writesize); oobbuf_r = vmalloc(mtd->oobsize); pagebuf_w = vmalloc(mtd->writesize); pagebuf_v = vmalloc(mtd->writesize); oobbuf_w = vmalloc(mtd->oobsize); if(!pagebuf_r || !oobbuf_r || !pagebuf_w || !pagebuf_v || !oobbuf_w) { pr_err("Alloc buf failed!"); goto out; } //find a vailid block while(offset < mtd->size) { if(mtd->_block_isbad(mtd, offset)) { offset += mtd->erasesize; } else { break; } } if(offset >= mtd->size) { pr_err("The whole mtd_partion are bad!\n"); goto out; } err = erase_eraseblock(((long)offset)/mtd->erasesize); if(err) { pr_err("Erase failed at EB: %d\n", ((unsigned int)offset)/mtd->erasesize); goto out; } pr_info("Erase block %d successfully!\n", ((unsigned int)offset)/mtd->erasesize); //prepare value prandom_seed_state(&rnd_state, 1); prandom_bytes_state(&rnd_state, oobbuf_w, mtd->oobsize); prandom_bytes_state(&rnd_state, pagebuf_w, mtd->writesize); memcpy(pagebuf_v, pagebuf_w, mtd->writesize); err = write_oob(offset, pagebuf_w, mtd->writesize, oobbuf_w, mtd->oobsize, MTD_OPS_PLACE_OOB); if(err != 0) { pr_err("1.1 write failed!\n"); goto erase; } err = read_oob(offset, pagebuf_r, mtd->writesize, oobbuf_r, mtd->oobsize, MTD_OPS_PLACE_OOB); if(err != 0) { pr_err("1.1 read failed!\n"); goto erase; } if(memcmp(pagebuf_v, pagebuf_r, mtd->writesize) != 0) { pr_err("1.1 compare page failed!\n"); goto erase; } memcpy(oobbuf_w, oobbuf_r, mtd->oobsize); for(j = 0; j < mtd->writesize * 8; j ++) { offset += mtd->writesize; err = insert_biterror(pagebuf_w); if(err) { pr_err("Insert biterror failed!\n"); goto erase; } pr_info("Insert %d bit-flip sucessfully!\n", j + 1); err = write_oob(offset, pagebuf_w, mtd->writesize, oobbuf_w, mtd->oobsize, MTD_OPS_RAW); if(err != 0) { pr_err("2.1 write failed!\n"); goto erase; } stats = mtd_part->master->ecc_stats; err = read_oob(offset, pagebuf_r, mtd->writesize, oobbuf_r, mtd->oobsize, MTD_OPS_PLACE_OOB); if(err != 0) { pr_err("2.1 read failed!\n"); break; } if(memcmp(pagebuf_v, pagebuf_r, mtd->writesize) != 0) { pr_err("2.2 compare page failed!\n"); goto erase; } corrected_num = mtd_part->master->ecc_stats.corrected - stats.corrected; if(corrected_num != (j + 1)) { pr_err("Bit-flip num is not match, expected:%d, really:%d\n", j + 1, corrected_num); goto erase; } } pr_info("Test successfully, this system can corrected %d bit-flip at most!\n", j); erase: err = erase_eraseblock(((unsigned int)offset)/mtd->erasesize); if(err) { pr_err("1.3 erase failed at EB: %d\n", ((unsigned int)offset)/mtd->erasesize); goto out; } out: vfree(pagebuf_r); vfree(oobbuf_r); vfree(pagebuf_w); vfree(oobbuf_w); pr_info("--------------------------------------------------------------------------\n"); return -1; }
/* Initialize base and padding for each memory region randomized with KASLR */ void __init kernel_randomize_memory(void) { size_t i; unsigned long vaddr_start, vaddr; unsigned long rand, memory_tb; struct rnd_state rand_state; unsigned long remain_entropy; vaddr_start = pgtable_l5_enabled() ? __PAGE_OFFSET_BASE_L5 : __PAGE_OFFSET_BASE_L4; vaddr = vaddr_start; /* * These BUILD_BUG_ON checks ensure the memory layout is consistent * with the vaddr_start/vaddr_end variables. These checks are very * limited.... */ BUILD_BUG_ON(vaddr_start >= vaddr_end); BUILD_BUG_ON(vaddr_end != CPU_ENTRY_AREA_BASE); BUILD_BUG_ON(vaddr_end > __START_KERNEL_map); if (!kaslr_memory_enabled()) return; kaslr_regions[0].size_tb = 1 << (MAX_PHYSMEM_BITS - TB_SHIFT); kaslr_regions[1].size_tb = VMALLOC_SIZE_TB; /* * Update Physical memory mapping to available and * add padding if needed (especially for memory hotplug support). */ BUG_ON(kaslr_regions[0].base != &page_offset_base); memory_tb = DIV_ROUND_UP(max_pfn << PAGE_SHIFT, 1UL << TB_SHIFT) + CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING; /* Adapt phyiscal memory region size based on available memory */ if (memory_tb < kaslr_regions[0].size_tb) kaslr_regions[0].size_tb = memory_tb; /* Calculate entropy available between regions */ remain_entropy = vaddr_end - vaddr_start; for (i = 0; i < ARRAY_SIZE(kaslr_regions); i++) remain_entropy -= get_padding(&kaslr_regions[i]); prandom_seed_state(&rand_state, kaslr_get_random_long("Memory")); for (i = 0; i < ARRAY_SIZE(kaslr_regions); i++) { unsigned long entropy; /* * Select a random virtual address using the extra entropy * available. */ entropy = remain_entropy / (ARRAY_SIZE(kaslr_regions) - i); prandom_bytes_state(&rand_state, &rand, sizeof(rand)); entropy = (rand % (entropy + 1)) & PUD_MASK; vaddr += entropy; *kaslr_regions[i].base = vaddr; /* * Jump the region and add a minimum padding based on * randomization alignment. */ vaddr += get_padding(&kaslr_regions[i]); vaddr = round_up(vaddr + 1, PUD_SIZE); remain_entropy -= entropy; } }
static int __init mtd_oobtest_init(void) { int err = 0; unsigned int i; uint64_t tmp; struct mtd_oob_ops ops; loff_t addr = 0, addr0; printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); if (dev < 0) { pr_info("Please specify a valid mtd-device via module parameter\n"); pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } pr_info("MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); pr_err("error: cannot get MTD device\n"); return err; } if (!mtd_type_is_nand(mtd)) { pr_info("this test requires NAND flash\n"); goto out; } tmp = mtd->size; do_div(tmp, mtd->erasesize); ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; pr_info("MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, mtd->writesize, ebcnt, pgcnt, mtd->oobsize); err = -ENOMEM; readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!readbuf) goto out; writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!writebuf) goto out; bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) goto out; err = mtdtest_scan_for_bad_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 0; /* First test: write all OOB, read it back and verify */ pr_info("test 1 of 5\n"); err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; prandom_seed_state(&rnd_state, 1); err = write_whole_device(); if (err) goto out; prandom_seed_state(&rnd_state, 1); err = verify_all_eraseblocks(); if (err) goto out; /* * Second test: write all OOB, a block at a time, read it back and * verify. */ pr_info("test 2 of 5\n"); err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; prandom_seed_state(&rnd_state, 3); err = write_whole_device(); if (err) goto out; /* Check all eraseblocks */ prandom_seed_state(&rnd_state, 3); pr_info("verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; err = verify_eraseblock_in_one_go(i); if (err) goto out; if (i % 256 == 0) pr_info("verified up to eraseblock %u\n", i); cond_resched(); } pr_info("verified %u eraseblocks\n", i); /* * Third test: write OOB at varying offsets and lengths, read it back * and verify. */ pr_info("test 3 of 5\n"); err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; /* Write all eraseblocks */ use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 1; prandom_seed_state(&rnd_state, 5); err = write_whole_device(); if (err) goto out; /* Check all eraseblocks */ use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 1; prandom_seed_state(&rnd_state, 5); err = verify_all_eraseblocks(); if (err) goto out; use_offset = 0; use_len = mtd->ecclayout->oobavail; use_len_max = mtd->ecclayout->oobavail; vary_offset = 0; /* Fourth test: try to write off end of device */ pr_info("test 4 of 5\n"); err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; addr0 = 0; for (i = 0; i < ebcnt && bbt[i]; ++i) addr0 += mtd->erasesize; /* Attempt to write off end of OOB */ ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = 1; ops.oobretlen = 0; ops.ooboffs = mtd->ecclayout->oobavail; ops.datbuf = NULL; ops.oobbuf = writebuf; pr_info("attempting to start write past end of OOB\n"); pr_info("an error is expected...\n"); err = mtd_write_oob(mtd, addr0, &ops); if (err) { pr_info("error occurred as expected\n"); err = 0; } else { pr_err("error: can write past end of OOB\n"); errcnt += 1; } /* Attempt to read off end of OOB */ ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = 1; ops.oobretlen = 0; ops.ooboffs = mtd->ecclayout->oobavail; ops.datbuf = NULL; ops.oobbuf = readbuf; pr_info("attempting to start read past end of OOB\n"); pr_info("an error is expected...\n"); err = mtd_read_oob(mtd, addr0, &ops); if (err) { pr_info("error occurred as expected\n"); err = 0; } else { pr_err("error: can read past end of OOB\n"); errcnt += 1; } if (bbt[ebcnt - 1]) pr_info("skipping end of device tests because last " "block is bad\n"); else { /* Attempt to write off end of device */ ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail + 1; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = writebuf; pr_info("attempting to write past end of device\n"); pr_info("an error is expected...\n"); err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { pr_info("error occurred as expected\n"); err = 0; } else { pr_err("error: wrote past end of device\n"); errcnt += 1; } /* Attempt to read off end of device */ ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail + 1; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; pr_info("attempting to read past end of device\n"); pr_info("an error is expected...\n"); err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { pr_info("error occurred as expected\n"); err = 0; } else { pr_err("error: read past end of device\n"); errcnt += 1; } err = mtdtest_erase_eraseblock(mtd, ebcnt - 1); if (err) goto out; /* Attempt to write off end of device */ ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail; ops.oobretlen = 0; ops.ooboffs = 1; ops.datbuf = NULL; ops.oobbuf = writebuf; pr_info("attempting to write past end of device\n"); pr_info("an error is expected...\n"); err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { pr_info("error occurred as expected\n"); err = 0; } else { pr_err("error: wrote past end of device\n"); errcnt += 1; } /* Attempt to read off end of device */ ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail; ops.oobretlen = 0; ops.ooboffs = 1; ops.datbuf = NULL; ops.oobbuf = readbuf; pr_info("attempting to read past end of device\n"); pr_info("an error is expected...\n"); err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { pr_info("error occurred as expected\n"); err = 0; } else { pr_err("error: read past end of device\n"); errcnt += 1; } } /* Fifth test: write / read across block boundaries */ pr_info("test 5 of 5\n"); /* Erase all eraseblocks */ err = mtdtest_erase_good_eraseblocks(mtd, bbt, 0, ebcnt); if (err) goto out; /* Write all eraseblocks */ prandom_seed_state(&rnd_state, 11); pr_info("writing OOBs of whole device\n"); for (i = 0; i < ebcnt - 1; ++i) { int cnt = 2; int pg; size_t sz = mtd->ecclayout->oobavail; if (bbt[i] || bbt[i + 1]) continue; addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; prandom_bytes_state(&rnd_state, writebuf, sz * cnt); for (pg = 0; pg < cnt; ++pg) { ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = sz; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = writebuf + pg * sz; err = mtd_write_oob(mtd, addr, &ops); if (err) goto out; if (i % 256 == 0) pr_info("written up to eraseblock %u\n", i); cond_resched(); addr += mtd->writesize; } } pr_info("written %u eraseblocks\n", i); /* Check all eraseblocks */ prandom_seed_state(&rnd_state, 11); pr_info("verifying all eraseblocks\n"); for (i = 0; i < ebcnt - 1; ++i) { if (bbt[i] || bbt[i + 1]) continue; prandom_bytes_state(&rnd_state, writebuf, mtd->ecclayout->oobavail * 2); addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; ops.ooblen = mtd->ecclayout->oobavail * 2; ops.oobretlen = 0; ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); if (err) goto out; if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { pr_err("error: verify failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { pr_err("error: too many errors\n"); goto out; } } if (i % 256 == 0) pr_info("verified up to eraseblock %u\n", i); cond_resched(); } pr_info("verified %u eraseblocks\n", i); pr_info("finished with %d errors\n", errcnt); out: kfree(bbt); kfree(writebuf); kfree(readbuf); put_mtd_device(mtd); if (err) pr_info("error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; }
/* Initialize base and padding for each memory region randomized with KASLR */ void __init kernel_randomize_memory(void) { size_t i; unsigned long vaddr = vaddr_start; unsigned long rand, memory_tb; struct rnd_state rand_state; unsigned long remain_entropy; /* * All these BUILD_BUG_ON checks ensures the memory layout is * consistent with the vaddr_start/vaddr_end variables. */ BUILD_BUG_ON(vaddr_start >= vaddr_end); BUILD_BUG_ON(IS_ENABLED(CONFIG_X86_ESPFIX64) && vaddr_end >= EFI_VA_END); BUILD_BUG_ON((IS_ENABLED(CONFIG_X86_ESPFIX64) || IS_ENABLED(CONFIG_EFI)) && vaddr_end >= __START_KERNEL_map); BUILD_BUG_ON(vaddr_end > __START_KERNEL_map); if (!kaslr_memory_enabled()) return; /* * Update Physical memory mapping to available and * add padding if needed (especially for memory hotplug support). */ BUG_ON(kaslr_regions[0].base != &page_offset_base); memory_tb = DIV_ROUND_UP(max_pfn << PAGE_SHIFT, 1UL << TB_SHIFT) + CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING; /* Adapt phyiscal memory region size based on available memory */ if (memory_tb < kaslr_regions[0].size_tb) kaslr_regions[0].size_tb = memory_tb; /* Calculate entropy available between regions */ remain_entropy = vaddr_end - vaddr_start; for (i = 0; i < ARRAY_SIZE(kaslr_regions); i++) remain_entropy -= get_padding(&kaslr_regions[i]); prandom_seed_state(&rand_state, kaslr_get_random_long("Memory")); for (i = 0; i < ARRAY_SIZE(kaslr_regions); i++) { unsigned long entropy; /* * Select a random virtual address using the extra entropy * available. */ entropy = remain_entropy / (ARRAY_SIZE(kaslr_regions) - i); prandom_bytes_state(&rand_state, &rand, sizeof(rand)); entropy = (rand % (entropy + 1)) & PUD_MASK; vaddr += entropy; *kaslr_regions[i].base = vaddr; /* * Jump the region and add a minimum padding based on * randomization alignment. */ vaddr += get_padding(&kaslr_regions[i]); vaddr = round_up(vaddr + 1, PUD_SIZE); remain_entropy -= entropy; } }
static int nandflash_agetest(void) { int err = 0; loff_t addr = 0; unsigned int test_blk = 10; unsigned int op = 0; unsigned char *readbuf = NULL; unsigned char *writebuf = NULL; unsigned int written = 0, read = 0; unsigned int continue_err = 0; unsigned int erase_time = 0; readbuf = vmalloc(mtd->writesize); if(!readbuf) { pr_err("%s, alloc readbuf failed!\n", __func__); err = -ENOMEM; goto out; } writebuf = vmalloc(mtd->writesize); if(!writebuf) { pr_err("%s, alloc writebuf failed!\n", __func__); err = -ENOMEM; goto out; } while((test_blk < ebcnt) && bbt[test_blk]) { test_blk ++; } if(test_blk >= ebcnt) { pr_err("The whole mtd_partion are bad!\n"); err = -EINVAL; goto out; } pr_info("Begin to make block %d as bad!\n", test_blk); addr = test_blk * mtd->erasesize; prandom_seed_state(&rnd_state, 1); prandom_bytes_state(&rnd_state, writebuf, mtd->writesize); err = agetest_erase_eraseblock(test_blk); if(err) { pr_err("the first erase failed at addr: 0x%.8x, err: %d\n", (unsigned int)addr, err); goto out; } while(1) { if(signal_pending(current)) goto out; err = mtd_write(mtd, addr, mtd->writesize, &written, writebuf); if(err || written != mtd->writesize) { pr_err("write failed at addr: 0x%.8x, err: %d, written: %d, time: %d\n", (unsigned int)addr, err, written, op); goto erase; } err = mtd_read(mtd, addr, mtd->writesize, &read, readbuf); if(err || read != mtd->writesize) { pr_err("read failed at addr: 0x%.8x, err: %d, read: %d, time: %d\n", (unsigned int)addr, err, read, op); goto erase; } if(memcmp(readbuf, writebuf, mtd->writesize) != 0) { pr_err("verify failed at addr: 0x%.8x!", (unsigned int)addr); goto erase; } erase: err = agetest_erase_eraseblock(test_blk); if(err) { pr_err("erase failed at addr: 0x%.8x, err: %d, time: %d\n", (unsigned int)addr, err, op); break; } op += 1; if(op % 1024 == 0) pr_info("we have erased %d times!\n", op); } /*make sure the block has been erased as bad block*/ while(1) { if(signal_pending(current)) break; err = mtd_write(mtd, addr, mtd->writesize, &written, writebuf); err = agetest_erase_eraseblock(test_blk); if(err) { continue_err ++; if(continue_err >= 0x1000) { pr_info("after %d times continue erase, the block has been erased as bad block!", erase_time); break; } if( continue_err % 100 == 0) pr_info("the continue_err is %d!", continue_err); } else { if(continue_err) pr_info("the continue_err may be clean, old value is %d\n", continue_err); continue_err = 0; } erase_time ++; if( erase_time % 1024 == 0) pr_info("the erase_time is %d!", erase_time); } pr_info("mark block %d as bad!\n", test_blk); mtd->_block_markbad(mtd, addr); err = 0; out: vfree(readbuf); vfree(writebuf); pr_info("agetest finished, %d(%d) operations done!\n", op, erase_time); return err; }