aboutsummaryrefslogtreecommitdiffstats
path: root/fs/pstore/ram.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r--fs/pstore/ram.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 8613e5b35c22..39d1373128e9 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -51,6 +51,10 @@ static ulong ramoops_ftrace_size = MIN_MEM_SIZE;
51module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400); 51module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400);
52MODULE_PARM_DESC(ftrace_size, "size of ftrace log"); 52MODULE_PARM_DESC(ftrace_size, "size of ftrace log");
53 53
54static ulong ramoops_pmsg_size = MIN_MEM_SIZE;
55module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400);
56MODULE_PARM_DESC(pmsg_size, "size of user space message log");
57
54static ulong mem_address; 58static ulong mem_address;
55module_param(mem_address, ulong, 0400); 59module_param(mem_address, ulong, 0400);
56MODULE_PARM_DESC(mem_address, 60MODULE_PARM_DESC(mem_address,
@@ -82,12 +86,14 @@ struct ramoops_context {
82 struct persistent_ram_zone **przs; 86 struct persistent_ram_zone **przs;
83 struct persistent_ram_zone *cprz; 87 struct persistent_ram_zone *cprz;
84 struct persistent_ram_zone *fprz; 88 struct persistent_ram_zone *fprz;
89 struct persistent_ram_zone *mprz;
85 phys_addr_t phys_addr; 90 phys_addr_t phys_addr;
86 unsigned long size; 91 unsigned long size;
87 unsigned int memtype; 92 unsigned int memtype;
88 size_t record_size; 93 size_t record_size;
89 size_t console_size; 94 size_t console_size;
90 size_t ftrace_size; 95 size_t ftrace_size;
96 size_t pmsg_size;
91 int dump_oops; 97 int dump_oops;
92 struct persistent_ram_ecc_info ecc_info; 98 struct persistent_ram_ecc_info ecc_info;
93 unsigned int max_dump_cnt; 99 unsigned int max_dump_cnt;
@@ -96,6 +102,7 @@ struct ramoops_context {
96 unsigned int dump_read_cnt; 102 unsigned int dump_read_cnt;
97 unsigned int console_read_cnt; 103 unsigned int console_read_cnt;
98 unsigned int ftrace_read_cnt; 104 unsigned int ftrace_read_cnt;
105 unsigned int pmsg_read_cnt;
99 struct pstore_info pstore; 106 struct pstore_info pstore;
100}; 107};
101 108
@@ -109,6 +116,7 @@ static int ramoops_pstore_open(struct pstore_info *psi)
109 cxt->dump_read_cnt = 0; 116 cxt->dump_read_cnt = 0;
110 cxt->console_read_cnt = 0; 117 cxt->console_read_cnt = 0;
111 cxt->ftrace_read_cnt = 0; 118 cxt->ftrace_read_cnt = 0;
119 cxt->pmsg_read_cnt = 0;
112 return 0; 120 return 0;
113} 121}
114 122
@@ -164,6 +172,12 @@ static int ramoops_read_kmsg_hdr(char *buffer, struct timespec *time,
164 return header_length; 172 return header_length;
165} 173}
166 174
175static bool prz_ok(struct persistent_ram_zone *prz)
176{
177 return !!prz && !!(persistent_ram_old_size(prz) +
178 persistent_ram_ecc_string(prz, NULL, 0));
179}
180
167static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, 181static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
168 int *count, struct timespec *time, 182 int *count, struct timespec *time,
169 char **buf, bool *compressed, 183 char **buf, bool *compressed,
@@ -178,13 +192,16 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type,
178 prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt, 192 prz = ramoops_get_next_prz(cxt->przs, &cxt->dump_read_cnt,
179 cxt->max_dump_cnt, id, type, 193 cxt->max_dump_cnt, id, type,
180 PSTORE_TYPE_DMESG, 1); 194 PSTORE_TYPE_DMESG, 1);
181 if (!prz) 195 if (!prz_ok(prz))
182 prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt, 196 prz = ramoops_get_next_prz(&cxt->cprz, &cxt->console_read_cnt,
183 1, id, type, PSTORE_TYPE_CONSOLE, 0); 197 1, id, type, PSTORE_TYPE_CONSOLE, 0);
184 if (!prz) 198 if (!prz_ok(prz))
185 prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt, 199 prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt,
186 1, id, type, PSTORE_TYPE_FTRACE, 0); 200 1, id, type, PSTORE_TYPE_FTRACE, 0);
187 if (!prz) 201 if (!prz_ok(prz))
202 prz = ramoops_get_next_prz(&cxt->mprz, &cxt->pmsg_read_cnt,
203 1, id, type, PSTORE_TYPE_PMSG, 0);
204 if (!prz_ok(prz))
188 return 0; 205 return 0;
189 206
190 if (!persistent_ram_old(prz)) 207 if (!persistent_ram_old(prz))
@@ -252,6 +269,11 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
252 return -ENOMEM; 269 return -ENOMEM;
253 persistent_ram_write(cxt->fprz, buf, size); 270 persistent_ram_write(cxt->fprz, buf, size);
254 return 0; 271 return 0;
272 } else if (type == PSTORE_TYPE_PMSG) {
273 if (!cxt->mprz)
274 return -ENOMEM;
275 persistent_ram_write(cxt->mprz, buf, size);
276 return 0;
255 } 277 }
256 278
257 if (type != PSTORE_TYPE_DMESG) 279 if (type != PSTORE_TYPE_DMESG)
@@ -309,6 +331,9 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count,
309 case PSTORE_TYPE_FTRACE: 331 case PSTORE_TYPE_FTRACE:
310 prz = cxt->fprz; 332 prz = cxt->fprz;
311 break; 333 break;
334 case PSTORE_TYPE_PMSG:
335 prz = cxt->mprz;
336 break;
312 default: 337 default:
313 return -EINVAL; 338 return -EINVAL;
314 } 339 }
@@ -435,7 +460,7 @@ static int ramoops_probe(struct platform_device *pdev)
435 goto fail_out; 460 goto fail_out;
436 461
437 if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size && 462 if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size &&
438 !pdata->ftrace_size)) { 463 !pdata->ftrace_size && !pdata->pmsg_size)) {
439 pr_err("The memory size and the record/console size must be " 464 pr_err("The memory size and the record/console size must be "
440 "non-zero\n"); 465 "non-zero\n");
441 goto fail_out; 466 goto fail_out;
@@ -447,6 +472,8 @@ static int ramoops_probe(struct platform_device *pdev)
447 pdata->console_size = rounddown_pow_of_two(pdata->console_size); 472 pdata->console_size = rounddown_pow_of_two(pdata->console_size);
448 if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size)) 473 if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size))
449 pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); 474 pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
475 if (pdata->pmsg_size && !is_power_of_2(pdata->pmsg_size))
476 pdata->pmsg_size = rounddown_pow_of_two(pdata->pmsg_size);
450 477
451 cxt->size = pdata->mem_size; 478 cxt->size = pdata->mem_size;
452 cxt->phys_addr = pdata->mem_address; 479 cxt->phys_addr = pdata->mem_address;
@@ -454,12 +481,14 @@ static int ramoops_probe(struct platform_device *pdev)
454 cxt->record_size = pdata->record_size; 481 cxt->record_size = pdata->record_size;
455 cxt->console_size = pdata->console_size; 482 cxt->console_size = pdata->console_size;
456 cxt->ftrace_size = pdata->ftrace_size; 483 cxt->ftrace_size = pdata->ftrace_size;
484 cxt->pmsg_size = pdata->pmsg_size;
457 cxt->dump_oops = pdata->dump_oops; 485 cxt->dump_oops = pdata->dump_oops;
458 cxt->ecc_info = pdata->ecc_info; 486 cxt->ecc_info = pdata->ecc_info;
459 487
460 paddr = cxt->phys_addr; 488 paddr = cxt->phys_addr;
461 489
462 dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size; 490 dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size
491 - cxt->pmsg_size;
463 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); 492 err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz);
464 if (err) 493 if (err)
465 goto fail_out; 494 goto fail_out;
@@ -474,13 +503,9 @@ static int ramoops_probe(struct platform_device *pdev)
474 if (err) 503 if (err)
475 goto fail_init_fprz; 504 goto fail_init_fprz;
476 505
477 if (!cxt->przs && !cxt->cprz && !cxt->fprz) { 506 err = ramoops_init_prz(dev, cxt, &cxt->mprz, &paddr, cxt->pmsg_size, 0);
478 pr_err("memory size too small, minimum is %zu\n", 507 if (err)
479 cxt->console_size + cxt->record_size + 508 goto fail_init_mprz;
480 cxt->ftrace_size);
481 err = -EINVAL;
482 goto fail_cnt;
483 }
484 509
485 cxt->pstore.data = cxt; 510 cxt->pstore.data = cxt;
486 /* 511 /*
@@ -525,7 +550,8 @@ fail_buf:
525 kfree(cxt->pstore.buf); 550 kfree(cxt->pstore.buf);
526fail_clear: 551fail_clear:
527 cxt->pstore.bufsize = 0; 552 cxt->pstore.bufsize = 0;
528fail_cnt: 553 kfree(cxt->mprz);
554fail_init_mprz:
529 kfree(cxt->fprz); 555 kfree(cxt->fprz);
530fail_init_fprz: 556fail_init_fprz:
531 kfree(cxt->cprz); 557 kfree(cxt->cprz);
@@ -583,6 +609,7 @@ static void ramoops_register_dummy(void)
583 dummy_data->record_size = record_size; 609 dummy_data->record_size = record_size;
584 dummy_data->console_size = ramoops_console_size; 610 dummy_data->console_size = ramoops_console_size;
585 dummy_data->ftrace_size = ramoops_ftrace_size; 611 dummy_data->ftrace_size = ramoops_ftrace_size;
612 dummy_data->pmsg_size = ramoops_pmsg_size;
586 dummy_data->dump_oops = dump_oops; 613 dummy_data->dump_oops = dump_oops;
587 /* 614 /*
588 * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC 615 * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC