aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHari Bathini <hbathini@linux.vnet.ibm.com>2014-10-01 03:02:30 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2014-10-30 01:52:46 -0400
commit408cddd96e3b155337f9e3aba2198e92e94c6068 (patch)
tree6000ae44112cace02d07c253a6b867aaea7b038b
parent94966b712c6875939fcdd83cb2707a797e131a43 (diff)
powerpc/fadump: Fix endianess issues in firmware assisted dump handling
Firmware-assisted dump (fadump) kernel code is not endian safe. The below patch fixes this issue. Tested this patch with upstream kernel. Below output shows crash tool successfully opening LE fadump vmcore. # crash vmlinux vmcore GNU gdb (GDB) 7.6 This GDB was configured as "powerpc64le-unknown-linux-gnu"... KERNEL: vmlinux DUMPFILE: vmcore CPUS: 16 DATE: Wed Dec 31 19:00:00 1969 UPTIME: 00:03:28 LOAD AVERAGE: 0.46, 0.86, 0.41 TASKS: 268 NODENAME: linux-dhr2 RELEASE: 3.17.0-rc5-7-default VERSION: #6 SMP Tue Sep 30 01:06:34 EDT 2014 MACHINE: ppc64le (4116 Mhz) MEMORY: 40 GB PANIC: "Oops: Kernel access of bad area, sig: 11 [#1]" (check log for details) PID: 6223 COMMAND: "bash" TASK: c0000009661b2500 [THREAD_INFO: c000000967ac0000] CPU: 2 STATE: TASK_RUNNING (PANIC) Signed-off-by: Hari Bathini <hbathini@linux.vnet.ibm.com> [mpe: Make the comment in pSeries_lpar_hptab_clear() clearer] Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r--arch/powerpc/include/asm/fadump.h52
-rw-r--r--arch/powerpc/kernel/fadump.c114
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c14
3 files changed, 95 insertions, 85 deletions
diff --git a/arch/powerpc/include/asm/fadump.h b/arch/powerpc/include/asm/fadump.h
index a6774560afe3..493e72f64b35 100644
--- a/arch/powerpc/include/asm/fadump.h
+++ b/arch/powerpc/include/asm/fadump.h
@@ -70,39 +70,39 @@
70#define CPU_UNKNOWN (~((u32)0)) 70#define CPU_UNKNOWN (~((u32)0))
71 71
72/* Utility macros */ 72/* Utility macros */
73#define SKIP_TO_NEXT_CPU(reg_entry) \ 73#define SKIP_TO_NEXT_CPU(reg_entry) \
74({ \ 74({ \
75 while (reg_entry->reg_id != REG_ID("CPUEND")) \ 75 while (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUEND")) \
76 reg_entry++; \ 76 reg_entry++; \
77 reg_entry++; \ 77 reg_entry++; \
78}) 78})
79 79
80/* Kernel Dump section info */ 80/* Kernel Dump section info */
81struct fadump_section { 81struct fadump_section {
82 u32 request_flag; 82 __be32 request_flag;
83 u16 source_data_type; 83 __be16 source_data_type;
84 u16 error_flags; 84 __be16 error_flags;
85 u64 source_address; 85 __be64 source_address;
86 u64 source_len; 86 __be64 source_len;
87 u64 bytes_dumped; 87 __be64 bytes_dumped;
88 u64 destination_address; 88 __be64 destination_address;
89}; 89};
90 90
91/* ibm,configure-kernel-dump header. */ 91/* ibm,configure-kernel-dump header. */
92struct fadump_section_header { 92struct fadump_section_header {
93 u32 dump_format_version; 93 __be32 dump_format_version;
94 u16 dump_num_sections; 94 __be16 dump_num_sections;
95 u16 dump_status_flag; 95 __be16 dump_status_flag;
96 u32 offset_first_dump_section; 96 __be32 offset_first_dump_section;
97 97
98 /* Fields for disk dump option. */ 98 /* Fields for disk dump option. */
99 u32 dd_block_size; 99 __be32 dd_block_size;
100 u64 dd_block_offset; 100 __be64 dd_block_offset;
101 u64 dd_num_blocks; 101 __be64 dd_num_blocks;
102 u32 dd_offset_disk_path; 102 __be32 dd_offset_disk_path;
103 103
104 /* Maximum time allowed to prevent an automatic dump-reboot. */ 104 /* Maximum time allowed to prevent an automatic dump-reboot. */
105 u32 max_time_auto; 105 __be32 max_time_auto;
106}; 106};
107 107
108/* 108/*
@@ -174,15 +174,15 @@ static inline u64 str_to_u64(const char *str)
174 174
175/* Register save area header. */ 175/* Register save area header. */
176struct fadump_reg_save_area_header { 176struct fadump_reg_save_area_header {
177 u64 magic_number; 177 __be64 magic_number;
178 u32 version; 178 __be32 version;
179 u32 num_cpu_offset; 179 __be32 num_cpu_offset;
180}; 180};
181 181
182/* Register entry. */ 182/* Register entry. */
183struct fadump_reg_entry { 183struct fadump_reg_entry {
184 u64 reg_id; 184 __be64 reg_id;
185 u64 reg_value; 185 __be64 reg_value;
186}; 186};
187 187
188/* fadump crash info structure */ 188/* fadump crash info structure */
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 742694c1d852..26d091a1a54c 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -58,7 +58,7 @@ int __init early_init_dt_scan_fw_dump(unsigned long node,
58 const __be32 *sections; 58 const __be32 *sections;
59 int i, num_sections; 59 int i, num_sections;
60 int size; 60 int size;
61 const int *token; 61 const __be32 *token;
62 62
63 if (depth != 1 || strcmp(uname, "rtas") != 0) 63 if (depth != 1 || strcmp(uname, "rtas") != 0)
64 return 0; 64 return 0;
@@ -72,7 +72,7 @@ int __init early_init_dt_scan_fw_dump(unsigned long node,
72 return 1; 72 return 1;
73 73
74 fw_dump.fadump_supported = 1; 74 fw_dump.fadump_supported = 1;
75 fw_dump.ibm_configure_kernel_dump = *token; 75 fw_dump.ibm_configure_kernel_dump = be32_to_cpu(*token);
76 76
77 /* 77 /*
78 * The 'ibm,kernel-dump' rtas node is present only if there is 78 * The 'ibm,kernel-dump' rtas node is present only if there is
@@ -147,11 +147,11 @@ static unsigned long init_fadump_mem_struct(struct fadump_mem_struct *fdm,
147 memset(fdm, 0, sizeof(struct fadump_mem_struct)); 147 memset(fdm, 0, sizeof(struct fadump_mem_struct));
148 addr = addr & PAGE_MASK; 148 addr = addr & PAGE_MASK;
149 149
150 fdm->header.dump_format_version = 0x00000001; 150 fdm->header.dump_format_version = cpu_to_be32(0x00000001);
151 fdm->header.dump_num_sections = 3; 151 fdm->header.dump_num_sections = cpu_to_be16(3);
152 fdm->header.dump_status_flag = 0; 152 fdm->header.dump_status_flag = 0;
153 fdm->header.offset_first_dump_section = 153 fdm->header.offset_first_dump_section =
154 (u32)offsetof(struct fadump_mem_struct, cpu_state_data); 154 cpu_to_be32((u32)offsetof(struct fadump_mem_struct, cpu_state_data));
155 155
156 /* 156 /*
157 * Fields for disk dump option. 157 * Fields for disk dump option.
@@ -167,27 +167,27 @@ static unsigned long init_fadump_mem_struct(struct fadump_mem_struct *fdm,
167 167
168 /* Kernel dump sections */ 168 /* Kernel dump sections */
169 /* cpu state data section. */ 169 /* cpu state data section. */
170 fdm->cpu_state_data.request_flag = FADUMP_REQUEST_FLAG; 170 fdm->cpu_state_data.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
171 fdm->cpu_state_data.source_data_type = FADUMP_CPU_STATE_DATA; 171 fdm->cpu_state_data.source_data_type = cpu_to_be16(FADUMP_CPU_STATE_DATA);
172 fdm->cpu_state_data.source_address = 0; 172 fdm->cpu_state_data.source_address = 0;
173 fdm->cpu_state_data.source_len = fw_dump.cpu_state_data_size; 173 fdm->cpu_state_data.source_len = cpu_to_be64(fw_dump.cpu_state_data_size);
174 fdm->cpu_state_data.destination_address = addr; 174 fdm->cpu_state_data.destination_address = cpu_to_be64(addr);
175 addr += fw_dump.cpu_state_data_size; 175 addr += fw_dump.cpu_state_data_size;
176 176
177 /* hpte region section */ 177 /* hpte region section */
178 fdm->hpte_region.request_flag = FADUMP_REQUEST_FLAG; 178 fdm->hpte_region.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
179 fdm->hpte_region.source_data_type = FADUMP_HPTE_REGION; 179 fdm->hpte_region.source_data_type = cpu_to_be16(FADUMP_HPTE_REGION);
180 fdm->hpte_region.source_address = 0; 180 fdm->hpte_region.source_address = 0;
181 fdm->hpte_region.source_len = fw_dump.hpte_region_size; 181 fdm->hpte_region.source_len = cpu_to_be64(fw_dump.hpte_region_size);
182 fdm->hpte_region.destination_address = addr; 182 fdm->hpte_region.destination_address = cpu_to_be64(addr);
183 addr += fw_dump.hpte_region_size; 183 addr += fw_dump.hpte_region_size;
184 184
185 /* RMA region section */ 185 /* RMA region section */
186 fdm->rmr_region.request_flag = FADUMP_REQUEST_FLAG; 186 fdm->rmr_region.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
187 fdm->rmr_region.source_data_type = FADUMP_REAL_MODE_REGION; 187 fdm->rmr_region.source_data_type = cpu_to_be16(FADUMP_REAL_MODE_REGION);
188 fdm->rmr_region.source_address = RMA_START; 188 fdm->rmr_region.source_address = cpu_to_be64(RMA_START);
189 fdm->rmr_region.source_len = fw_dump.boot_memory_size; 189 fdm->rmr_region.source_len = cpu_to_be64(fw_dump.boot_memory_size);
190 fdm->rmr_region.destination_address = addr; 190 fdm->rmr_region.destination_address = cpu_to_be64(addr);
191 addr += fw_dump.boot_memory_size; 191 addr += fw_dump.boot_memory_size;
192 192
193 return addr; 193 return addr;
@@ -272,7 +272,7 @@ int __init fadump_reserve_mem(void)
272 * first kernel. 272 * first kernel.
273 */ 273 */
274 if (fdm_active) 274 if (fdm_active)
275 fw_dump.boot_memory_size = fdm_active->rmr_region.source_len; 275 fw_dump.boot_memory_size = be64_to_cpu(fdm_active->rmr_region.source_len);
276 else 276 else
277 fw_dump.boot_memory_size = fadump_calculate_reserve_size(); 277 fw_dump.boot_memory_size = fadump_calculate_reserve_size();
278 278
@@ -314,8 +314,8 @@ int __init fadump_reserve_mem(void)
314 (unsigned long)(base >> 20)); 314 (unsigned long)(base >> 20));
315 315
316 fw_dump.fadumphdr_addr = 316 fw_dump.fadumphdr_addr =
317 fdm_active->rmr_region.destination_address + 317 be64_to_cpu(fdm_active->rmr_region.destination_address) +
318 fdm_active->rmr_region.source_len; 318 be64_to_cpu(fdm_active->rmr_region.source_len);
319 pr_debug("fadumphdr_addr = %p\n", 319 pr_debug("fadumphdr_addr = %p\n",
320 (void *) fw_dump.fadumphdr_addr); 320 (void *) fw_dump.fadumphdr_addr);
321 } else { 321 } else {
@@ -472,9 +472,9 @@ fadump_read_registers(struct fadump_reg_entry *reg_entry, struct pt_regs *regs)
472{ 472{
473 memset(regs, 0, sizeof(struct pt_regs)); 473 memset(regs, 0, sizeof(struct pt_regs));
474 474
475 while (reg_entry->reg_id != REG_ID("CPUEND")) { 475 while (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUEND")) {
476 fadump_set_regval(regs, reg_entry->reg_id, 476 fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
477 reg_entry->reg_value); 477 be64_to_cpu(reg_entry->reg_value));
478 reg_entry++; 478 reg_entry++;
479 } 479 }
480 reg_entry++; 480 reg_entry++;
@@ -603,20 +603,20 @@ static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm)
603 if (!fdm->cpu_state_data.bytes_dumped) 603 if (!fdm->cpu_state_data.bytes_dumped)
604 return -EINVAL; 604 return -EINVAL;
605 605
606 addr = fdm->cpu_state_data.destination_address; 606 addr = be64_to_cpu(fdm->cpu_state_data.destination_address);
607 vaddr = __va(addr); 607 vaddr = __va(addr);
608 608
609 reg_header = vaddr; 609 reg_header = vaddr;
610 if (reg_header->magic_number != REGSAVE_AREA_MAGIC) { 610 if (be64_to_cpu(reg_header->magic_number) != REGSAVE_AREA_MAGIC) {
611 printk(KERN_ERR "Unable to read register save area.\n"); 611 printk(KERN_ERR "Unable to read register save area.\n");
612 return -ENOENT; 612 return -ENOENT;
613 } 613 }
614 pr_debug("--------CPU State Data------------\n"); 614 pr_debug("--------CPU State Data------------\n");
615 pr_debug("Magic Number: %llx\n", reg_header->magic_number); 615 pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
616 pr_debug("NumCpuOffset: %x\n", reg_header->num_cpu_offset); 616 pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
617 617
618 vaddr += reg_header->num_cpu_offset; 618 vaddr += be32_to_cpu(reg_header->num_cpu_offset);
619 num_cpus = *((u32 *)(vaddr)); 619 num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
620 pr_debug("NumCpus : %u\n", num_cpus); 620 pr_debug("NumCpus : %u\n", num_cpus);
621 vaddr += sizeof(u32); 621 vaddr += sizeof(u32);
622 reg_entry = (struct fadump_reg_entry *)vaddr; 622 reg_entry = (struct fadump_reg_entry *)vaddr;
@@ -639,13 +639,13 @@ static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm)
639 fdh = __va(fw_dump.fadumphdr_addr); 639 fdh = __va(fw_dump.fadumphdr_addr);
640 640
641 for (i = 0; i < num_cpus; i++) { 641 for (i = 0; i < num_cpus; i++) {
642 if (reg_entry->reg_id != REG_ID("CPUSTRT")) { 642 if (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUSTRT")) {
643 printk(KERN_ERR "Unable to read CPU state data\n"); 643 printk(KERN_ERR "Unable to read CPU state data\n");
644 rc = -ENOENT; 644 rc = -ENOENT;
645 goto error_out; 645 goto error_out;
646 } 646 }
647 /* Lower 4 bytes of reg_value contains logical cpu id */ 647 /* Lower 4 bytes of reg_value contains logical cpu id */
648 cpu = reg_entry->reg_value & FADUMP_CPU_ID_MASK; 648 cpu = be64_to_cpu(reg_entry->reg_value) & FADUMP_CPU_ID_MASK;
649 if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) { 649 if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) {
650 SKIP_TO_NEXT_CPU(reg_entry); 650 SKIP_TO_NEXT_CPU(reg_entry);
651 continue; 651 continue;
@@ -692,7 +692,7 @@ static int __init process_fadump(const struct fadump_mem_struct *fdm_active)
692 return -EINVAL; 692 return -EINVAL;
693 693
694 /* Check if the dump data is valid. */ 694 /* Check if the dump data is valid. */
695 if ((fdm_active->header.dump_status_flag == FADUMP_ERROR_FLAG) || 695 if ((be16_to_cpu(fdm_active->header.dump_status_flag) == FADUMP_ERROR_FLAG) ||
696 (fdm_active->cpu_state_data.error_flags != 0) || 696 (fdm_active->cpu_state_data.error_flags != 0) ||
697 (fdm_active->rmr_region.error_flags != 0)) { 697 (fdm_active->rmr_region.error_flags != 0)) {
698 printk(KERN_ERR "Dump taken by platform is not valid\n"); 698 printk(KERN_ERR "Dump taken by platform is not valid\n");
@@ -828,7 +828,7 @@ static void fadump_setup_crash_memory_ranges(void)
828static inline unsigned long fadump_relocate(unsigned long paddr) 828static inline unsigned long fadump_relocate(unsigned long paddr)
829{ 829{
830 if (paddr > RMA_START && paddr < fw_dump.boot_memory_size) 830 if (paddr > RMA_START && paddr < fw_dump.boot_memory_size)
831 return fdm.rmr_region.destination_address + paddr; 831 return be64_to_cpu(fdm.rmr_region.destination_address) + paddr;
832 else 832 else
833 return paddr; 833 return paddr;
834} 834}
@@ -902,7 +902,7 @@ static int fadump_create_elfcore_headers(char *bufp)
902 * to the specified destination_address. Hence set 902 * to the specified destination_address. Hence set
903 * the correct offset. 903 * the correct offset.
904 */ 904 */
905 phdr->p_offset = fdm.rmr_region.destination_address; 905 phdr->p_offset = be64_to_cpu(fdm.rmr_region.destination_address);
906 } 906 }
907 907
908 phdr->p_paddr = mbase; 908 phdr->p_paddr = mbase;
@@ -951,7 +951,7 @@ static void register_fadump(void)
951 951
952 fadump_setup_crash_memory_ranges(); 952 fadump_setup_crash_memory_ranges();
953 953
954 addr = fdm.rmr_region.destination_address + fdm.rmr_region.source_len; 954 addr = be64_to_cpu(fdm.rmr_region.destination_address) + be64_to_cpu(fdm.rmr_region.source_len);
955 /* Initialize fadump crash info header. */ 955 /* Initialize fadump crash info header. */
956 addr = init_fadump_header(addr); 956 addr = init_fadump_header(addr);
957 vaddr = __va(addr); 957 vaddr = __va(addr);
@@ -1023,7 +1023,7 @@ void fadump_cleanup(void)
1023 /* Invalidate the registration only if dump is active. */ 1023 /* Invalidate the registration only if dump is active. */
1024 if (fw_dump.dump_active) { 1024 if (fw_dump.dump_active) {
1025 init_fadump_mem_struct(&fdm, 1025 init_fadump_mem_struct(&fdm,
1026 fdm_active->cpu_state_data.destination_address); 1026 be64_to_cpu(fdm_active->cpu_state_data.destination_address));
1027 fadump_invalidate_dump(&fdm); 1027 fadump_invalidate_dump(&fdm);
1028 } 1028 }
1029} 1029}
@@ -1063,7 +1063,7 @@ static void fadump_invalidate_release_mem(void)
1063 return; 1063 return;
1064 } 1064 }
1065 1065
1066 destination_address = fdm_active->cpu_state_data.destination_address; 1066 destination_address = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
1067 fadump_cleanup(); 1067 fadump_cleanup();
1068 mutex_unlock(&fadump_mutex); 1068 mutex_unlock(&fadump_mutex);
1069 1069
@@ -1183,31 +1183,31 @@ static int fadump_region_show(struct seq_file *m, void *private)
1183 seq_printf(m, 1183 seq_printf(m,
1184 "CPU : [%#016llx-%#016llx] %#llx bytes, " 1184 "CPU : [%#016llx-%#016llx] %#llx bytes, "
1185 "Dumped: %#llx\n", 1185 "Dumped: %#llx\n",
1186 fdm_ptr->cpu_state_data.destination_address, 1186 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address),
1187 fdm_ptr->cpu_state_data.destination_address + 1187 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) +
1188 fdm_ptr->cpu_state_data.source_len - 1, 1188 be64_to_cpu(fdm_ptr->cpu_state_data.source_len) - 1,
1189 fdm_ptr->cpu_state_data.source_len, 1189 be64_to_cpu(fdm_ptr->cpu_state_data.source_len),
1190 fdm_ptr->cpu_state_data.bytes_dumped); 1190 be64_to_cpu(fdm_ptr->cpu_state_data.bytes_dumped));
1191 seq_printf(m, 1191 seq_printf(m,
1192 "HPTE: [%#016llx-%#016llx] %#llx bytes, " 1192 "HPTE: [%#016llx-%#016llx] %#llx bytes, "
1193 "Dumped: %#llx\n", 1193 "Dumped: %#llx\n",
1194 fdm_ptr->hpte_region.destination_address, 1194 be64_to_cpu(fdm_ptr->hpte_region.destination_address),
1195 fdm_ptr->hpte_region.destination_address + 1195 be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
1196 fdm_ptr->hpte_region.source_len - 1, 1196 be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
1197 fdm_ptr->hpte_region.source_len, 1197 be64_to_cpu(fdm_ptr->hpte_region.source_len),
1198 fdm_ptr->hpte_region.bytes_dumped); 1198 be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
1199 seq_printf(m, 1199 seq_printf(m,
1200 "DUMP: [%#016llx-%#016llx] %#llx bytes, " 1200 "DUMP: [%#016llx-%#016llx] %#llx bytes, "
1201 "Dumped: %#llx\n", 1201 "Dumped: %#llx\n",
1202 fdm_ptr->rmr_region.destination_address, 1202 be64_to_cpu(fdm_ptr->rmr_region.destination_address),
1203 fdm_ptr->rmr_region.destination_address + 1203 be64_to_cpu(fdm_ptr->rmr_region.destination_address) +
1204 fdm_ptr->rmr_region.source_len - 1, 1204 be64_to_cpu(fdm_ptr->rmr_region.source_len) - 1,
1205 fdm_ptr->rmr_region.source_len, 1205 be64_to_cpu(fdm_ptr->rmr_region.source_len),
1206 fdm_ptr->rmr_region.bytes_dumped); 1206 be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
1207 1207
1208 if (!fdm_active || 1208 if (!fdm_active ||
1209 (fw_dump.reserve_dump_area_start == 1209 (fw_dump.reserve_dump_area_start ==
1210 fdm_ptr->cpu_state_data.destination_address)) 1210 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address)))
1211 goto out; 1211 goto out;
1212 1212
1213 /* Dump is active. Show reserved memory region. */ 1213 /* Dump is active. Show reserved memory region. */
@@ -1215,10 +1215,10 @@ static int fadump_region_show(struct seq_file *m, void *private)
1215 " : [%#016llx-%#016llx] %#llx bytes, " 1215 " : [%#016llx-%#016llx] %#llx bytes, "
1216 "Dumped: %#llx\n", 1216 "Dumped: %#llx\n",
1217 (unsigned long long)fw_dump.reserve_dump_area_start, 1217 (unsigned long long)fw_dump.reserve_dump_area_start,
1218 fdm_ptr->cpu_state_data.destination_address - 1, 1218 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) - 1,
1219 fdm_ptr->cpu_state_data.destination_address - 1219 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
1220 fw_dump.reserve_dump_area_start, 1220 fw_dump.reserve_dump_area_start,
1221 fdm_ptr->cpu_state_data.destination_address - 1221 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
1222 fw_dump.reserve_dump_area_start); 1222 fw_dump.reserve_dump_area_start);
1223out: 1223out:
1224 if (fdm_active) 1224 if (fdm_active)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 8c509d5397c6..f6880d2a40fb 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -43,6 +43,7 @@
43#include <asm/trace.h> 43#include <asm/trace.h>
44#include <asm/firmware.h> 44#include <asm/firmware.h>
45#include <asm/plpar_wrappers.h> 45#include <asm/plpar_wrappers.h>
46#include <asm/fadump.h>
46 47
47#include "pseries.h" 48#include "pseries.h"
48 49
@@ -247,8 +248,17 @@ static void pSeries_lpar_hptab_clear(void)
247 } 248 }
248 249
249#ifdef __LITTLE_ENDIAN__ 250#ifdef __LITTLE_ENDIAN__
250 /* Reset exceptions to big endian */ 251 /*
251 if (firmware_has_feature(FW_FEATURE_SET_MODE)) { 252 * Reset exceptions to big endian.
253 *
254 * FIXME this is a hack for kexec, we need to reset the exception
255 * endian before starting the new kernel and this is a convenient place
256 * to do it.
257 *
258 * This is also called on boot when a fadump happens. In that case we
259 * must not change the exception endian mode.
260 */
261 if (firmware_has_feature(FW_FEATURE_SET_MODE) && !is_fadump_active()) {
252 long rc; 262 long rc;
253 263
254 rc = pseries_big_endian_exceptions(); 264 rc = pseries_big_endian_exceptions();