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 <[email protected]>
> 
> ---
>  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
> [email protected]
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to