15 #include <linux/types.h>
16 #include <linux/errno.h>
19 #include <linux/slab.h>
21 #include <linux/ctype.h>
23 #include <asm/uaccess.h>
24 #include <asm/nvram.h>
27 #include <asm/machdep.h>
32 static unsigned int nvram_size;
33 static int nvram_fetch, nvram_store;
51 .name =
"ibm,rtas-log",
58 .name =
"lnx,oops-log",
64 static const char *pseries_nvram_os_partitions[] = {
70 static void oops_to_nvram(
struct kmsg_dumper *dumper,
78 #define NVRAM_RTAS_READ_TIMEOUT 5
79 static unsigned long last_unread_rtas_event;
105 static size_t big_oops_buf_sz;
106 static char *big_oops_buf, *oops_buf;
107 static u16 *oops_len;
108 static char *oops_data;
109 static size_t oops_data_sz;
112 #define COMPR_LEVEL 6
113 #define WINDOW_BITS 12
126 if (nvram_size == 0 || nvram_fetch == RTAS_UNKNOWN_SERVICE)
129 if (*index >= nvram_size)
133 if (i + count > nvram_size)
134 count = nvram_size -
i;
138 for (; count != 0; count -= len) {
144 len) != 0) || len != done) {
145 spin_unlock_irqrestore(&nvram_lock, flags);
149 memcpy(p, nvram_buf, len);
155 spin_unlock_irqrestore(&nvram_lock, flags);
161 static ssize_t pSeries_nvram_write(
char *buf,
size_t count, loff_t *index)
169 if (nvram_size == 0 || nvram_store == RTAS_UNKNOWN_SERVICE)
172 if (*index >= nvram_size)
176 if (i + count > nvram_size)
177 count = nvram_size -
i;
181 for (; count != 0; count -= len) {
186 memcpy(nvram_buf, p, len);
189 len) != 0) || len != done) {
190 spin_unlock_irqrestore(&nvram_lock, flags);
197 spin_unlock_irqrestore(&nvram_lock, flags);
203 static ssize_t pSeries_nvram_get_size(
void)
205 return nvram_size ? nvram_size : -
ENODEV;
239 int length,
unsigned int err_type,
unsigned int error_log_cnt)
245 if (part->
index == -1) {
249 if (length > part->
size) {
256 tmp_index = part->
index;
264 rc =
ppc_md.nvram_write(buff, length, &tmp_index);
274 unsigned int err_type,
unsigned int error_log_cnt)
277 err_type, error_log_cnt);
288 unsigned int * err_type,
unsigned int * error_log_cnt)
294 if (rtas_log_partition.
index == -1)
297 if (length > rtas_log_partition.
size)
298 length = rtas_log_partition.
size;
300 tmp_index = rtas_log_partition.
index;
304 printk(
KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
308 rc =
ppc_md.nvram_read(buff, length, &tmp_index);
310 printk(
KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc);
326 int clear_word = ERR_FLAG_ALREADY_LOGGED;
329 if (rtas_log_partition.
index == -1)
332 tmp_index = rtas_log_partition.
index;
334 rc =
ppc_md.nvram_write((
char *)&clear_word,
sizeof(
int), &tmp_index);
336 printk(
KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc);
339 last_unread_rtas_event = 0;
374 if (p && size < part->min_size) {
375 pr_info(
"nvram: Found too small %s partition,"
376 " removing it...\n", part->
name);
386 pr_info(
"nvram: No room to create %s partition, "
387 "deleting any obsolete OS partitions...\n",
390 pseries_nvram_os_partitions);
397 pr_err(
"nvram: Failed to find or create %s"
398 " partition, err %d\n", part->
name, (
int)p);
408 static void __init nvram_init_oops_partition(
int rtas_partition_exists)
412 rc = pseries_nvram_init_os_partition(&oops_log_partition);
414 if (!rtas_partition_exists)
416 pr_notice(
"nvram: Using %s partition to log both"
417 " RTAS errors and oops/panic reports\n",
418 rtas_log_partition.
name);
419 memcpy(&oops_log_partition, &rtas_log_partition,
420 sizeof(rtas_log_partition));
424 pr_err(
"nvram: No memory for %s partition\n",
425 oops_log_partition.
name);
428 oops_len = (
u16*) oops_buf;
429 oops_data = oops_buf +
sizeof(
u16);
430 oops_data_sz = oops_log_partition.
size -
sizeof(
u16);
437 big_oops_buf_sz = (oops_data_sz * 100) / 45;
442 if (!stream.workspace) {
443 pr_err(
"nvram: No memory for compression workspace; "
444 "skipping compression of %s partition data\n",
445 oops_log_partition.
name);
450 pr_err(
"No memory for uncompressed %s data; "
451 "skipping compression\n", oops_log_partition.
name);
452 stream.workspace =
NULL;
455 rc = kmsg_dump_register(&nvram_kmsg_dumper);
457 pr_err(
"nvram: kmsg_dump_register() failed; returned %d\n", rc);
460 kfree(stream.workspace);
464 static int __init pseries_nvram_init_log_partitions(
void)
468 rc = pseries_nvram_init_os_partition(&rtas_log_partition);
469 nvram_init_oops_partition(rc == 0);
477 const unsigned int *nbytes_p;
478 unsigned int proplen;
485 if (nbytes_p ==
NULL || proplen !=
sizeof(
unsigned int)) {
490 nvram_size = *nbytes_p;
497 ppc_md.nvram_read = pSeries_nvram_read;
498 ppc_md.nvram_write = pSeries_nvram_write;
499 ppc_md.nvram_size = pSeries_nvram_get_size;
512 static int clobbering_unread_rtas_event(
void)
514 return (oops_log_partition.
index == rtas_log_partition.
index
515 && last_unread_rtas_event
521 static int nvram_compress(
const void *
in,
void *
out,
size_t inlen,
533 stream.avail_in =
inlen;
535 stream.next_out =
out;
536 stream.avail_out =
outlen;
537 stream.total_out = 0;
547 if (stream.total_out >= stream.total_in)
550 ret = stream.total_out;
556 static int zip_oops(
size_t text_len)
558 int zipped_len = nvram_compress(big_oops_buf, oops_data, text_len,
560 if (zipped_len < 0) {
561 pr_err(
"nvram: compression failed; returned %d\n", zipped_len);
562 pr_err(
"nvram: logging uncompressed oops/panic report\n");
565 *oops_len = (
u16) zipped_len;
576 static void oops_to_nvram(
struct kmsg_dumper *dumper,
579 static unsigned int oops_count = 0;
580 static bool panicking =
false;
584 unsigned int err_type = ERR_TYPE_KERNEL_PANIC_GZ;
604 pr_err(
"%s: ignoring unrecognized KMSG_DUMP_* reason %d\n",
609 if (clobbering_unread_rtas_event())
616 kmsg_dump_get_buffer(dumper,
false,
617 big_oops_buf, big_oops_buf_sz, &text_len);
618 rc = zip_oops(text_len);
621 kmsg_dump_rewind(dumper);
622 kmsg_dump_get_buffer(dumper,
true,
623 oops_data, oops_data_sz, &text_len);
624 err_type = ERR_TYPE_KERNEL_PANIC;
625 *oops_len = (
u16) text_len;
629 (
int) (
sizeof(*oops_len) + *oops_len), err_type, ++oops_count);
631 spin_unlock_irqrestore(&lock, flags);