fadump: fix endianess issues in firmware assisted dump handling
PATCH v2 1/1 fadump: fix endianess issues in firmware assisted dump handling
Firmware-assisted dump (fadump) kernel code is not LE compliant. The below patch tries to fix this issue. Tested this patch with upstream kernel. Did some sanity testing for the LE fadump vmcore generated. Below output shows crash tool successfully opening LE fadump vmcore.
# crash vmlinux vmcore
crash 7.0.5 Copyright (C) 2002-2014 Red Hat, Inc. Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation Copyright (C) 1999-2006 Hewlett-Packard Co Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited Copyright (C) 2006, 2007 VA Linux Systems Japan K.K. Copyright (C) 2005, 2011 NEC Corporation Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc. Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. This program is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Enter "help copying" to see the conditions. This program has absolutely no warranty. Enter "help warranty" for details. crash: vmlinux: no .gnu_debuglink section GNU gdb (GDB) 7.6 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. 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) crash>
Changes in v2:
1. Addressed casting related warnings.
2. Elaborated on why exceptions should not be changed to big endian during fadump boot.
Signed-off-by Hari Bathini <[email protected]>
--- arch/powerpc/include/asm/fadump.h | 52 ++++++++------- arch/powerpc/kernel/fadump.c | 114 +++++++++++++++++---------------- arch/powerpc/platforms/pseries/lpar.c | 15 ++++ 3 files changed, 96 insertions(+), 85 deletions(-)
arch/powerpc/include/asm/fadump.h +26 -26
@@ -70,39 +70,39 @@#define CPU_UNKNOWN (~((u32)0))/* Utility macros */ -#define SKIP_TO_NEXT_CPU (reg_entry) \ -({ \ - while (reg_entry->reg_id != REG_ID("CPUEND")) \ - reg_entry++; \ - reg_entry++; \ +#define SKIP_TO_NEXT_CPU (reg_entry) \ +({ \ + while (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUEND")) \ + reg_entry++; \ + reg_entry++; \ })/* Kernel Dump section info */ struct fadump_section { -u32 request_flag; -u16 source_data_type; -u16 error_flags; -u64 source_address; -u64 source_len; -u64 bytes_dumped; -u64 destination_address; +__be32 request_flag; +__be16 source_data_type; +__be16 error_flags; +__be64 source_address; +__be64 source_len; +__be64 bytes_dumped; +__be64 destination_address; };/* ibm,configure-kernel-dump header. */ struct fadump_section_header { -u32 dump_format_version; -u16 dump_num_sections; -u16 dump_status_flag; -u32 offset_first_dump_section; +__be32 dump_format_version; +__be16 dump_num_sections; +__be16 dump_status_flag; +__be32 offset_first_dump_section;/* Fields for disk dump option. */ -u32 dd_block_size; -u64 dd_block_offset; -u64 dd_num_blocks; -u32 dd_offset_disk_path; +__be32 dd_block_size; +__be64 dd_block_offset; +__be64 dd_num_blocks; +__be32 dd_offset_disk_path;/* Maximum time allowed to prevent an automatic dump-reboot. */ -u32 max_time_auto; +__be32 max_time_auto; };/*
@@ -174,15 +174,15 @@ static inline u64 str_to_u64(const char *str)/* Register save area header. */ struct fadump_reg_save_area_header { -u64 magic_number; -u32 version; -u32 num_cpu_offset; +__be64 magic_number; +__be32 version; +__be32 num_cpu_offset; };/* Register entry. */ struct fadump_reg_entry { -u64 reg_id; -u64 reg_value; +__be64 reg_id; +__be64 reg_value; };/* fadump crash info structure */
arch/powerpc/kernel/fadump.c +57 -57
249 lines not on this page · raw message
arch/powerpc/platforms/pseries/lpar.c +13 -2
@@ -43,6 +43,7 @@#include <asm/trace.h> #include <asm/firmware.h> #include <asm/plpar_wrappers.h> +#include <asm/fadump.h> #include "pseries.h"
@@ -249,8 +250,18 @@ static void pSeries_lpar_hptab_clear(void) }#ifdef __LITTLE_ENDIAN__ -/* Reset exceptions to big endian */ -if (firmware_has_feature (FW_FEATURE_SET_MODE )) { +/* +* Reset exceptions to big endian +* In fadump case, after system crash phyp preserves the memory contents +* and hashtable. Hence in the second kernel it is necessary to clear +* the hastable during htab_initialize() to remove old mappings. +* When we do that in second kernel we already booted in LE mode +* and ready to take up exception in LE mode. If we enable big endian +* exception in fadump case we see system crash because it tries to run +* LE interrupt code in BE mode. Hence if we are coming here as part of +* fadump crash we must not enable big endian exception. +*/ +if (firmware_has_feature (FW_FEATURE_SET_MODE ) && !is_fadump_active ()) {long rc; rc =pseries_big_endian_exceptions ();