[PATCH 2/2] ARM: kexec: fix failure to boot crash kernel
Keerthy
j-keerthy at ti.com
Thu Jul 20 03:32:54 PDT 2017
On Thursday 20 July 2017 01:40 PM, Russell King wrote:
> 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.
>
> Avoid this by defining a kimage architecture structure, and store
> the address of to be passed in r2 to the new there, which will
Some word missing between 'new' and 'there'?
> either be the ATAGs or the dtb blob.
Tested loading crash kernel on DRA7-EVM
Now works with the sequence:
kexec -d -p
kexec -l
echo c > /proc/sysrq-trigger
Without this patch as soon as we do kexec -l the crash kernel booting
would fail without finding dtb.
Tested-by: Keerthy <j-keerthy at ti.com>
>
> Reported-by: Keerthy <j-keerthy at ti.com>
> Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
> ---
> arch/arm/include/asm/kexec.h | 5 +++++
> arch/arm/kernel/machine_kexec.c | 11 ++++++-----
> 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 @@
>
> #ifndef __ASSEMBLY__
>
> +#define ARCH_HAS_KIMAGE_ARCH
> +struct kimage_arch {
> + u32 kernel_r2;
> +};
> +
> /**
> * crash_setup_regs() - save registers for the panic kernel
> * @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;
>
> static atomic_t waiting_for_crash_ipi;
>
> -static unsigned long dt_mem;
> /*
> * Provide a dummy crash_notes definition while crash dump arrives to arm.
> * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
> @@ -42,6 +41,9 @@ int machine_kexec_prepare(struct kimage *image)
> __be32 header;
> int i, err;
>
> + image->arch.kernel_r2 = image->start - KEXEC_ARM_ZIMAGE_OFFSET
> + + KEXEC_ARM_ATAGS_OFFSET;
> +
> /*
> * Validate that if the current HW supports SMP, then the SW supports
> * 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)
> if (err)
> return err;
>
> - if (be32_to_cpu(header) == OF_DT_HEADER)
> - dt_mem = current_segment->mem;
> + if (header == cpu_to_be32(OF_DT_HEADER))
> + image->arch.kernel_r2 = current_segment->mem;
> }
> return 0;
> }
> @@ -165,8 +167,7 @@ void machine_kexec(struct kimage *image)
> kexec_start_address = image->start;
> kexec_indirection_page = page_list;
> kexec_mach_type = machine_arch_type;
> - kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET
> - + KEXEC_ARM_ATAGS_OFFSET;
> + kexec_boot_atags = image->arch.kernel_r2;
>
> /* copy our kernel relocation code to the control code page */
> reboot_entry = fncpy(reboot_code_buffer,
>
More information about the linux-arm-kernel
mailing list