Commit 9fa2984d authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt

powerpc/pseries: Fix endian issues in nvram code

The NVRAM code has a number of endian issues. I noticed a very
confused error log count:

RTAS: 100663330 -------- RTAS event begin --------

100663330 == 0x06000022. 0x6 LE error logs and 0x22 BE error logs.

The pstore code has similar issues - if we write an oops in one
endian and attempt to read it in another we get junk.

Make both of these formats big endian, and byteswap as required.
Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent ca5de4e6
...@@ -43,8 +43,8 @@ static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */ ...@@ -43,8 +43,8 @@ static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */
static DEFINE_SPINLOCK(nvram_lock); static DEFINE_SPINLOCK(nvram_lock);
struct err_log_info { struct err_log_info {
int error_type; __be32 error_type;
unsigned int seq_num; __be32 seq_num;
}; };
struct nvram_os_partition { struct nvram_os_partition {
...@@ -79,9 +79,9 @@ static const char *pseries_nvram_os_partitions[] = { ...@@ -79,9 +79,9 @@ static const char *pseries_nvram_os_partitions[] = {
}; };
struct oops_log_info { struct oops_log_info {
u16 version; __be16 version;
u16 report_length; __be16 report_length;
u64 timestamp; __be64 timestamp;
} __attribute__((packed)); } __attribute__((packed));
static void oops_to_nvram(struct kmsg_dumper *dumper, static void oops_to_nvram(struct kmsg_dumper *dumper,
...@@ -291,8 +291,8 @@ int nvram_write_os_partition(struct nvram_os_partition *part, char * buff, ...@@ -291,8 +291,8 @@ int nvram_write_os_partition(struct nvram_os_partition *part, char * buff,
length = part->size; length = part->size;
} }
info.error_type = err_type; info.error_type = cpu_to_be32(err_type);
info.seq_num = error_log_cnt; info.seq_num = cpu_to_be32(error_log_cnt);
tmp_index = part->index; tmp_index = part->index;
...@@ -364,8 +364,8 @@ int nvram_read_partition(struct nvram_os_partition *part, char *buff, ...@@ -364,8 +364,8 @@ int nvram_read_partition(struct nvram_os_partition *part, char *buff,
} }
if (part->os_partition) { if (part->os_partition) {
*error_log_cnt = info.seq_num; *error_log_cnt = be32_to_cpu(info.seq_num);
*err_type = info.error_type; *err_type = be32_to_cpu(info.error_type);
} }
return 0; return 0;
...@@ -529,9 +529,9 @@ static int zip_oops(size_t text_len) ...@@ -529,9 +529,9 @@ static int zip_oops(size_t text_len)
pr_err("nvram: logging uncompressed oops/panic report\n"); pr_err("nvram: logging uncompressed oops/panic report\n");
return -1; return -1;
} }
oops_hdr->version = OOPS_HDR_VERSION; oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
oops_hdr->report_length = (u16) zipped_len; oops_hdr->report_length = cpu_to_be16(zipped_len);
oops_hdr->timestamp = get_seconds(); oops_hdr->timestamp = cpu_to_be64(get_seconds());
return 0; return 0;
} }
...@@ -574,9 +574,9 @@ static int nvram_pstore_write(enum pstore_type_id type, ...@@ -574,9 +574,9 @@ static int nvram_pstore_write(enum pstore_type_id type,
clobbering_unread_rtas_event()) clobbering_unread_rtas_event())
return -1; return -1;
oops_hdr->version = OOPS_HDR_VERSION; oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
oops_hdr->report_length = (u16) size; oops_hdr->report_length = cpu_to_be16(size);
oops_hdr->timestamp = get_seconds(); oops_hdr->timestamp = cpu_to_be64(get_seconds());
if (compressed) if (compressed)
err_type = ERR_TYPE_KERNEL_PANIC_GZ; err_type = ERR_TYPE_KERNEL_PANIC_GZ;
...@@ -670,16 +670,16 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type, ...@@ -670,16 +670,16 @@ static ssize_t nvram_pstore_read(u64 *id, enum pstore_type_id *type,
size_t length, hdr_size; size_t length, hdr_size;
oops_hdr = (struct oops_log_info *)buff; oops_hdr = (struct oops_log_info *)buff;
if (oops_hdr->version < OOPS_HDR_VERSION) { if (be16_to_cpu(oops_hdr->version) < OOPS_HDR_VERSION) {
/* Old format oops header had 2-byte record size */ /* Old format oops header had 2-byte record size */
hdr_size = sizeof(u16); hdr_size = sizeof(u16);
length = oops_hdr->version; length = be16_to_cpu(oops_hdr->version);
time->tv_sec = 0; time->tv_sec = 0;
time->tv_nsec = 0; time->tv_nsec = 0;
} else { } else {
hdr_size = sizeof(*oops_hdr); hdr_size = sizeof(*oops_hdr);
length = oops_hdr->report_length; length = be16_to_cpu(oops_hdr->report_length);
time->tv_sec = oops_hdr->timestamp; time->tv_sec = be64_to_cpu(oops_hdr->timestamp);
time->tv_nsec = 0; time->tv_nsec = 0;
} }
*buf = kmalloc(length, GFP_KERNEL); *buf = kmalloc(length, GFP_KERNEL);
...@@ -889,13 +889,13 @@ static void oops_to_nvram(struct kmsg_dumper *dumper, ...@@ -889,13 +889,13 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
kmsg_dump_get_buffer(dumper, false, kmsg_dump_get_buffer(dumper, false,
oops_data, oops_data_sz, &text_len); oops_data, oops_data_sz, &text_len);
err_type = ERR_TYPE_KERNEL_PANIC; err_type = ERR_TYPE_KERNEL_PANIC;
oops_hdr->version = OOPS_HDR_VERSION; oops_hdr->version = cpu_to_be16(OOPS_HDR_VERSION);
oops_hdr->report_length = (u16) text_len; oops_hdr->report_length = cpu_to_be16(text_len);
oops_hdr->timestamp = get_seconds(); oops_hdr->timestamp = cpu_to_be64(get_seconds());
} }
(void) nvram_write_os_partition(&oops_log_partition, oops_buf, (void) nvram_write_os_partition(&oops_log_partition, oops_buf,
(int) (sizeof(*oops_hdr) + oops_hdr->report_length), err_type, (int) (sizeof(*oops_hdr) + text_len), err_type,
++oops_count); ++oops_count);
spin_unlock_irqrestore(&lock, flags); spin_unlock_irqrestore(&lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment