diff options
-rw-r--r-- | arch/powerpc/platforms/pseries/nvram.c | 102 |
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 */ | ||
543 | int 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; | ||
568 | error: | ||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | static int nvram_pstore_open(struct pstore_info *psi) | 542 | static 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) | |||
802 | static void __init nvram_init_oops_partition(int rtas_partition_exists) | 726 | static 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); |