diff options
Diffstat (limited to 'fs/pstore/ram.c')
| -rw-r--r-- | fs/pstore/ram.c | 53 |
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; | |||
| 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 | ||
| @@ -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 | ||
| 175 | static 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 | |||
| 167 | static ssize_t ramoops_pstore_read(u64 *id, enum pstore_type_id *type, | 181 | static 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); |
| 526 | fail_clear: | 551 | fail_clear: |
| 527 | cxt->pstore.bufsize = 0; | 552 | cxt->pstore.bufsize = 0; |
| 528 | fail_cnt: | 553 | kfree(cxt->mprz); |
| 554 | fail_init_mprz: | ||
| 529 | kfree(cxt->fprz); | 555 | kfree(cxt->fprz); |
| 530 | fail_init_fprz: | 556 | fail_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 |
