aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c102
1 files changed, 12 insertions, 90 deletions
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 6a5f2b1f32ca..b966458e9b21 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -539,36 +539,6 @@ static int zip_oops(size_t text_len)
539} 539}
540 540
541#ifdef CONFIG_PSTORE 541#ifdef CONFIG_PSTORE
542/* Derived from logfs_uncompress */
543int nvram_decompress(void *in, void *out, size_t inlen, size_t outlen)
544{
545 int err, ret;
546
547 ret = -EIO;
548 err = zlib_inflateInit(&stream);
549 if (err != Z_OK)
550 goto error;
551
552 stream.next_in = in;
553 stream.avail_in = inlen;
554 stream.total_in = 0;
555 stream.next_out = out;
556 stream.avail_out = outlen;
557 stream.total_out = 0;
558
559 err = zlib_inflate(&stream, Z_FINISH);
560 if (err != Z_STREAM_END)
561 goto error;
562
563 err = zlib_inflateEnd(&stream);
564 if (err != Z_OK)
565 goto error;
566
567 ret = stream.total_out;
568error:
569 return ret;
570}
571
572static int nvram_pstore_open(struct pstore_info *psi) 542static int nvram_pstore_open(struct pstore_info *psi)
573{ 543{
574 /* Reset the iterator to start reading partitions again */ 544 /* Reset the iterator to start reading partitions again */
@@ -611,30 +581,8 @@ static int nvram_pstore_write(enum pstore_type_id type,
611 oops_hdr->report_length = (u16) size; 581 oops_hdr->report_length = (u16) size;
612 oops_hdr->timestamp = get_seconds(); 582 oops_hdr->timestamp = get_seconds();
613 583
614 if (big_oops_buf) {
615 rc = zip_oops(size);
616 /*
617 * If compression fails copy recent log messages from
618 * big_oops_buf to oops_data.
619 */
620 if (rc != 0) {
621 size_t diff = size - oops_data_sz + hsize;
622
623 if (size > oops_data_sz) {
624 memcpy(oops_data, big_oops_buf, hsize);
625 memcpy(oops_data + hsize, big_oops_buf + diff,
626 oops_data_sz - hsize);
627
628 oops_hdr->report_length = (u16) oops_data_sz;
629 } else
630 memcpy(oops_data, big_oops_buf, size);
631 } else
632 err_type = ERR_TYPE_KERNEL_PANIC_GZ;
633 }
634
635 rc = nvram_write_os_partition(&oops_log_partition, oops_buf, 584 rc = nvram_write_os_partition(&oops_log_partition, oops_buf,
636 (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type, 585 (int) (sizeof(*oops_hdr) + size), err_type, count);
637 count);
638 586
639 if (rc != 0) 587 if (rc != 0)
640 return rc; 588 return rc;
@@ -655,7 +603,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
655 struct oops_log_info *oops_hdr; 603 struct oops_log_info *oops_hdr;
656 unsigned int err_type, id_no, size = 0; 604 unsigned int err_type, id_no, size = 0;
657 struct nvram_os_partition *part = NULL; 605 struct nvram_os_partition *part = NULL;
658 char *buff = NULL, *big_buff = NULL; 606 char *buff = NULL;
659 int sig = 0; 607 int sig = 0;
660 loff_t p; 608 loff_t p;
661 609
@@ -719,8 +667,7 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
719 *id = id_no; 667 *id = id_no;
720 668
721 if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) { 669 if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
722 int length, unzipped_len; 670 size_t length, hdr_size;
723 size_t hdr_size;
724 671
725 oops_hdr = (struct oops_log_info *)buff; 672 oops_hdr = (struct oops_log_info *)buff;
726 if (oops_hdr->version < OOPS_HDR_VERSION) { 673 if (oops_hdr->version < OOPS_HDR_VERSION) {
@@ -740,24 +687,6 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
740 return -ENOMEM; 687 return -ENOMEM;
741 memcpy(*buf, buff + hdr_size, length); 688 memcpy(*buf, buff + hdr_size, length);
742 kfree(buff); 689 kfree(buff);
743
744 if (err_type == ERR_TYPE_KERNEL_PANIC_GZ) {
745 big_buff = kmalloc(big_oops_buf_sz, GFP_KERNEL);
746 if (!big_buff)
747 return -ENOMEM;
748
749 unzipped_len = nvram_decompress(*buf, big_buff,
750 length, big_oops_buf_sz);
751
752 if (unzipped_len < 0) {
753 pr_err("nvram: decompression failed, returned "
754 "rc %d\n", unzipped_len);
755 kfree(big_buff);
756 } else {
757 *buf = big_buff;
758 length = unzipped_len;
759 }
760 }
761 return length; 690 return length;
762 } 691 }
763 692
@@ -777,13 +706,8 @@ static int nvram_pstore_init(void)
777{ 706{
778 int rc = 0; 707 int rc = 0;
779 708
780 if (big_oops_buf) { 709 nvram_pstore_info.buf = oops_data;
781 nvram_pstore_info.buf = big_oops_buf; 710 nvram_pstore_info.bufsize = oops_data_sz;
782 nvram_pstore_info.bufsize = big_oops_buf_sz;
783 } else {
784 nvram_pstore_info.buf = oops_data;
785 nvram_pstore_info.bufsize = oops_data_sz;
786 }
787 711
788 rc = pstore_register(&nvram_pstore_info); 712 rc = pstore_register(&nvram_pstore_info);
789 if (rc != 0) 713 if (rc != 0)
@@ -802,7 +726,6 @@ static int nvram_pstore_init(void)
802static void __init nvram_init_oops_partition(int rtas_partition_exists) 726static void __init nvram_init_oops_partition(int rtas_partition_exists)
803{ 727{
804 int rc; 728 int rc;
805 size_t size;
806 729
807 rc = pseries_nvram_init_os_partition(&oops_log_partition); 730 rc = pseries_nvram_init_os_partition(&oops_log_partition);
808 if (rc != 0) { 731 if (rc != 0) {
@@ -823,6 +746,11 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
823 oops_data = oops_buf + sizeof(struct oops_log_info); 746 oops_data = oops_buf + sizeof(struct oops_log_info);
824 oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info); 747 oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
825 748
749 rc = nvram_pstore_init();
750
751 if (!rc)
752 return;
753
826 /* 754 /*
827 * Figure compression (preceded by elimination of each line's <n> 755 * Figure compression (preceded by elimination of each line's <n>
828 * severity prefix) will reduce the oops/panic report to at most 756 * severity prefix) will reduce the oops/panic report to at most
@@ -831,9 +759,8 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
831 big_oops_buf_sz = (oops_data_sz * 100) / 45; 759 big_oops_buf_sz = (oops_data_sz * 100) / 45;
832 big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL); 760 big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
833 if (big_oops_buf) { 761 if (big_oops_buf) {
834 size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), 762 stream.workspace = kmalloc(zlib_deflate_workspacesize(
835 zlib_inflate_workspacesize()); 763 WINDOW_BITS, MEM_LEVEL), GFP_KERNEL);
836 stream.workspace = kmalloc(size, GFP_KERNEL);
837 if (!stream.workspace) { 764 if (!stream.workspace) {
838 pr_err("nvram: No memory for compression workspace; " 765 pr_err("nvram: No memory for compression workspace; "
839 "skipping compression of %s partition data\n", 766 "skipping compression of %s partition data\n",
@@ -847,11 +774,6 @@ static void __init nvram_init_oops_partition(int rtas_partition_exists)
847 stream.workspace = NULL; 774 stream.workspace = NULL;
848 } 775 }
849 776
850 rc = nvram_pstore_init();
851
852 if (!rc)
853 return;
854
855 rc = kmsg_dump_register(&nvram_kmsg_dumper); 777 rc = kmsg_dump_register(&nvram_kmsg_dumper);
856 if (rc != 0) { 778 if (rc != 0) {
857 pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc); 779 pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);