aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/pstore/ftrace.c9
-rw-r--r--fs/pstore/platform.c30
-rw-r--r--fs/pstore/ram.c44
-rw-r--r--include/linux/pstore.h21
4 files changed, 55 insertions, 49 deletions
diff --git a/fs/pstore/ftrace.c b/fs/pstore/ftrace.c
index 899d0ba0bd6c..a5506ec6995e 100644
--- a/fs/pstore/ftrace.c
+++ b/fs/pstore/ftrace.c
@@ -37,6 +37,12 @@ static void notrace pstore_ftrace_call(unsigned long ip,
37{ 37{
38 unsigned long flags; 38 unsigned long flags;
39 struct pstore_ftrace_record rec = {}; 39 struct pstore_ftrace_record rec = {};
40 struct pstore_record record = {
41 .type = PSTORE_TYPE_FTRACE,
42 .buf = (char *)&rec,
43 .size = sizeof(rec),
44 .psi = psinfo,
45 };
40 46
41 if (unlikely(oops_in_progress)) 47 if (unlikely(oops_in_progress))
42 return; 48 return;
@@ -47,8 +53,7 @@ static void notrace pstore_ftrace_call(unsigned long ip,
47 rec.parent_ip = parent_ip; 53 rec.parent_ip = parent_ip;
48 pstore_ftrace_write_timestamp(&rec, pstore_ftrace_stamp++); 54 pstore_ftrace_write_timestamp(&rec, pstore_ftrace_stamp++);
49 pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id()); 55 pstore_ftrace_encode_cpu(&rec, raw_smp_processor_id());
50 psinfo->write_buf(PSTORE_TYPE_FTRACE, 0, NULL, 0, (void *)&rec, 56 psinfo->write_buf(&record);
51 0, sizeof(rec), psinfo);
52 57
53 local_irq_restore(flags); 58 local_irq_restore(flags);
54} 59}
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index aa3d6e572ede..5eecf9012459 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -587,8 +587,11 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
587 const char *e = s + c; 587 const char *e = s + c;
588 588
589 while (s < e) { 589 while (s < e) {
590 struct pstore_record record = {
591 .type = PSTORE_TYPE_CONSOLE,
592 .psi = psinfo,
593 };
590 unsigned long flags; 594 unsigned long flags;
591 u64 id;
592 595
593 if (c > psinfo->bufsize) 596 if (c > psinfo->bufsize)
594 c = psinfo->bufsize; 597 c = psinfo->bufsize;
@@ -599,8 +602,9 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
599 } else { 602 } else {
600 spin_lock_irqsave(&psinfo->buf_lock, flags); 603 spin_lock_irqsave(&psinfo->buf_lock, flags);
601 } 604 }
602 psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &id, 0, 605 record.buf = (char *)s;
603 s, 0, c, psinfo); 606 record.size = c;
607 psinfo->write_buf(&record);
604 spin_unlock_irqrestore(&psinfo->buf_lock, flags); 608 spin_unlock_irqrestore(&psinfo->buf_lock, flags);
605 s += c; 609 s += c;
606 c = e - s; 610 c = e - s;
@@ -630,10 +634,9 @@ static void pstore_unregister_console(void) {}
630 634
631static int pstore_write_compat(struct pstore_record *record) 635static int pstore_write_compat(struct pstore_record *record)
632{ 636{
633 return record->psi->write_buf(record->type, record->reason, 637 record->buf = psinfo->buf;
634 &record->id, record->part, 638
635 psinfo->buf, record->compressed, 639 return record->psi->write_buf(record);
636 record->size, record->psi);
637} 640}
638 641
639static int pstore_write_buf_user_compat(enum pstore_type_id type, 642static int pstore_write_buf_user_compat(enum pstore_type_id type,
@@ -653,6 +656,15 @@ static int pstore_write_buf_user_compat(enum pstore_type_id type,
653 bufsize = psinfo->bufsize; 656 bufsize = psinfo->bufsize;
654 spin_lock_irqsave(&psinfo->buf_lock, flags); 657 spin_lock_irqsave(&psinfo->buf_lock, flags);
655 for (i = 0; i < size; ) { 658 for (i = 0; i < size; ) {
659 struct pstore_record record = {
660 .type = type,
661 .reason = reason,
662 .id = id,
663 .part = part,
664 .buf = psinfo->buf,
665 .compressed = compressed,
666 .psi = psi,
667 };
656 size_t c = min(size - i, bufsize); 668 size_t c = min(size - i, bufsize);
657 669
658 ret = __copy_from_user(psinfo->buf, buf + i, c); 670 ret = __copy_from_user(psinfo->buf, buf + i, c);
@@ -660,8 +672,8 @@ static int pstore_write_buf_user_compat(enum pstore_type_id type,
660 ret = -EFAULT; 672 ret = -EFAULT;
661 break; 673 break;
662 } 674 }
663 ret = psi->write_buf(type, reason, id, part, psinfo->buf, 675 record.size = c;
664 compressed, c, psi); 676 ret = psi->write_buf(&record);
665 if (unlikely(ret < 0)) 677 if (unlikely(ret < 0))
666 break; 678 break;
667 i += c; 679 i += c;
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index a18575fe32e9..a7cdde60b1f9 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -378,23 +378,18 @@ static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz,
378 return len; 378 return len;
379} 379}
380 380
381static int notrace ramoops_pstore_write_buf(enum pstore_type_id type, 381static int notrace ramoops_pstore_write_buf(struct pstore_record *record)
382 enum kmsg_dump_reason reason,
383 u64 *id, unsigned int part,
384 const char *buf,
385 bool compressed, size_t size,
386 struct pstore_info *psi)
387{ 382{
388 struct ramoops_context *cxt = psi->data; 383 struct ramoops_context *cxt = record->psi->data;
389 struct persistent_ram_zone *prz; 384 struct persistent_ram_zone *prz;
390 size_t hlen; 385 size_t size, hlen;
391 386
392 if (type == PSTORE_TYPE_CONSOLE) { 387 if (record->type == PSTORE_TYPE_CONSOLE) {
393 if (!cxt->cprz) 388 if (!cxt->cprz)
394 return -ENOMEM; 389 return -ENOMEM;
395 persistent_ram_write(cxt->cprz, buf, size); 390 persistent_ram_write(cxt->cprz, record->buf, record->size);
396 return 0; 391 return 0;
397 } else if (type == PSTORE_TYPE_FTRACE) { 392 } else if (record->type == PSTORE_TYPE_FTRACE) {
398 int zonenum; 393 int zonenum;
399 394
400 if (!cxt->fprzs) 395 if (!cxt->fprzs)
@@ -407,33 +402,36 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
407 else 402 else
408 zonenum = 0; 403 zonenum = 0;
409 404
410 persistent_ram_write(cxt->fprzs[zonenum], buf, size); 405 persistent_ram_write(cxt->fprzs[zonenum], record->buf,
406 record->size);
411 return 0; 407 return 0;
412 } else if (type == PSTORE_TYPE_PMSG) { 408 } else if (record->type == PSTORE_TYPE_PMSG) {
413 pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__); 409 pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
414 return -EINVAL; 410 return -EINVAL;
415 } 411 }
416 412
417 if (type != PSTORE_TYPE_DMESG) 413 if (record->type != PSTORE_TYPE_DMESG)
418 return -EINVAL; 414 return -EINVAL;
419 415
420 /* Out of the various dmesg dump types, ramoops is currently designed 416 /*
417 * Out of the various dmesg dump types, ramoops is currently designed
421 * to only store crash logs, rather than storing general kernel logs. 418 * to only store crash logs, rather than storing general kernel logs.
422 */ 419 */
423 if (reason != KMSG_DUMP_OOPS && 420 if (record->reason != KMSG_DUMP_OOPS &&
424 reason != KMSG_DUMP_PANIC) 421 record->reason != KMSG_DUMP_PANIC)
425 return -EINVAL; 422 return -EINVAL;
426 423
427 /* Skip Oopes when configured to do so. */ 424 /* Skip Oopes when configured to do so. */
428 if (reason == KMSG_DUMP_OOPS && !cxt->dump_oops) 425 if (record->reason == KMSG_DUMP_OOPS && !cxt->dump_oops)
429 return -EINVAL; 426 return -EINVAL;
430 427
431 /* Explicitly only take the first part of any new crash. 428 /*
429 * Explicitly only take the first part of any new crash.
432 * If our buffer is larger than kmsg_bytes, this can never happen, 430 * If our buffer is larger than kmsg_bytes, this can never happen,
433 * and if our buffer is smaller than kmsg_bytes, we don't want the 431 * and if our buffer is smaller than kmsg_bytes, we don't want the
434 * report split across multiple records. 432 * report split across multiple records.
435 */ 433 */
436 if (part != 1) 434 if (record->part != 1)
437 return -ENOSPC; 435 return -ENOSPC;
438 436
439 if (!cxt->dprzs) 437 if (!cxt->dprzs)
@@ -441,10 +439,12 @@ static int notrace ramoops_pstore_write_buf(enum pstore_type_id type,
441 439
442 prz = cxt->dprzs[cxt->dump_write_cnt]; 440 prz = cxt->dprzs[cxt->dump_write_cnt];
443 441
444 hlen = ramoops_write_kmsg_hdr(prz, compressed); 442 /* Build header and append record contents. */
443 hlen = ramoops_write_kmsg_hdr(prz, record->compressed);
444 size = record->size;
445 if (size + hlen > prz->buffer_size) 445 if (size + hlen > prz->buffer_size)
446 size = prz->buffer_size - hlen; 446 size = prz->buffer_size - hlen;
447 persistent_ram_write(prz, buf, size);