[PATCH] ARM: kdump: copy kernel relocation code at the kexec prepare stage

Russell King - ARM Linux linux at arm.linux.org.uk
Mon Sep 19 08:20:59 EDT 2011


On Thu, Sep 15, 2011 at 10:32:09PM -0700, Lei Wen wrote:
> diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
> index e59bbd4..f60fc90 100644
> --- a/arch/arm/kernel/machine_kexec.c
> +++ b/arch/arm/kernel/machine_kexec.c
> @@ -32,6 +32,21 @@ static atomic_t waiting_for_crash_ipi;
>  
>  int machine_kexec_prepare(struct kimage *image)
>  {
> +	unsigned long page_list;
> +	void *reboot_code_buffer;
> +	page_list = image->head & PAGE_MASK;
> +
> +	reboot_code_buffer = page_address(image->control_code_page);
> +
> +	/* Prepare parameters for reboot_code_buffer*/
> +	kexec_start_address = image->start;
> +	kexec_indirection_page = page_list;
> +	kexec_mach_type = machine_arch_type;
> +	kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
> +
> +	/* copy our kernel relocation code to the control code page */
> +	memcpy(reboot_code_buffer,
> +	       relocate_new_kernel, relocate_new_kernel_size);
>  	return 0;
>  }
>  
> @@ -82,29 +97,14 @@ void (*kexec_reinit)(void);
>  
>  void machine_kexec(struct kimage *image)
>  {
> -	unsigned long page_list;
>  	unsigned long reboot_code_buffer_phys;
>  	void *reboot_code_buffer;
>  
> -
> -	page_list = image->head & PAGE_MASK;
> -
>  	/* we need both effective and real address here */
>  	reboot_code_buffer_phys =
>  	    page_to_pfn(image->control_code_page) << PAGE_SHIFT;
>  	reboot_code_buffer = page_address(image->control_code_page);
>  
> -	/* Prepare parameters for reboot_code_buffer*/
> -	kexec_start_address = image->start;
> -	kexec_indirection_page = page_list;
> -	kexec_mach_type = machine_arch_type;
> -	kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
> -
> -	/* copy our kernel relocation code to the control code page */
> -	memcpy(reboot_code_buffer,
> -	       relocate_new_kernel, relocate_new_kernel_size);
> -
> -
>  	flush_icache_range((unsigned long) reboot_code_buffer,
>  			   (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);

You should keep this flush with the memcpy - the two are intimately
related - the flush is to ensure I/D cache coherency for the code
which was copied into the page.  Splitting them into two different
functions is asking for future bugs.



More information about the kexec mailing list