1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/types.h>
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/spinlock.h>
19#include <linux/slab.h>
20#include <linux/kmsg_dump.h>
21#include <linux/pstore.h>
22#include <linux/ctype.h>
23#include <linux/zlib.h>
24#include <asm/uaccess.h>
25#include <asm/nvram.h>
26#include <asm/rtas.h>
27#include <asm/prom.h>
28#include <asm/machdep.h>
29
30
31#define NVRW_CNT 0x20
32
33
34
35
36
37
38#define OOPS_HDR_VERSION 5000
39
40static unsigned int nvram_size;
41static int nvram_fetch, nvram_store;
42static char nvram_buf[NVRW_CNT];
43static DEFINE_SPINLOCK(nvram_lock);
44
45struct err_log_info {
46 int error_type;
47 unsigned int seq_num;
48};
49
50struct nvram_os_partition {
51 const char *name;
52 int req_size;
53 int min_size;
54 long size;
55 long index;
56 bool os_partition;
57};
58
59static struct nvram_os_partition rtas_log_partition = {
60 .name = "ibm,rtas-log",
61 .req_size = 2079,
62 .min_size = 1055,
63 .index = -1,
64 .os_partition = true
65};
66
67static struct nvram_os_partition oops_log_partition = {
68 .name = "lnx,oops-log",
69 .req_size = 4000,
70 .min_size = 2000,
71 .index = -1,
72 .os_partition = true
73};
74
75static const char *pseries_nvram_os_partitions[] = {
76 "ibm,rtas-log",
77 "lnx,oops-log",
78 NULL
79};
80
81struct oops_log_info {
82 u16 version;
83 u16 report_length;
84 u64 timestamp;
85} __attribute__((packed));
86
87static void oops_to_nvram(struct kmsg_dumper *dumper,
88 enum kmsg_dump_reason reason);
89
90static struct kmsg_dumper nvram_kmsg_dumper = {
91 .dump = oops_to_nvram
92};
93
94
95#define NVRAM_RTAS_READ_TIMEOUT 5
96static unsigned long last_unread_rtas_event;
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123static size_t big_oops_buf_sz;
124static char *big_oops_buf, *oops_buf;
125static char *oops_data;
126static size_t oops_data_sz;
127
128
129#define COMPR_LEVEL 6
130#define WINDOW_BITS 12
131#define MEM_LEVEL 4
132static struct z_stream_s stream;
133
134#ifdef CONFIG_PSTORE
135static struct nvram_os_partition of_config_partition = {
136 .name = "of-config",
137 .index = -1,
138 .os_partition = false
139};
140
141static struct nvram_os_partition common_partition = {
142 .name = "common",
143 .index = -1,
144 .os_partition = false
145};
146
147static enum pstore_type_id nvram_type_ids[] = {
148 PSTORE_TYPE_DMESG,
149 PSTORE_TYPE_PPC_RTAS,
150 PSTORE_TYPE_PPC_OF,
151 PSTORE_TYPE_PPC_COMMON,
152 -1
153};
154static int read_type;
155static unsigned long last_rtas_event;
156#endif
157
158static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index)
159{
160 unsigned int i;
161 unsigned long len;
162 int done;
163 unsigned long flags;
164 char *p = buf;
165
166
167 if (nvram_size == 0 || nvram_fetch == RTAS_UNKNOWN_SERVICE)
168 return -ENODEV;
169
170 if (*index >= nvram_size)
171 return 0;
172
173 i = *index;
174 if (i + count > nvram_size)
175 count = nvram_size - i;
176
177 spin_lock_irqsave(&nvram_lock, flags);
178
179 for (; count != 0; count -= len) {
180 len = count;
181 if (len > NVRW_CNT)
182 len = NVRW_CNT;
183
184 if ((rtas_call(nvram_fetch, 3, 2, &done, i, __pa(nvram_buf),
185 len) != 0) || len != done) {
186 spin_unlock_irqrestore(&nvram_lock, flags);
187 return -EIO;
188 }
189
190 memcpy(p, nvram_buf, len);
191
192 p += len;
193 i += len;
194 }
195
196 spin_unlock_irqrestore(&nvram_lock, flags);
197
198 *index = i;
199 return p - buf;
200}
201
202static ssize_t pSeries_nvram_write(char *buf, size_t count, loff_t *index)
203{
204 unsigned int i;
205 unsigned long len;
206 int done;
207 unsigned long flags;
208 const char *p = buf;
209
210 if (nvram_size == 0 || nvram_store == RTAS_UNKNOWN_SERVICE)
211 return -ENODEV;
212
213 if (*index >= nvram_size)
214 return 0;
215
216 i = *index;
217 if (i + count > nvram_size)
218 count = nvram_size - i;
219
220 spin_lock_irqsave(&nvram_lock, flags);
221
222 for (; count != 0; count -= len) {
223 len = count;
224 if (len > NVRW_CNT)
225 len = NVRW_CNT;
226
227 memcpy(nvram_buf, p, len);
228
229 if ((rtas_call(nvram_store, 3, 2, &done, i, __pa(nvram_buf),
230 len) != 0) || len != done) {
231 spin_unlock_irqrestore(&nvram_lock, flags);
232 return -EIO;
233 }
234
235 p += len;
236 i += len;
237 }
238 spin_unlock_irqrestore(&nvram_lock, flags);
239
240 *index = i;
241 return p - buf;
242}
243
244static ssize_t pSeries_nvram_get_size(void)
245{
246 return nvram_size ? nvram_size : -ENODEV;
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
280 int length, unsigned int err_type, unsigned int error_log_cnt)
281{
282 int rc;
283 loff_t tmp_index;
284 struct err_log_info info;
285
286 if (part->index == -1) {
287 return -ESPIPE;
288 }
289
290 if (length > part->size) {
291 length = part->size;
292 }
293
294 info.error_type = err_type;
295 info.seq_num = error_log_cnt;
296
297 tmp_index = part->index;
298
299 rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index);
300 if (rc <= 0) {
301 pr_err("%s: Failed nvram_write (%d)\n", __FUNCTION__, rc);
302 return rc;
303 }
304
305 rc = ppc_md.nvram_write(buff, length, &tmp_index);
306 if (rc <= 0) {
307 pr_err("%s: Failed nvram_write (%d)\n", __FUNCTION__, rc);
308 return rc;
309 }
310
311 return 0;
312}
313
314int nvram_write_error_log(char * buff, int length,
315 unsigned int err_type, unsigned int error_log_cnt)
316{
317 int rc = nvram_write_os_partition(&rtas_log_partition, buff, length,
318 err_type, error_log_cnt);
319 if (!rc) {
320 last_unread_rtas_event = get_seconds();
321#ifdef CONFIG_PSTORE
322 last_rtas_event = get_seconds();
323#endif
324 }
325
326 return rc;
327}
328
329
330
331
332
333int nvram_read_partition(struct nvram_os_partition *part, char *buff,
334 int length, unsigned int *err_type,
335 unsigned int *error_log_cnt)
336{
337 int rc;
338 loff_t tmp_index;
339 struct err_log_info info;
340
341 if (part->index == -1)
342 return -1;
343
344 if (length > part->size)
345 length = part->size;
346
347 tmp_index = part->index;
348
349 if (part->os_partition) {
350 rc = ppc_md.nvram_read((char *)&info,
351 sizeof(struct err_log_info),
352 &tmp_index);
353 if (rc <= 0) {
354 pr_err("%s: Failed nvram_read (%d)\n", __FUNCTION__,
355 rc);
356 return rc;
357 }
358 }
359
360 rc = ppc_md.nvram_read(buff, length, &tmp_index);
361 if (rc <= 0) {
362 pr_err("%s: Failed nvram_read (%d)\n", __FUNCTION__, rc);
363 return rc;
364 }
365
366 if (part->os_partition) {
367 *error_log_cnt = info.seq_num;
368 *err_type = info.error_type;
369 }
370
371 return 0;
372}
373
374
375
376
377
378int nvram_read_error_log(char *buff, int length,
379 unsigned int *err_type, unsigned int *error_log_cnt)
380{
381 return nvram_read_partition(&rtas_log_partition, buff, length,
382 err_type, error_log_cnt);
383}
384
385
386
387
388int nvram_clear_error_log(void)
389{
390 loff_t tmp_index;
391 int clear_word = ERR_FLAG_ALREADY_LOGGED;
392 int rc;
393
394 if (rtas_log_partition.index == -1)
395 return -1;
396
397 tmp_index = rtas_log_partition.index;
398
399 rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index);
400 if (rc <= 0) {
401 printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
402 return rc;
403 }
404 last_unread_rtas_event = 0;
405
406 return 0;
407}
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426static int __init pseries_nvram_init_os_partition(struct nvram_os_partition
427 *part)
428{
429 loff_t p;
430 int size;
431
432
433 nvram_scan_partitions();
434
435
436 p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size);
437
438
439 if (p && size < part->min_size) {
440 pr_info("nvram: Found too small %s partition,"
441 " removing it...\n", part->name);
442 nvram_remove_partition(part->name, NVRAM_SIG_OS, NULL);
443 p = 0;
444 }
445
446
447 if (!p) {
448 p = nvram_create_partition(part->name, NVRAM_SIG_OS,
449 part->req_size, part->min_size);
450 if (p == -ENOSPC) {
451 pr_info("nvram: No room to create %s partition, "
452 "deleting any obsolete OS partitions...\n",
453 part->name);
454 nvram_remove_partition(NULL, NVRAM_SIG_OS,
455 pseries_nvram_os_partitions);
456 p = nvram_create_partition(part->name, NVRAM_SIG_OS,
457 part->req_size, part->min_size);
458 }
459 }
460
461 if (p <= 0) {
462 pr_err("nvram: Failed to find or create %s"
463 " partition, err %d\n", part->name, (int)p);
464 return -1;
465 }
466
467 part->index = p;
468 part->size = nvram_get_partition_size(p) - sizeof(struct err_log_info);
469
470 return 0;
471}
472
473
474
475
476
477
478
479
480
481static int clobbering_unread_rtas_event(void)
482{
483 return (oops_log_partition.index == rtas_log_partition.index
484 && last_unread_rtas_event
485 && get_seconds() - last_unread_rtas_event <=
486 NVRAM_RTAS_READ_TIMEOUT);
487}
488
489
490static int nvram_compress(const void *in, void *out, size_t inlen,
491 size_t outlen)
492{
493 int err, ret;
494
495 ret = -EIO;
496 err = zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS,
497 MEM_LEVEL, Z_DEFAULT_STRATEGY);
498 if (err != Z_OK)
499 goto error;
500
501 stream.next_in = in;
502 stream.avail_in = inlen;
503 stream.total_in = 0;
504 stream.next_out = out;
505 stream.avail_out = outlen;
506 stream.total_out = 0;
507
508 err = zlib_deflate(&stream, Z_FINISH);
509 if (err != Z_STREAM_END)
510 goto error;
511
512 err = zlib_deflateEnd(&stream);
513 if (err != Z_OK)
514 goto error;
515
516 if (stream.total_out >= stream.total_in)
517 goto error;
518
519 ret = stream.total_out;
520error:
521 return ret;
522}
523
524
525static int zip_oops(size_t text_len)
526{
527 struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
528 int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
529 oops_data_sz);
530 if (zipped_len < 0) {
531 pr_err("nvram: compression failed; returned %d\n", zipped_len);
532 pr_err("nvram: logging uncompressed oops/panic report\n");
533 return -1;
534 }
535 oops_hdr->version = OOPS_HDR_VERSION;
536 oops_hdr->report_length = (u16) zipped_len;
537 oops_hdr->timestamp = get_seconds();
538 return 0;
539}
540
541#ifdef CONFIG_PSTORE
542
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)
573{
574
575 read_type = -1;
576 return 0;
577}
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595static int nvram_pstore_write(enum pstore_type_id type,
596 enum kmsg_dump_reason reason,
597 u64 *id, unsigned int part, int count,
598 size_t hsize, size_t size,
599 struct pstore_info *psi)
600{
601 int rc;
602 unsigned int err_type = ERR_TYPE_KERNEL_PANIC;
603 struct oops_log_info *oops_hdr = (struct oops_log_info *) oops_buf;
604
605
606 if (part > 1 || type != PSTORE_TYPE_DMESG ||
607 clobbering_unread_rtas_event())
608 return -1;
609
610 oops_hdr->version = OOPS_HDR_VERSION;
611 oops_hdr->report_length = (u16) size;
612 oops_hdr->timestamp = get_seconds();
613
614 if (big_oops_buf) {
615 rc = zip_oops(size);
616
617
618
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,
636 (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
637 count);
638
639 if (rc != 0)
640 return rc;
641
642 *id = part;
643 return 0;
644}
645
646
647
648
649
650
651static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
652 int *count, struct timespec *time, char **buf,
653 struct pstore_info *psi)
654{
655 struct oops_log_info *oops_hdr;
656 unsigned int err_type, id_no, size = 0;
657 struct nvram_os_partition *part = NULL;
658 char *buff = NULL, *big_buff = NULL;
659 int sig = 0;
660 loff_t p;
661
662 read_type++;
663
664 switch (nvram_type_ids[read_type]) {
665 case PSTORE_TYPE_DMESG:
666 part = &oops_log_partition;
667 *type = PSTORE_TYPE_DMESG;
668 break;
669 case PSTORE_TYPE_PPC_RTAS:
670 part = &rtas_log_partition;
671 *type = PSTORE_TYPE_PPC_RTAS;
672 time->tv_sec = last_rtas_event;
673 time->tv_nsec = 0;
674 break;
675 case PSTORE_TYPE_PPC_OF:
676 sig = NVRAM_SIG_OF;
677 part = &of_config_partition;
678 *type = PSTORE_TYPE_PPC_OF;
679 *id = PSTORE_TYPE_PPC_OF;
680 time->tv_sec = 0;
681 time->tv_nsec = 0;
682 break;
683 case PSTORE_TYPE_PPC_COMMON:
684 sig = NVRAM_SIG_SYS;
685 part = &common_partition;
686 *type = PSTORE_TYPE_PPC_COMMON;
687 *id = PSTORE_TYPE_PPC_COMMON;
688 time->tv_sec = 0;
689 time->tv_nsec = 0;
690 break;
691 default:
692 return 0;
693 }
694
695 if (!part->os_partition) {
696 p = nvram_find_partition(part->name, sig, &size);
697 if (p <= 0) {
698 pr_err("nvram: Failed to find partition %s, "
699 "err %d\n", part->name, (int)p);
700 return 0;
701 }
702 part->index = p;
703 part->size = size;
704 }
705
706 buff = kmalloc(part->size, GFP_KERNEL);
707
708 if (!buff)
709 return -ENOMEM;
710
711 if (nvram_read_partition(part, buff, part->size, &err_type, &id_no)) {
712 kfree(buff);
713 return 0;
714 }
715
716 *count = 0;
717
718 if (part->os_partition)
719 *id = id_no;
720
721 if (nvram_type_ids[read_type] == PSTORE_TYPE_DMESG) {
722 int length, unzipped_len;
723 size_t hdr_size;
724
725 oops_hdr = (struct oops_log_info *)buff;
726 if (oops_hdr->version < OOPS_HDR_VERSION) {
727
728 hdr_size = sizeof(u16);
729 length = oops_hdr->version;
730 time->tv_sec = 0;
731 time->tv_nsec = 0;
732 } else {
733 hdr_size = sizeof(*oops_hdr);
734 length = oops_hdr->report_length;
735 time->tv_sec = oops_hdr->timestamp;
736 time->tv_nsec = 0;
737 }
738 *buf = kmalloc(length, GFP_KERNEL);
739 if (*buf == NULL)
740 return -ENOMEM;
741 memcpy(*buf, buff + hdr_size, length);
742 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;
762 }
763
764 *buf = buff;
765 return part->size;
766}
767
768static struct pstore_info nvram_pstore_info = {
769 .owner = THIS_MODULE,
770 .name = "nvram",
771 .open = nvram_pstore_open,
772 .read = nvram_pstore_read,
773 .write = nvram_pstore_write,
774};
775
776static int nvram_pstore_init(void)
777{
778 int rc = 0;
779
780 if (big_oops_buf) {
781 nvram_pstore_info.buf = big_oops_buf;
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
788 rc = pstore_register(&nvram_pstore_info);
789 if (rc != 0)
790 pr_err("nvram: pstore_register() failed, defaults to "
791 "kmsg_dump; returned %d\n", rc);
792
793 return rc;
794}
795#else
796static int nvram_pstore_init(void)
797{
798 return -1;
799}
800#endif
801
802static void __init nvram_init_oops_partition(int rtas_partition_exists)
803{
804 int rc;
805 size_t size;
806
807 rc = pseries_nvram_init_os_partition(&oops_log_partition);
808 if (rc != 0) {
809 if (!rtas_partition_exists)
810 return;
811 pr_notice("nvram: Using %s partition to log both"
812 " RTAS errors and oops/panic reports\n",
813 rtas_log_partition.name);
814 memcpy(&oops_log_partition, &rtas_log_partition,
815 sizeof(rtas_log_partition));
816 }
817 oops_buf = kmalloc(oops_log_partition.size, GFP_KERNEL);
818 if (!oops_buf) {
819 pr_err("nvram: No memory for %s partition\n",
820 oops_log_partition.name);
821 return;
822 }
823 oops_data = oops_buf + sizeof(struct oops_log_info);
824 oops_data_sz = oops_log_partition.size - sizeof(struct oops_log_info);
825
826
827
828
829
830
831 big_oops_buf_sz = (oops_data_sz * 100) / 45;
832 big_oops_buf = kmalloc(big_oops_buf_sz, GFP_KERNEL);
833 if (big_oops_buf) {
834 size = max(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL),
835 zlib_inflate_workspacesize());
836 stream.workspace = kmalloc(size, GFP_KERNEL);
837 if (!stream.workspace) {
838 pr_err("nvram: No memory for compression workspace; "
839 "skipping compression of %s partition data\n",
840 oops_log_partition.name);
841 kfree(big_oops_buf);
842 big_oops_buf = NULL;
843 }
844 } else {
845 pr_err("No memory for uncompressed %s data; "
846 "skipping compression\n", oops_log_partition.name);
847 stream.workspace = NULL;
848 }
849
850 rc = nvram_pstore_init();
851
852 if (!rc)
853 return;
854
855 rc = kmsg_dump_register(&nvram_kmsg_dumper);
856 if (rc != 0) {
857 pr_err("nvram: kmsg_dump_register() failed; returned %d\n", rc);
858 kfree(oops_buf);
859 kfree(big_oops_buf);
860 kfree(stream.workspace);
861 }
862}
863
864static int __init pseries_nvram_init_log_partitions(void)
865{
866 int rc;
867
868 rc = pseries_nvram_init_os_partition(&rtas_log_partition);
869 nvram_init_oops_partition(rc == 0);
870 return 0;
871}
872machine_arch_initcall(pseries, pseries_nvram_init_log_partitions);
873
874int __init pSeries_nvram_init(void)
875{
876 struct device_node *nvram;
877 const unsigned int *nbytes_p;
878 unsigned int proplen;
879
880 nvram = of_find_node_by_type(NULL, "nvram");
881 if (nvram == NULL)
882 return -ENODEV;
883
884 nbytes_p = of_get_property(nvram, "#bytes", &proplen);
885 if (nbytes_p == NULL || proplen != sizeof(unsigned int)) {
886 of_node_put(nvram);
887 return -EIO;
888 }
889
890 nvram_size = *nbytes_p;
891
892 nvram_fetch = rtas_token("nvram-fetch");
893 nvram_store = rtas_token("nvram-store");
894 printk(KERN_INFO "PPC64 nvram contains %d bytes\n", nvram_size);
895 of_node_put(nvram);
896
897 ppc_md.nvram_read = pSeries_nvram_read;
898 ppc_md.nvram_write = pSeries_nvram_write;
899 ppc_md.nvram_size = pSeries_nvram_get_size;
900
901 return 0;
902}
903
904
905
906
907
908
909
910
911
912static void oops_to_nvram(struct kmsg_dumper *dumper,
913 enum kmsg_dump_reason reason)
914{
915 struct oops_log_info *oops_hdr = (struct oops_log_info *)oops_buf;
916 static unsigned int oops_count = 0;
917 static bool panicking = false;
918 static DEFINE_SPINLOCK(lock);
919 unsigned long flags;
920 size_t text_len;
921 unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
922 int rc = -1;
923
924 switch (reason) {
925 case KMSG_DUMP_RESTART:
926 case KMSG_DUMP_HALT:
927 case KMSG_DUMP_POWEROFF:
928
929 return;
930 case KMSG_DUMP_OOPS:
931 break;
932 case KMSG_DUMP_PANIC:
933 panicking = true;
934 break;
935 case KMSG_DUMP_EMERG:
936 if (panicking)
937
938 return;
939 break;
940 default:
941 pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n",
942 __FUNCTION__, (int) reason);
943 return;
944 }
945
946 if (clobbering_unread_rtas_event())
947 return;
948
949 if (!spin_trylock_irqsave(&lock, flags))
950 return;
951
952 if (big_oops_buf) {
953 kmsg_dump_get_buffer(dumper, false,
954 big_oops_buf, big_oops_buf_sz, &text_len);
955 rc = zip_oops(text_len);
956 }
957 if (rc != 0) {
958 kmsg_dump_rewind(dumper);
959 kmsg_dump_get_buffer(dumper, false,
960 oops_data, oops_data_sz, &text_len);
961 err_type = ERR_TYPE_KERNEL_PANIC;
962 oops_hdr->version = OOPS_HDR_VERSION;
963 oops_hdr->report_length = (u16) text_len;
964 oops_hdr->timestamp = get_seconds();
965 }
966
967 (void) nvram_write_os_partition(&oops_log_partition, oops_buf,
968 (int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type,
969 ++oops_count);
970
971 spin_unlock_irqrestore(&lock, flags);
972}
973