pstore/ram: Add ECC support
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>
This commit is contained in:
parent
896fc1f0c4
commit
39eb7e9791
|
@ -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
|
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).
|
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
|
2. Setting the parameters
|
||||||
|
|
||||||
Setting the ramoops parameters can be done in 2 different manners:
|
Setting the ramoops parameters can be done in 2 different manners:
|
||||||
|
@ -46,6 +51,7 @@ static struct ramoops_platform_data ramoops_data = {
|
||||||
.mem_address = <...>,
|
.mem_address = <...>,
|
||||||
.record_size = <...>,
|
.record_size = <...>,
|
||||||
.dump_oops = <...>,
|
.dump_oops = <...>,
|
||||||
|
.ecc = <...>,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device ramoops_dev = {
|
static struct platform_device ramoops_dev = {
|
||||||
|
|
|
@ -56,12 +56,18 @@ module_param(dump_oops, int, 0600);
|
||||||
MODULE_PARM_DESC(dump_oops,
|
MODULE_PARM_DESC(dump_oops,
|
||||||
"set to 1 to dump oopses, 0 to only dump panics (default 1)");
|
"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 ramoops_context {
|
||||||
struct persistent_ram_zone **przs;
|
struct persistent_ram_zone **przs;
|
||||||
phys_addr_t phys_addr;
|
phys_addr_t phys_addr;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
size_t record_size;
|
size_t record_size;
|
||||||
int dump_oops;
|
int dump_oops;
|
||||||
|
bool ecc;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
unsigned int max_count;
|
unsigned int max_count;
|
||||||
unsigned int read_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->phys_addr = pdata->mem_address;
|
||||||
cxt->record_size = pdata->record_size;
|
cxt->record_size = pdata->record_size;
|
||||||
cxt->dump_oops = pdata->dump_oops;
|
cxt->dump_oops = pdata->dump_oops;
|
||||||
|
cxt->ecc = pdata->ecc;
|
||||||
|
|
||||||
cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_count, GFP_KERNEL);
|
cxt->przs = kzalloc(sizeof(*cxt->przs) * cxt->max_count, GFP_KERNEL);
|
||||||
if (!cxt->przs) {
|
if (!cxt->przs) {
|
||||||
|
@ -248,7 +255,7 @@ static int __init ramoops_probe(struct platform_device *pdev)
|
||||||
size_t sz = cxt->record_size;
|
size_t sz = cxt->record_size;
|
||||||
phys_addr_t start = cxt->phys_addr + sz * i;
|
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])) {
|
if (IS_ERR(cxt->przs[i])) {
|
||||||
err = PTR_ERR(cxt->przs[i]);
|
err = PTR_ERR(cxt->przs[i]);
|
||||||
dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
|
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;
|
record_size = pdata->record_size;
|
||||||
dump_oops = pdata->dump_oops;
|
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->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;
|
return 0;
|
||||||
|
|
||||||
|
@ -347,6 +355,7 @@ static int __init ramoops_init(void)
|
||||||
dummy_data->mem_address = mem_address;
|
dummy_data->mem_address = mem_address;
|
||||||
dummy_data->record_size = record_size;
|
dummy_data->record_size = record_size;
|
||||||
dummy_data->dump_oops = dump_oops;
|
dummy_data->dump_oops = dump_oops;
|
||||||
|
dummy_data->ecc = ramoops_ecc;
|
||||||
dummy = platform_create_bundle(&ramoops_driver, ramoops_probe,
|
dummy = platform_create_bundle(&ramoops_driver, ramoops_probe,
|
||||||
NULL, 0, dummy_data,
|
NULL, 0, dummy_data,
|
||||||
sizeof(struct ramoops_platform_data));
|
sizeof(struct ramoops_platform_data));
|
||||||
|
|
|
@ -92,6 +92,7 @@ struct ramoops_platform_data {
|
||||||
unsigned long mem_address;
|
unsigned long mem_address;
|
||||||
unsigned long record_size;
|
unsigned long record_size;
|
||||||
int dump_oops;
|
int dump_oops;
|
||||||
|
bool ecc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue