aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2017-07-19 18:09:58 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2017-07-20 06:37:42 -0400
commit0d70262a2d60886da6fe5b1fc8bbcd76cbbc306d (patch)
treea5ba2a9cc7793d3cc4f14338ea37611356712f38
parent67556d7a851c20116923c23f1d49ecdec954e3a0 (diff)
ARM: kexec: fix failure to boot crash kernel
When kexec was converted to DTB, the dtb address was passed between machine_kexec_prepare() and machine_kexec() using a static variable. This is bad news if you load a crash kernel followed by a normal kernel or vice versa - the last loaded kernel overwrites the dtb address. This can result in kexec failures, as (eg) we try to boot the crash kernel with the last loaded dtb. For example, with: the crash kernel fails to find the dtb. Avoid this by defining a kimage architecture structure, and store the address to be passed in r2 there, which will either be the ATAGs or the dtb blob. Fixes: 4cabd1d9625c ("ARM: 7539/1: kexec: scan for dtb magic in segments") Fixes: 42d720d1731a ("ARM: kexec: Make .text R/W in machine_kexec") Reported-by: Keerthy <j-keerthy@ti.com> Tested-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-rw-r--r--arch/arm/include/asm/kexec.h5
-rw-r--r--arch/arm/kernel/machine_kexec.c11
2 files changed, 11 insertions, 5 deletions
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index 1869af6bac5c..25021b798a1e 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -19,6 +19,11 @@
19 19
20#ifndef __ASSEMBLY__ 20#ifndef __ASSEMBLY__
21 21
22#define ARCH_HAS_KIMAGE_ARCH
23struct kimage_arch {
24 u32 kernel_r2;
25};
26
22/** 27/**
23 * crash_setup_regs() - save registers for the panic kernel 28 * crash_setup_regs() - save registers for the panic kernel
24 * @newregs: registers are saved here 29 * @newregs: registers are saved here
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 15495887ca14..fe1419eeb932 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -30,7 +30,6 @@ extern unsigned long kexec_boot_atags;
30 30
31static atomic_t waiting_for_crash_ipi; 31static atomic_t waiting_for_crash_ipi;
32 32
33static unsigned long dt_mem;
34/* 33/*
35 * Provide a dummy crash_notes definition while crash dump arrives to arm. 34 * Provide a dummy crash_notes definition while crash dump arrives to arm.
36 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. 35 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -42,6 +41,9 @@ int machine_kexec_prepare(struct kimage *image)
42 __be32 header; 41 __be32 header;
43 int i, err; 42 int i, err;
44 43
44 image->arch.kernel_r2 = image->start - KEXEC_ARM_ZIMAGE_OFFSET
45 + KEXEC_ARM_ATAGS_OFFSET;
46
45 /* 47 /*
46 * Validate that if the current HW supports SMP, then the SW supports 48 * Validate that if the current HW supports SMP, then the SW supports
47 * and implements CPU hotplug for the current HW. If not, we won't be 49 * and implements CPU hotplug for the current HW. If not, we won't be
@@ -66,8 +68,8 @@ int machine_kexec_prepare(struct kimage *image)
66 if (err) 68 if (err)
67 return err; 69 return err;
68 70
69 if (be32_to_cpu(header) == OF_DT_HEADER) 71 if (header == cpu_to_be32(OF_DT_HEADER))
70 dt_mem = current_segment->mem; 72 image->arch.kernel_r2 = current_segment->mem;
71 } 73 }
72 return 0; 74 return 0;
73} 75}
@@ -165,8 +167,7 @@ void machine_kexec(struct kimage *image)
165 kexec_start_address = image->start; 167 kexec_start_address = image->start;
166 kexec_indirection_page = page_list; 168 kexec_indirection_page = page_list;
167 kexec_mach_type = machine_arch_type; 169 kexec_mach_type = machine_arch_type;
168 kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET 170 kexec_boot_atags = image->arch.kernel_r2;
169 + KEXEC_ARM_ATAGS_OFFSET;
170 171
171 /* copy our kernel relocation code to the control code page */ 172 /* copy our kernel relocation code to the control code page */
172 reboot_entry = fncpy(reboot_code_buffer, 173 reboot_entry = fncpy(reboot_code_buffer,