pstore/ram: Add ECC support
authorAnton Vorontsov <anton.vorontsov@linaro.org>
Thu, 17 May 2012 07:15:34 +0000 (00:15 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 May 2012 15:51:59 +0000 (08:51 -0700)
This is now straightforward: just introduce a module parameter and pass
the needed value to persistent_ram_new().

Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: Marco Stornelli <marco.stornelli@gmail.com>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ramoops.txt
fs/pstore/ram.c
include/linux/pstore_ram.h

index 470d2c4db6ff3d8c558a19e6c4f22ba0a277733d..4ba7db231cb275507363c0330b01656e8d254f08 100644 (file)
@@ -30,6 +30,11 @@ variable while setting 0 in that variable dumps only the panics.
 The module uses a counter to record multiple dumps but the counter gets reset
 on restart (i.e. new dumps after the restart will overwrite old ones).
 
+Ramoops also supports software ECC protection of persistent memory regions.
+This might be useful when a hardware reset was used to bring the machine back
+to life (i.e. a watchdog triggered). In such cases, RAM may be somewhat
+corrupt, but usually it is restorable.
+
 2. Setting the parameters
 
 Setting the ramoops parameters can be done in 2 different manners:
@@ -46,6 +51,7 @@ static struct ramoops_platform_data ramoops_data = {
         .mem_address            = <...>,
         .record_size            = <...>,
         .dump_oops              = <...>,
+        .ecc                    = <...>,
 };
 
 static struct platform_device ramoops_dev = {
index 62b13eda4691671d24905c7440a53b238249dae4..9123cce28c1e8d6f511738cda7435861f1261ef7 100644 (file)
@@ -56,12 +56,18 @@ module_param(dump_oops, int, 0600);
 MODULE_PARM_DESC(dump_oops,
                "set to 1 to dump oopses, 0 to only dump panics (default 1)");
 
+static int ramoops_ecc;
+module_param_named(ecc, ramoops_ecc, int, 0600);
+MODULE_PARM_DESC(ramoops_ecc,
+               "set to 1 to enable ECC support");
+
 struct ramoops_context {
        struct persistent_ram_zone **przs;
        phys_addr_t phys_addr;
        unsigned long size;
        size_t record_size;
        int dump_oops;
+       bool ecc;
        unsigned int count;
        unsigned int max_count;
        unsigned int read_count;
@@ -236,6 +242,7 @@ static int __init ramoops_probe(struct platform_device *pdev)
        cxt->phys_addr = pdata->mem_address;
        cxt->record_size = pdata->record_size;
        cxt->dump_oops = pdata->dump_oops;
+       cxt->ecc = pdata->ecc;
 
        cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_count, GFP_KERNEL);
        if (!cxt->przs) {
@@ -248,7 +255,7 @@ static int __init ramoops_probe(struct platform_device *pdev)
                size_t sz = cxt->record_size;
                phys_addr_t start = cxt->phys_addr + sz * i;
 
-               cxt->przs[i] = persistent_ram_new(start, sz, 0);
+               cxt->przs[i] = persistent_ram_new(start, sz, cxt->ecc);
                if (IS_ERR(cxt->przs[i])) {
                        err = PTR_ERR(cxt->przs[i]);
                        dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
@@ -281,9 +288,10 @@ static int __init ramoops_probe(struct platform_device *pdev)
        record_size = pdata->record_size;
        dump_oops = pdata->dump_oops;
 
-       pr_info("attached 0x%lx@0x%llx (%ux0x%zx)\n",
+       pr_info("attached 0x%lx@0x%llx (%ux0x%zx), ecc: %s\n",
                cxt->size, (unsigned long long)cxt->phys_addr,
-               cxt->max_count, cxt->record_size);
+               cxt->max_count, cxt->record_size,
+               ramoops_ecc ? "on" : "off");
 
        return 0;
 
@@ -347,6 +355,7 @@ static int __init ramoops_init(void)
                dummy_data->mem_address = mem_address;
                dummy_data->record_size = record_size;
                dummy_data->dump_oops = dump_oops;
+               dummy_data->ecc = ramoops_ecc;
                dummy = platform_create_bundle(&ramoops_driver, ramoops_probe,
                        NULL, 0, dummy_data,
                        sizeof(struct ramoops_platform_data));
index ffe24a52c5afb0c8844af8819f29202acbd56901..7ed7fd4dba49629fe6bd3ed2bef29b244bd7c6d9 100644 (file)
@@ -92,6 +92,7 @@ struct ramoops_platform_data {
        unsigned long   mem_address;
        unsigned long   record_size;
        int             dump_oops;
+       bool            ecc;
 };
 
 #endif