summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2010-09-10 11:57:36 -0700
committerEric W. Biederman <ebiederm@xmission.com>2010-09-10 21:38:41 -0700
commitd60bd565d6b9d4f63f6cc33d413681da81ef8e96 (patch)
tree10d91bfcf822a5593e21db7402e22e37d2b9593c
parent9847b493f2ee3020c38da496af90984fe25d5a39 (diff)
x86 crashdump: On x86_64 generate EM_X86_64 crashdump headers.
Paper bag time. I forgot to double check my changes worked on x86_64. So I wound up with x86_64 putting i386 crashdump headers on when it generated a crashdump header. Ouch! Fix it by using the new KEXEC_ARCH_NATIVE value so we can see what we are doing. Change the one remaining arch test of info->kexec_flags to look at elf_info.machine instead. memset elf_info to 0 to ensure all of the fields are initialized to something predictable. *Sigh* What a landmine getting the arch out of kexec_flags became. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r--kexec/arch/i386/crashdump-x86.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index 06e5ae9..9eb574f 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -628,10 +628,10 @@ static int get_crash_notes(int cpu, uint64_t *addr, uint64_t *len)
return get_crash_notes_per_cpu(cpu, addr, len);
}
-static enum coretype get_core_type(struct kexec_info *info,
+static enum coretype get_core_type(struct crash_elf_info *elf_info,
struct memory_range *range, int ranges)
{
- if ((info->kexec_flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_X86_64)
+ if ((elf_info->machine) == EM_X86_64)
return CORE_TYPE_ELF64;
else {
/* fall back to default */
@@ -690,19 +690,33 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
int nr_ranges, align = 1024, i;
struct memory_range *mem_range, *memmap_p;
struct crash_elf_info elf_info;
+ unsigned kexec_arch;
/* Constant parts of the elf_info */
+ memset(&elf_info, 0, sizeof(elf_info));
elf_info.data = ELFDATA2LSB;
elf_info.backup_src_start = BACKUP_SRC_START;
elf_info.backup_src_end = BACKUP_SRC_END;
+ /* Get the architecture of the running kernel */
+ kexec_arch = info->kexec_flags & KEXEC_ARCH_MASK;
+ if (kexec_arch == KEXEC_ARCH_DEFAULT)
+ kexec_arch = KEXEC_ARCH_NATIVE;
+
/* Get the elf architecture of the running kernel */
- if ((info->kexec_flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_X86_64) {
+ switch(kexec_arch) {
+ case KEXEC_ARCH_X86_64:
elf_info.machine = EM_X86_64;
- } else {
+ break;
+ case KEXEC_ARCH_386:
elf_info.machine = EM_386;
elf_info.lowmem_limit = X86_MAXMEM;
elf_info.get_note_info = get_crash_notes;
+ break;
+ default:
+ fprintf(stderr, "unsupported crashdump architecture: %04x\n",
+ kexec_arch);
+ return -1;
}
if (get_crash_memory_ranges(&mem_range, &nr_ranges,
@@ -716,7 +730,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
*/
if (arch_options.core_header_type == CORE_TYPE_UNDEF) {
arch_options.core_header_type =
- get_core_type(info, mem_range, nr_ranges);
+ get_core_type(&elf_info, mem_range, nr_ranges);
}
/* Get the elf class... */
elf_info.class = ELFCLASS32;