cregit-Linux how code gets into the kernel

Release 4.11 arch/arm/plat-samsung/pm-check.c

/* linux/arch/arm/plat-s3c/pm-check.c
 *  originally in linux/arch/arm/plat-s3c24xx/pm.c
 *
 * Copyright (c) 2004-2008 Simtec Electronics
 *      http://armlinux.simtec.co.uk
 *      Ben Dooks <ben@simtec.co.uk>
 *
 * S3C Power Mangament - suspend/resume memory corruption check.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#include <linux/kernel.h>
#include <linux/suspend.h>
#include <linux/init.h>
#include <linux/crc32.h>
#include <linux/ioport.h>
#include <linux/slab.h>

#include <plat/pm-common.h>

#if CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE < 1
#error CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE must be a positive non-zero value
#endif

/* suspend checking code...
 *
 * this next area does a set of crc checks over all the installed
 * memory, so the system can verify if the resume was ok.
 *
 * CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
 * increasing it will mean that the area corrupted will be less easy to spot,
 * and reducing the size will cause the CRC save area to grow
*/


#define CHECK_CHUNKSIZE (CONFIG_SAMSUNG_PM_CHECK_CHUNKSIZE * 1024)


static u32 crc_size;	
/* size needed for the crc block */

static u32 *crcs;	
/* allocated over suspend/resume */


typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);

/* s3c_pm_run_res
 *
 * go through the given resource list, and look for system ram
*/


static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg) { while (ptr != NULL) { if (ptr->child != NULL) s3c_pm_run_res(ptr->child, fn, arg); if ((ptr->flags & IORESOURCE_SYSTEM_RAM) == IORESOURCE_SYSTEM_RAM) { S3C_PMDBG("Found system RAM at %08lx..%08lx\n", (unsigned long)ptr->start, (unsigned long)ptr->end); arg = (fn)(ptr, arg); } ptr = ptr->sibling; } }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks9597.94%266.67%
Toshi Kani22.06%133.33%
Total97100.00%3100.00%


static void s3c_pm_run_sysram(run_fn_t fn, u32 *arg) { s3c_pm_run_res(&iomem_resource, fn, arg); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks23100.00%1100.00%
Total23100.00%1100.00%


static u32 *s3c_pm_countram(struct resource *res, u32 *val) { u32 size = (u32)resource_size(res); size += CHECK_CHUNKSIZE-1; size /= CHECK_CHUNKSIZE; S3C_PMDBG("Area %08lx..%08lx, %d blocks\n", (unsigned long)res->start, (unsigned long)res->end, size); *val += size * sizeof(u32); return val; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks7095.89%266.67%
Joe Perches34.11%133.33%
Total73100.00%3100.00%

/* s3c_pm_prepare_check * * prepare the necessary information for creating the CRCs. This * must be done before the final save, as it will require memory * allocating, and thus touching bits of the kernel we do not * know about. */
void s3c_pm_check_prepare(void) { crc_size = 0; s3c_pm_run_sysram(s3c_pm_countram, &crc_size); S3C_PMDBG("s3c_pm_prepare_check: %u checks needed\n", crc_size); crcs = kmalloc(crc_size+4, GFP_KERNEL); if (crcs == NULL) printk(KERN_ERR "Cannot allocated CRC save area\n"); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks49100.00%1100.00%
Total49100.00%1100.00%


static u32 *s3c_pm_makecheck(struct resource *res, u32 *val) { unsigned long addr, left; for (addr = res->start; addr < res->end; addr += CHECK_CHUNKSIZE) { left = res->end - addr; if (left > CHECK_CHUNKSIZE) left = CHECK_CHUNKSIZE; *val = crc32_le(~0, phys_to_virt(addr), left); val++; } return val; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks82100.00%1100.00%
Total82100.00%1100.00%

/* s3c_pm_check_store * * compute the CRC values for the memory blocks before the final * sleep. */
void s3c_pm_check_store(void) { if (crcs != NULL) s3c_pm_run_sysram(s3c_pm_makecheck, crcs); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks20100.00%1100.00%
Total20100.00%1100.00%

/* in_region * * return TRUE if the area defined by ptr..ptr+size contains the * what..what+whatsz */
static inline int in_region(void *ptr, int size, void *what, size_t whatsz) { if ((what+whatsz) < ptr) return 0; if (what > (ptr+size)) return 0; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks50100.00%1100.00%
Total50100.00%1100.00%

/** * s3c_pm_runcheck() - helper to check a resource on restore. * @res: The resource to check * @vak: Pointer to list of CRC32 values to check. * * Called from the s3c_pm_check_restore() via s3c_pm_run_sysram(), this * function runs the given memory resource checking it against the stored * CRC to ensure that memory is restored. The function tries to skip as * many of the areas used during the suspend process. */
static u32 *s3c_pm_runcheck(struct resource *res, u32 *val) { unsigned long addr; unsigned long left; void *stkpage; void *ptr; u32 calc; stkpage = (void *)((u32)&calc & ~PAGE_MASK); for (addr = res->start; addr < res->end; addr += CHECK_CHUNKSIZE) { left = res->end - addr; if (left > CHECK_CHUNKSIZE) left = CHECK_CHUNKSIZE; ptr = phys_to_virt(addr); if (in_region(ptr, left, stkpage, 4096)) { S3C_PMDBG("skipping %08lx, has stack in\n", addr); goto skip_check; } if (in_region(ptr, left, crcs, crc_size)) { S3C_PMDBG("skipping %08lx, has crc block in\n", addr); goto skip_check; } /* calculate and check the checksum */ calc = crc32_le(~0, ptr, left); if (calc != *val) { printk(KERN_ERR "Restore CRC error at " "%08lx (%08x vs %08x)\n", addr, calc, *val); S3C_PMDBG("Restore CRC error at %08lx (%08x vs %08x)\n", addr, calc, *val); } skip_check: val++; } return val; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks203100.00%2100.00%
Total203100.00%2100.00%

/** * s3c_pm_check_restore() - memory check called on resume * * check the CRCs after the restore event and free the memory used * to hold them */
void s3c_pm_check_restore(void) { if (crcs != NULL) s3c_pm_run_sysram(s3c_pm_runcheck, crcs); }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks20100.00%2100.00%
Total20100.00%2100.00%

/** * s3c_pm_check_cleanup() - free memory resources * * Free the resources that where allocated by the suspend * memory check code. We do this separately from the * s3c_pm_check_restore() function as we cannot call any * functions that might sleep during that resume. */
void s3c_pm_check_cleanup(void) { kfree(crcs); crcs = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks16100.00%2100.00%
Total16100.00%2100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Ben Dooks69598.58%550.00%
Joe Perches30.43%110.00%
Tejun Heo30.43%110.00%
Toshi Kani20.28%110.00%
Tomasz Figa10.14%110.00%
Andrea Gelmini10.14%110.00%
Total705100.00%10100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.