diff options
Diffstat (limited to 'fs/pstore/ram.c')
-rw-r--r-- | fs/pstore/ram.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 6150e54eed30..39d1373128e9 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c | |||
@@ -51,6 +51,10 @@ static ulong ramoops_ftrace_size = MIN_MEM_SIZE; | |||
51 | module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400); | 51 | module_param_named(ftrace_size, ramoops_ftrace_size, ulong, 0400); |
52 | MODULE_PARM_DESC(ftrace_size, "size of ftrace log"); | 52 | MODULE_PARM_DESC(ftrace_size, "size of ftrace log"); |
53 | 53 | ||
54 | static ulong ramoops_pmsg_size = MIN_MEM_SIZE; | ||
55 | module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400); | ||
56 | MODULE_PARM_DESC(pmsg_size, "size of user space message log"); | ||
57 | |||
54 | static ulong mem_address; | 58 | static ulong mem_address; |
55 | module_param(mem_address, ulong, 0400); | 59 | module_param(mem_address, ulong, 0400); |
56 | MODULE_PARM_DESC(mem_address, | 60 | MODULE_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 | ||
@@ -191,6 +199,9 @@ static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | |||
191 | prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt, | 199 | prz = ramoops_get_next_prz(&cxt->fprz, &cxt->ftrace_read_cnt, |
192 | 1, id, type, PSTORE_TYPE_FTRACE, 0); | 200 | 1, id, type, PSTORE_TYPE_FTRACE, 0); |
193 | if (!prz_ok(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)) | ||
194 | return 0; | 205 | return 0; |
195 | 206 | ||
196 | if (!persistent_ram_old(prz)) | 207 | if (!persistent_ram_old(prz)) |
@@ -258,6 +269,11 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, | |||
258 | return -ENOMEM; | 269 | return -ENOMEM; |
259 | persistent_ram_write(cxt->fprz, buf, size); | 270 | persistent_ram_write(cxt->fprz, buf, size); |
260 | 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; | ||
261 | } | 277 | } |
262 | 278 | ||
263 | if (type != PSTORE_TYPE_DMESG) | 279 | if (type != PSTORE_TYPE_DMESG) |
@@ -315,6 +331,9 @@ static int ramoops_pstore_erase(enum pstore_type_id type, u64 id, int count, | |||
315 | case PSTORE_TYPE_FTRACE: | 331 | case PSTORE_TYPE_FTRACE: |
316 | prz = cxt->fprz; | 332 | prz = cxt->fprz; |
317 | break; | 333 | break; |
334 | case PSTORE_TYPE_PMSG: | ||
335 | prz = cxt->mprz; | ||
336 | break; | ||
318 | default: | 337 | default: |
319 | return -EINVAL; | 338 | return -EINVAL; |
320 | } | 339 | } |
@@ -441,7 +460,7 @@ static int ramoops_probe(struct platform_device *pdev) | |||
441 | goto fail_out; | 460 | goto fail_out; |
442 | 461 | ||
443 | if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size && | 462 | if (!pdata->mem_size || (!pdata->record_size && !pdata->console_size && |
444 | !pdata->ftrace_size)) { | 463 | !pdata->ftrace_size && !pdata->pmsg_size)) { |
445 | 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 " |
446 | "non-zero\n"); | 465 | "non-zero\n"); |
447 | goto fail_out; | 466 | goto fail_out; |
@@ -453,6 +472,8 @@ static int ramoops_probe(struct platform_device *pdev) | |||
453 | pdata->console_size = rounddown_pow_of_two(pdata->console_size); | 472 | pdata->console_size = rounddown_pow_of_two(pdata->console_size); |
454 | if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size)) | 473 | if (pdata->ftrace_size && !is_power_of_2(pdata->ftrace_size)) |
455 | 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); | ||
456 | 477 | ||
457 | cxt->size = pdata->mem_size; | 478 | cxt->size = pdata->mem_size; |
458 | cxt->phys_addr = pdata->mem_address; | 479 | cxt->phys_addr = pdata->mem_address; |
@@ -460,12 +481,14 @@ static int ramoops_probe(struct platform_device *pdev) | |||
460 | cxt->record_size = pdata->record_size; | 481 | cxt->record_size = pdata->record_size; |
461 | cxt->console_size = pdata->console_size; | 482 | cxt->console_size = pdata->console_size; |
462 | cxt->ftrace_size = pdata->ftrace_size; | 483 | cxt->ftrace_size = pdata->ftrace_size; |
484 | cxt->pmsg_size = pdata->pmsg_size; | ||
463 | cxt->dump_oops = pdata->dump_oops; | 485 | cxt->dump_oops = pdata->dump_oops; |
464 | cxt->ecc_info = pdata->ecc_info; | 486 | cxt->ecc_info = pdata->ecc_info; |
465 | 487 | ||
466 | paddr = cxt->phys_addr; | 488 | paddr = cxt->phys_addr; |
467 | 489 | ||
468 | 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; | ||
469 | err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); | 492 | err = ramoops_init_przs(dev, cxt, &paddr, dump_mem_sz); |
470 | if (err) | 493 | if (err) |
471 | goto fail_out; | 494 | goto fail_out; |
@@ -480,6 +503,10 @@ static int ramoops_probe(struct platform_device *pdev) | |||
480 | if (err) | 503 | if (err) |
481 | goto fail_init_fprz; | 504 | goto fail_init_fprz; |
482 | 505 | ||
506 | err = ramoops_init_prz(dev, cxt, &cxt->mprz, &paddr, cxt->pmsg_size, 0); | ||
507 | if (err) | ||
508 | goto fail_init_mprz; | ||
509 | |||
483 | cxt->pstore.data = cxt; | 510 | cxt->pstore.data = cxt; |
484 | /* | 511 | /* |
485 | * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we | 512 | * Console can handle any buffer size, so prefer LOG_LINE_MAX. If we |
@@ -523,6 +550,8 @@ fail_buf: | |||
523 | kfree(cxt->pstore.buf); | 550 | kfree(cxt->pstore.buf); |
524 | fail_clear: | 551 | fail_clear: |
525 | cxt->pstore.bufsize = 0; | 552 | cxt->pstore.bufsize = 0; |
553 | kfree(cxt->mprz); | ||
554 | fail_init_mprz: | ||
526 | kfree(cxt->fprz); | 555 | kfree(cxt->fprz); |
527 | fail_init_fprz: | 556 | fail_init_fprz: |
528 | kfree(cxt->cprz); | 557 | kfree(cxt->cprz); |
@@ -580,6 +609,7 @@ static void ramoops_register_dummy(void) | |||
580 | dummy_data->record_size = record_size; | 609 | dummy_data->record_size = record_size; |
581 | dummy_data->console_size = ramoops_console_size; | 610 | dummy_data->console_size = ramoops_console_size; |
582 | dummy_data->ftrace_size = ramoops_ftrace_size; | 611 | dummy_data->ftrace_size = ramoops_ftrace_size; |
612 | dummy_data->pmsg_size = ramoops_pmsg_size; | ||
583 | dummy_data->dump_oops = dump_oops; | 613 | dummy_data->dump_oops = dump_oops; |
584 | /* | 614 | /* |
585 | * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC | 615 | * For backwards compatibility ramoops.ecc=1 means 16 bytes ECC |