[PATCH] kexec jump support for x86_64

Simon Horman horms at verge.net.au
Tue Dec 8 22:52:07 EST 2009


On Wed, Dec 09, 2009 at 09:45:42AM +0800, Huang Ying wrote:
> x86_64 specific support, including crash memory range and purgatory setup.
> Corresponding kernel support has been merged already.

Hi Huang,

Could you please include a description of what jump support is
in the changelog?

> 
> Signed-off-by: Huang Ying <ying.huang at intel.com>
> 
> ---
>  kexec/arch/x86_64/crashdump-x86_64.c     |   48 ++++++++++++++++++++++---------
>  purgatory/arch/x86_64/purgatory-x86_64.c |   11 ++++++-
>  purgatory/arch/x86_64/setup-x86_64.S     |    3 +
>  3 files changed, 48 insertions(+), 14 deletions(-)
> 
> --- a/kexec/arch/x86_64/crashdump-x86_64.c
> +++ b/kexec/arch/x86_64/crashdump-x86_64.c
> @@ -161,7 +161,8 @@ static struct memory_range crash_reserve
>   * to look into down the line. May be something like /proc/kernelmem or may
>   * be zone data structures exported from kernel.
>   */
> -static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
> +static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
> +				   int kexec_flags)
>  {
>  	const char *iomem= proc_iomem();
>  	int memory_ranges = 0, gart = 0;
> @@ -179,10 +180,12 @@ static int get_crash_memory_ranges(struc
>  
>  	/* First entry is for first 640K region. Different bios report first
>  	 * 640K in different manner hence hardcoding it */
> -	crash_memory_range[0].start = 0x00000000;
> -	crash_memory_range[0].end = 0x0009ffff;
> -	crash_memory_range[0].type = RANGE_RAM;
> -	memory_ranges++;
> +	if (!(kexec_flags & KEXEC_PRESERVE_CONTEXT)) {
> +		crash_memory_range[0].start = 0x00000000;
> +		crash_memory_range[0].end = 0x0009ffff;
> +		crash_memory_range[0].type = RANGE_RAM;
> +		memory_ranges++;
> +	}
>  
>  	while(fgets(line, sizeof(line), fp) != 0) {
>  		char *str;
> @@ -239,6 +242,22 @@ static int get_crash_memory_ranges(struc
>  		memory_ranges++;
>  	}
>  	fclose(fp);
> +	if (kexec_flags & KEXEC_PRESERVE_CONTEXT) {
> +		int i;
> +		for (i = 0; i < memory_ranges; i++) {
> +			if (crash_memory_range[i].end > 0x0009ffff) {
> +				crash_reserved_mem.start = \
> +					crash_memory_range[i].start;
> +				break;
> +			}
> +		}
> +		if (crash_reserved_mem.start >= mem_max) {
> +			fprintf(stderr, "Too small mem_max: 0x%llx.\n", mem_max);
> +			return -1;
> +		}
> +		crash_reserved_mem.end = mem_max;
> +		crash_reserved_mem.type = RANGE_RAM;
> +	}
>  	if (exclude_region(&memory_ranges, crash_reserved_mem.start,
>  				crash_reserved_mem.end) < 0)
>  		return -1;
> @@ -590,7 +609,8 @@ int load_crashdump_segments(struct kexec
>  	if (get_kernel_vaddr_and_size(info))
>  		return -1;
>  
> -	if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0)
> +	if (get_crash_memory_ranges(&mem_range, &nr_ranges,
> +				    info->kexec_flags) < 0)
>  		return -1;
>  
>  	/* Memory regions which panic kernel can safely use to boot into */
> @@ -602,13 +622,15 @@ int load_crashdump_segments(struct kexec
>  	add_memmap(memmap_p, crash_reserved_mem.start, sz);
>  
>  	/* Create a backup region segment to store backup data*/
> -	sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1);
> -	tmp = xmalloc(sz);
> -	memset(tmp, 0, sz);
> -	info->backup_start = add_buffer(info, tmp, sz, sz, align,
> -				0, max_addr, 1);
> -	if (delete_memmap(memmap_p, info->backup_start, sz) < 0)
> -		return -1;
> +	if (!(info->kexec_flags & KEXEC_PRESERVE_CONTEXT)) {
> +		sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1);
> +		tmp = xmalloc(sz);
> +		memset(tmp, 0, sz);
> +		info->backup_start = add_buffer(info, tmp, sz, sz, align,
> +						0, max_addr, 1);
> +		if (delete_memmap(memmap_p, info->backup_start, sz) < 0)
> +			return -1;
> +	}
>  
>  	/* Create elf header segment and store crash image data. */
>  	if (crash_create_elf64_headers(info, &elf_info,
> --- a/purgatory/arch/x86_64/purgatory-x86_64.c
> +++ b/purgatory/arch/x86_64/purgatory-x86_64.c
> @@ -6,6 +6,7 @@
>  uint8_t reset_vga = 0;
>  uint8_t legacy_pic = 0;
>  uint8_t panic_kernel = 0;
> +unsigned long jump_back_entry = 0;
>  char *cmdline_end = NULL;
>  
>  void setup_arch(void)
> @@ -14,8 +15,16 @@ void setup_arch(void)
>  	if (legacy_pic)   x86_setup_legacy_pic();
>  }
>  
> +void x86_setup_jump_back_entry(void)
> +{
> +	if (cmdline_end)
> +		sprintf(cmdline_end, " kexec_jump_back_entry=0x%lx",
> +			jump_back_entry);
> +}
> +
>  /* This function can be used to execute after the SHA256 verification. */
>  void post_verification_setup_arch(void)
>  {
> -	 if (panic_kernel)   crashdump_backup_memory();
> +	if (panic_kernel)    crashdump_backup_memory();
> +	if (jump_back_entry) x86_setup_jump_back_entry();
>  }
> --- a/purgatory/arch/x86_64/setup-x86_64.S
> +++ b/purgatory/arch/x86_64/setup-x86_64.S
> @@ -41,6 +41,9 @@ purgatory_start:
>  
>  	/* In 64bit mode the code segment is meaningless */
>  
> +	movq	0(%rsp), %rax
> +	movq	%rax, jump_back_entry
> +
>  	/* Setup a stack */
>  	movq	$lstack_end, %rsp
>  
> 
> 
> 
> _______________________________________________
> kexec mailing list
> kexec at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec



More information about the kexec mailing list