diff --git a/kexec-tools-1.101-Makefile.patch b/kexec-tools-1.101-Makefile.patch deleted file mode 100644 index a4e5fed..0000000 --- a/kexec-tools-1.101-Makefile.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kexec-tools-1.101/Makefile.orig 2006-10-20 13:42:52.000000000 -0400 -+++ kexec-tools-1.101/Makefile 2006-10-20 13:43:22.000000000 -0400 -@@ -45,7 +45,7 @@ - MAN_PAGES:= kexec/kexec.8 - MAN_PAGES+= kdump/kdump.8 - BINARIES_i386:= $(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test $(SBINDIR)/kdump --BINARIES_x86_64:=$(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test -+BINARIES_x86_64:= $(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test $(SBINDIR)/kdump - BINARIES:=$(SBINDIR)/kexec $(BINARIES_$(ARCH)) - - TARGETS:=$(BINARIES) $(MAN_PAGES) diff --git a/kexec-tools-1.101-bzimage-options.patch b/kexec-tools-1.101-bzimage-options.patch deleted file mode 100644 index 7ede3f3..0000000 --- a/kexec-tools-1.101-bzimage-options.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c.orig 2007-01-04 13:58:06.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2007-01-04 14:14:07.000000000 -0500 -@@ -234,6 +234,9 @@ int bzImage_load(int argc, char **argv, - #define OPT_APPEND (OPT_ARCH_MAX+0) - #define OPT_RAMDISK (OPT_ARCH_MAX+1) - #define OPT_REAL_MODE (OPT_ARCH_MAX+2) -+#define OPT_ARGS_ELF (OPT_ARCH_MAX+3) -+#define OPT_ARGS_LINUX (OPT_ARCH_MAX+4) -+#define OPT_ARGS_NONE (OPT_ARCH_MAX+5) - static const struct option options[] = { - KEXEC_ARCH_OPTIONS - { "debug", 0, 0, OPT_DEBUG }, -@@ -242,6 +245,9 @@ int bzImage_load(int argc, char **argv, - { "initrd", 1, 0, OPT_RAMDISK }, - { "ramdisk", 1, 0, OPT_RAMDISK }, - { "real-mode", 0, 0, OPT_REAL_MODE }, -+ { "args-elf", 0, NULL, OPT_ARGS_ELF }, -+ { "args-linux", 0, NULL, OPT_ARGS_LINUX }, -+ { "args-none", 0, NULL, OPT_ARGS_NONE }, - { 0, 0, 0, 0 }, - }; - static const char short_options[] = KEXEC_ARCH_OPT_STR "d"; -@@ -276,6 +282,11 @@ int bzImage_load(int argc, char **argv, - case OPT_REAL_MODE: - real_mode_entry = 1; - break; -+ case OPT_ARGS_ELF: -+ case OPT_ARGS_LINUX: -+ case OPT_ARGS_NONE: -+ /* we can ignore these options */ -+ break; - } - } - command_line_len = 0; diff --git a/kexec-tools-1.101-elf-core-type.patch b/kexec-tools-1.101-elf-core-type.patch deleted file mode 100644 index 0296076..0000000 --- a/kexec-tools-1.101-elf-core-type.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/i386/kexec-x86.c.orig 2006-11-15 16:28:04.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-x86.c 2006-11-15 16:28:13.000000000 -0500 -@@ -145,7 +145,7 @@ - .serial_baud = 0, - .console_vga = 0, - .console_serial = 0, -- .core_header_type = CORE_TYPE_ELF64, -+ .core_header_type = CORE_TYPE_ELF32, - }; - - int arch_process_options(int argc, char **argv) diff --git a/kexec-tools-1.101-elf-format.patch b/kexec-tools-1.101-elf-format.patch deleted file mode 100644 index 446080f..0000000 --- a/kexec-tools-1.101-elf-format.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c.fix 2006-08-29 20:07:34.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c 2006-08-29 20:08:03.000000000 -0400 -@@ -120,7 +120,7 @@ int elf_x86_64_load(int argc, char **arg - /* - * Parse the command line arguments - */ -- arg_style = ARG_STYLE_ELF; -+ arg_style = ARG_STYLE_LINUX; - command_line = 0; - modified_cmdline = 0; - modified_cmdline_len = 0; ---- kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c.fix 2006-08-29 20:07:14.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c 2006-08-29 20:07:24.000000000 -0400 -@@ -121,7 +121,7 @@ int elf_x86_load(int argc, char **argv, - /* - * Parse the command line arguments - */ -- arg_style = ARG_STYLE_ELF; -+ arg_style = ARG_STYLE_LINUX; - command_line = 0; - modified_cmdline = 0; - modified_cmdline_len = 0; diff --git a/kexec-tools-1.101-et-dyn.patch b/kexec-tools-1.101-et-dyn.patch deleted file mode 100644 index ad2c1f2..0000000 --- a/kexec-tools-1.101-et-dyn.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- kexec-tools-1.101/kexec/kexec-elf.h.orig 2006-07-31 10:41:57.000000000 -0400 -+++ kexec-tools-1.101/kexec/kexec-elf.h 2006-07-31 10:42:09.000000000 -0400 -@@ -89,7 +89,7 @@ extern int build_elf_info(const char *bu - extern int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr); - extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr); - --extern int elf_exec_load(const struct mem_ehdr *ehdr, struct kexec_info *info); -+extern int elf_exec_load(struct mem_ehdr *ehdr, struct kexec_info *info); - extern int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, - unsigned long min, unsigned long max, int end); - ---- kexec-tools-1.101/kexec/kexec-elf-exec.c.orig 2006-07-31 10:14:20.000000000 -0400 -+++ kexec-tools-1.101/kexec/kexec-elf-exec.c 2006-07-31 10:18:25.000000000 -0400 -@@ -47,7 +47,7 @@ int build_elf_exec_info(const char *buf, - } - - --int elf_exec_load(const struct mem_ehdr *ehdr, struct kexec_info *info) -+int elf_exec_load(struct mem_ehdr *ehdr, struct kexec_info *info) - { - unsigned long base; - int result; -@@ -79,8 +79,8 @@ int elf_exec_load(const struct mem_ehdr - } - start = phdr->p_paddr; - stop = start + phdr->p_memsz; -- if (start > first) { -- start = first; -+ if (first > start) { -+ first = start; - } - if (last < stop) { - last = stop; -@@ -126,6 +126,10 @@ int elf_exec_load(const struct mem_ehdr - phdr->p_data, size, - phdr->p_paddr + base, phdr->p_memsz); - } -+ -+ /* Update entry point to reflect new load address*/ -+ ehdr->e_entry += base; -+ - result = 0; - out: - return result; diff --git a/kexec-tools-1.101-ia64-EFI.patch b/kexec-tools-1.101-ia64-EFI.patch deleted file mode 100644 index e88c652..0000000 --- a/kexec-tools-1.101-ia64-EFI.patch +++ /dev/null @@ -1,281 +0,0 @@ ---- kexec-tools-1.101/purgatory/arch/ia64/entry.S.orig1 2006-10-12 14:25:54.000000000 -0400 -+++ kexec-tools-1.101/purgatory/arch/ia64/entry.S 2006-10-12 14:48:04.000000000 -0400 -@@ -46,6 +46,8 @@ - br.call.sptk.many b0=ia64_env_setup - movl r10=__kernel_entry;; - ld8 r14=[r10];; -+ movl r10=__boot_param_base;; -+ ld8 r28=[r10];; - mov b6=r14;; - mov ar.lc=r0 - mov ar.ec=r0 -@@ -61,6 +63,7 @@ - DECLARE_DATA8(__command_line_len) - DECLARE_DATA8(__efi_memmap_base) - DECLARE_DATA8(__efi_memmap_size) -+DECLARE_DATA8(__boot_param_base) - DECLARE_DATA8(__loaded_segments) - DECLARE_DATA8(__loaded_segments_num) - ---- kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c.orig1 2006-10-12 14:25:54.000000000 -0400 -+++ kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c 2006-10-12 14:48:04.000000000 -0400 -@@ -123,11 +123,12 @@ - uint64_t command_line_len; - uint64_t efi_memmap_base; - uint64_t efi_memmap_size; -+ uint64_t boot_param_base; - struct loaded_segment *loaded_segments; - unsigned long loaded_segments_num; - }; - --void -+void - setup_arch(void) - { - reset_vga(); -@@ -138,11 +139,11 @@ - return addr - PAGE_OFFSET; - } - --void --patch_efi_memmap(struct kexec_boot_params *params, -+void -+patch_efi_memmap(struct kexec_boot_params *params, - struct ia64_boot_param *boot_param) - { -- void *dest = (void *)params->efi_memmap_base; -+ void *dest = (void *)params->efi_memmap_base; - void *src = (void *)boot_param->efi_memmap; - unsigned long len = boot_param->efi_memmap_size; - unsigned long memdesc_size = boot_param->efi_memdesc_size; -@@ -150,15 +151,15 @@ - efi_memory_desc_t *md1, *md2; - void *p1, *p2, *src_end = src + len; - int i; -- for (p1 = src, p2 = dest; p1 < src_end; -+ for (p1 = src, p2 = dest; p1 < src_end; - p1 += memdesc_size, p2 += memdesc_size) { - unsigned long mstart, mend; - md1 = p1; - md2 = p2; -- if (md1->num_pages == 0) -+ if (md1->num_pages == 0) - continue; - mstart = md1->phys_addr; -- mend = md1->phys_addr + (md1->num_pages -+ mend = md1->phys_addr + (md1->num_pages - << EFI_PAGE_SHIFT); - switch (md1->type) { - case EFI_LOADER_DATA: -@@ -168,7 +169,7 @@ - default: - *md2 = *md1; - } -- // segments are already sorted and aligned to 4K -+ // segments are already sorted and aligned to 4K - orig_type = md2->type; - for (i = 0; i < params->loaded_segments_num; i++) { - struct loaded_segment *seg; -@@ -177,50 +178,50 @@ - unsigned long start_pages, mid_pages, end_pages; - if (seg->end > mend) { - p1 += memdesc_size; -- for(; p1 < src_end; -+ for(; p1 < src_end; - p1 += memdesc_size) { - md1 = p1; - /* TODO check contig and attribute here */ -- mend = md1->phys_addr -+ mend = md1->phys_addr - + (md1->num_pages << EFI_PAGE_SHIFT); - if (seg->end < mend) - break; - } - } -- start_pages = (seg->start - mstart) -+ start_pages = (seg->start - mstart) - >> EFI_PAGE_SHIFT; - mid_pages = (seg->end - seg->start) - >> EFI_PAGE_SHIFT; -- end_pages = (mend - seg->end) -+ end_pages = (mend - seg->end) - >> EFI_PAGE_SHIFT; - if (start_pages) { - md2->num_pages = start_pages; -- p2 += memdesc_size; -+ p2 += memdesc_size; - md2 = p2; - *md2 = *md1; - } - md2->phys_addr = seg->start; - md2->num_pages = mid_pages; -- md2->type = seg->reserved ? -+ md2->type = seg->reserved ? - EFI_UNUSABLE_MEMORY:EFI_LOADER_DATA; - if (end_pages) { -- p2 += memdesc_size; -+ p2 += memdesc_size; - md2 = p2; - *md2 = *md1; - md2->phys_addr = seg->end; - md2->num_pages = end_pages; - md2->type = orig_type; - mstart = seg->end; -- } else -+ } else - break; - } - } - } -- -+ - boot_param->efi_memmap_size = p2 - dest; - } - --void -+void - flush_icache_range(char *start, unsigned long len) - { - unsigned long i; -@@ -233,7 +234,7 @@ - extern char __dummy_efi_function[], __dummy_efi_function_end[]; - - --void -+void - ia64_env_setup(struct ia64_boot_param *boot_param, - struct kexec_boot_params *params) - { -@@ -243,13 +244,15 @@ - unsigned long *set_virtual_address_map; - char *command_line = (char *)params->command_line; - uint64_t command_line_len = params->command_line_len; -- -+ struct ia64_boot_param *new_boot_param = -+ (struct ia64_boot_param *) params->boot_param_base; -+ memcpy(new_boot_param, boot_param, 4096); - // patch efi_runtime->set_virtual_address_map to a - // dummy function - len = __dummy_efi_function_end - __dummy_efi_function; -- memcpy(command_line + command_line_len, -+ memcpy(command_line + command_line_len, - __dummy_efi_function, len); -- systab = (efi_system_table_t *)boot_param->efi_systab; -+ systab = (efi_system_table_t *)new_boot_param->efi_systab; - runtime = (efi_runtime_services_t *)PA(systab->runtime); - set_virtual_address_map = - (unsigned long *)PA(runtime->set_virtual_address_map); -@@ -257,15 +260,14 @@ - (unsigned long)(command_line + command_line_len); - flush_icache_range(command_line + command_line_len, len); - -- patch_efi_memmap(params, boot_param); -- -- boot_param->efi_memmap = params->efi_memmap_base; -+ patch_efi_memmap(params, new_boot_param); - -- boot_param->command_line = params->command_line; -- boot_param->console_info.orig_x = 0; -- boot_param->console_info.orig_y = 0; -- boot_param->initrd_start = params->ramdisk_base; -- boot_param->initrd_size = params->ramdisk_size; -+ new_boot_param->efi_memmap = params->efi_memmap_base; -+ new_boot_param->command_line = params->command_line; -+ new_boot_param->console_info.orig_x = 0; -+ new_boot_param->console_info.orig_y = 0; -+ new_boot_param->initrd_start = params->ramdisk_base; -+ new_boot_param->initrd_size = params->ramdisk_size; - } - - /* This function can be used to execute after the SHA256 verification. */ ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c.orig1 2006-10-12 14:25:54.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2006-10-12 14:47:57.000000000 -0400 -@@ -36,6 +36,38 @@ - - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - -+/* Reserve range for EFI memmap and Boot parameter */ -+static int split_range(int range, unsigned long start, unsigned long end) -+{ -+ unsigned long ram_end = memory_range[range - 1].end; -+ unsigned int type = memory_range[range - 1].type; -+ int i; -+ //align end and start to page size of EFI -+ start = start & ~((1UL<<12) - 1); -+ end = (end + (1UL<<12) - 1)& ~((1UL<<12) - 1); -+ for (i = 0; i < range; i++) -+ if(memory_range[i].start <= start && memory_range[i].end >=end) -+ break; -+ if (i >= range) -+ return range; -+ range = i; -+ if (memory_range[range].start < start) { -+ memory_range[range].end = start; -+ range++; -+ } -+ memory_range[range].start = start; -+ memory_range[range].end = end; -+ memory_range[range].type = RANGE_RESERVED; -+ range++; -+ if (end < ram_end) { -+ memory_range[range].start = end; -+ memory_range[range].end = ram_end; -+ memory_range[range].type = type; -+ range++; -+ } -+ return range; -+} -+ - /* Return a sorted list of available memory ranges. */ - int get_memory_ranges(struct memory_range **range, int *ranges, - unsigned long kexec_flags) -@@ -85,6 +117,12 @@ - mem_max = end; - } - continue; -+ } else if (memcmp(str, "Boot parameter\n", 14) == 0) { -+ memory_ranges = split_range(memory_ranges, start, end); -+ continue; -+ } else if (memcmp(str, "EFI Memory Map\n", 14) == 0) { -+ memory_ranges = split_range(memory_ranges, start, end); -+ continue; - } else - continue; - /* -@@ -125,7 +163,7 @@ - { - static const struct option options[] = { - KEXEC_ARCH_OPTIONS -- { 0, 0, NULL, 0 }, -+ { 0, 0, NULL, 0 }, - }; - static const char short_options[] = KEXEC_ARCH_OPT_STR; - int opt; ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig1 2006-10-12 14:25:54.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-10-12 14:48:04.000000000 -0400 -@@ -115,9 +115,10 @@ - unsigned long entry, max_addr, gp_value; - unsigned long command_line_base, ramdisk_base; - unsigned long efi_memmap_base, efi_memmap_size; -+ unsigned long boot_param_base; - int result; - int opt; -- char *efi_memmap_buf; -+ char *efi_memmap_buf, *boot_param; - #define OPT_APPEND (OPT_ARCH_MAX+0) - #define OPT_RAMDISK (OPT_ARCH_MAX+1) - static const struct option options[] = { -@@ -191,6 +192,13 @@ - &command_line) < 0) - return -1; - -+ // reverve 4k for ia64_boot_param -+ boot_param = xmalloc(4096); -+ boot_param_base = add_buffer(info, boot_param, 4096, 4096, 4096, 0, -+ max_addr, -1); -+ elf_rel_set_symbol(&info->rhdr, "__boot_param_base", -+ &boot_param_base, sizeof(long)); -+ - // reserve 8k for efi_memmap - efi_memmap_size = 1UL<<14; - efi_memmap_buf = xmalloc(efi_memmap_size); diff --git a/kexec-tools-1.101-ia64-dash-l-fix.patch b/kexec-tools-1.101-ia64-dash-l-fix.patch deleted file mode 100644 index 8419113..0000000 --- a/kexec-tools-1.101-ia64-dash-l-fix.patch +++ /dev/null @@ -1,125 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h.orig 2006-12-01 14:36:39.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h 2006-12-01 14:49:13.000000000 -0500 -@@ -7,6 +7,10 @@ - int elf_ia64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); - void elf_ia64_usage(void); -+int update_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr); -+void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr, -+ unsigned long addr); -+ - #define MAX_MEMORY_RANGES 1024 - #define EFI_PAGE_SIZE (1UL<<12) - #define ELF_PAGE_SIZE (1UL<<16) ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c.orig 2006-12-01 14:36:39.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2006-12-01 14:55:16.000000000 -0500 -@@ -28,14 +28,16 @@ - #include - #include - #include -+#include - #include - #include "../../kexec.h" - #include "../../kexec-syscall.h" -+#include "elf.h" - #include "kexec-ia64.h" - #include - - static struct memory_range memory_range[MAX_MEMORY_RANGES]; -- -+static int memory_ranges; - /* Reserve range for EFI memmap and Boot parameter */ - static int split_range(int range, unsigned long start, unsigned long end) - { -@@ -73,7 +75,6 @@ - unsigned long kexec_flags) - { - const char iomem[]= "/proc/iomem"; -- int memory_ranges = 0; - char line[MAX_LINE]; - FILE *fp; - fp = fopen(iomem, "r"); -@@ -209,6 +210,45 @@ - return 0; - } - -+int update_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr) -+{ -+ int i; -+ struct mem_phdr *phdr; -+ unsigned long start_addr = ULONG_MAX, end_addr = 0; -+ unsigned long align = 1UL<<26; // 64M -+ for(i = 0; i < ehdr->e_phnum; i++) { -+ phdr = &ehdr->e_phdr[i]; -+ if (phdr->p_type == PT_LOAD) { -+ if (phdr->p_paddr < start_addr) -+ start_addr = phdr->p_paddr; -+ if ((phdr->p_paddr + phdr->p_memsz) > end_addr) -+ end_addr = phdr->p_paddr + phdr->p_memsz; -+ } -+ -+ } -+ -+ for (i = 0; i < memory_ranges -+ && memory_range[i].start <= start_addr; i++) { -+ if (memory_range[i].type == RANGE_RAM && -+ memory_range[i].end > end_addr) -+ return; -+ } -+ -+ for (i = 0; i < memory_ranges; i++) { -+ if (memory_range[i].type == RANGE_RAM) { -+ unsigned long start = -+ (memory_range[i].start + align - 1)&~(align - 1); -+ unsigned long end = memory_range[i].end; -+ if (end > start && -+ (end - start) > (end_addr - start_addr)) { -+ move_loaded_segments(info, ehdr, start); -+ return 0; -+ } -+ } -+ } -+ return 1; -+} -+ - void arch_update_purgatory(struct kexec_info *info) - { - } ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2006-12-01 14:36:39.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-12-01 14:59:29.000000000 -0500 -@@ -84,7 +84,8 @@ - - /* Move the crash kerenl physical offset to reserved region - */ --static void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr) -+void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr, -+ unsigned long addr) - { - int i; - long offset; -@@ -92,7 +93,7 @@ - for(i = 0; i < ehdr->e_phnum; i++) { - phdr = &ehdr->e_phdr[i]; - if (phdr->p_type == PT_LOAD) { -- offset = mem_min - phdr->p_paddr; -+ offset = addr - phdr->p_paddr; - break; - } - } -@@ -174,8 +175,14 @@ - fprintf(stderr, "Failed to find crash kernel region in /proc/iomem\n"); - return -1; - } -- move_loaded_segments(info, &ehdr); -- } -+ move_loaded_segments(info, &ehdr, mem_min); -+ } else { -+ if (update_loaded_segments(info, &ehdr)) { -+ fprintf(stderr, "Failed to place kernel\n"); -+ return -1; -+ } -+ } -+ - - entry = ehdr.e_entry; - max_addr = elf_max_addr(&ehdr); diff --git a/kexec-tools-1.101-ia64-fixup.patch b/kexec-tools-1.101-ia64-fixup.patch deleted file mode 100644 index 795ccec..0000000 --- a/kexec-tools-1.101-ia64-fixup.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c.orig 2006-07-05 15:16:35.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2006-07-05 15:16:54.000000000 -0400 -@@ -87,8 +87,6 @@ int arch_process_options(int argc, char - }; - static const char short_options[] = KEXEC_ARCH_OPT_STR; - int opt; -- unsigned long value; -- char *end; - - opterr = 0; /* Don't complain about unrecognized options here */ - while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { -@@ -115,28 +113,6 @@ int arch_compat_trampoline(struct kexec_ - } - if (strcmp(utsname.machine, "ia64") == 0) - { -- info->kexec_flags |= KEXEC_ARCH_X86_64; -- } -- else { -- fprintf(stderr, "Unsupported machine type: %s\n", -- utsname.machine); -- return -1; -- } -- return 0; --} -- --int arch_compat_trampoline(struct kexec_info *info) --{ -- int result; -- struct utsname utsname; -- result = uname(&utsname); -- if (result < 0) { -- fprintf(stderr, "uname failed: %s\n", -- strerror(errno)); -- return -1; -- } -- if (strcmp(utsname.machine, "ia64") == 0) -- { - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_IA64 here. - */ diff --git a/kexec-tools-1.101-ia64-icache-align.patch b/kexec-tools-1.101-ia64-icache-align.patch deleted file mode 100644 index fed2601..0000000 --- a/kexec-tools-1.101-ia64-icache-align.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c.orig 2006-10-20 13:45:49.000000000 -0400 -+++ kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c 2006-10-20 13:46:56.000000000 -0400 -@@ -224,7 +224,9 @@ - void - flush_icache_range(char *start, unsigned long len) - { -- unsigned long i; -+ unsigned long i,addr; -+ addr = (unsigned long)start & ~31UL; -+ len += (unsigned long)start - addr; - for (i = 0;i < len; i += 32) - asm volatile("fc.i %0"::"r"(start + i):"memory"); - asm volatile (";;sync.i;;":::"memory"); diff --git a/kexec-tools-1.101-ia64-kdump.patch b/kexec-tools-1.101-ia64-kdump.patch deleted file mode 100644 index 80cab6f..0000000 --- a/kexec-tools-1.101-ia64-kdump.patch +++ /dev/null @@ -1,1251 +0,0 @@ -diff -puN /dev/null kexec/arch/ia64/crashdump-ia64.c ---- /dev/null 2006-07-13 05:14:41.629277080 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/arch/ia64/crashdump-ia64.c 2006-07-13 14:42:05.000000000 +0530 -@@ -0,0 +1,351 @@ -+/* -+ * kexec: crashdum support -+ * Copyright (C) 2005-2006 Zou Nan hai Intel Corp -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-elf.h" -+#include "../../kexec-syscall.h" -+#include "kexec-ia64.h" -+#include "crashdump-ia64.h" -+ -+int memory_ranges = 0; -+#define LOAD_OFFSET (0xa000000000000000UL + 0x100000000UL - (1UL<<26)) -+#define MAX_LINE 160 -+/* Stores a sorted list of RAM memory ranges for which to create elf headers. -+ * A separate program header is created for backup region */ -+static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; -+/* Memory region reserved for storing panic kernel and other data. */ -+static struct memory_range crash_reserved_mem; -+unsigned long elfcorehdr; -+static unsigned long kernel_code_start; -+struct loaded_segment { -+ unsigned long start; -+ unsigned long end; -+ unsigned long reserved; -+}; -+ -+#define MAX_LOAD_SEGMENTS 128 -+struct loaded_segment loaded_segments[MAX_LOAD_SEGMENTS]; -+ -+unsigned long loaded_segments_num, loaded_segments_base; -+static int seg_comp(const void *a, const void *b) -+{ -+ const struct loaded_segment *x = a, *y = b; -+ /* avoid overflow */ -+ if (x->start > y->start) return 1; -+ if (x->start < y->start) return -1; -+ return 0; -+} -+ -+/* purgatory code need this info to patch the EFI memmap -+ */ -+static void add_loaded_segments_info(struct kexec_info *info, -+ struct mem_ehdr *ehdr, unsigned long max_addr) -+{ -+ int i; -+ for(i = 0; i < ehdr->e_phnum; i++) { -+ unsigned long start, end; -+ struct mem_phdr *phdr; -+ phdr = &ehdr->e_phdr[i]; -+ if (phdr->p_type != PT_LOAD) -+ continue; -+ start = phdr->p_paddr; -+ end = phdr->p_paddr + phdr->p_memsz; -+ -+ loaded_segments[loaded_segments_num].start = -+ start&~(ELF_PAGE_SIZE-1); -+ loaded_segments[loaded_segments_num].end = -+ (end + ELF_PAGE_SIZE - 1)&~(ELF_PAGE_SIZE - 1); -+ loaded_segments[loaded_segments_num].reserved = 0; -+ loaded_segments_num++; -+ } -+} -+ -+static int get_crash_notes_section_addr(unsigned long *addr, int cpu) -+{ -+ char crash_notes[128]; -+ char line[MAX_LINE]; -+ FILE *fp; -+ sprintf(crash_notes, "/sys/devices/system/cpu/cpu%d/crash_notes", cpu); -+ fp = fopen(crash_notes, "r"); -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", -+ crash_notes, strerror(errno)); -+ fprintf(stderr, "Try mounting sysfs\n"); -+ return -1; -+ } -+ if (fscanf(fp, "%lx", addr) != 1) { -+ *addr = 0; -+ return -1; -+ } -+ return 0; -+} -+ -+/* Removes crash reserve region from list of memory chunks for whom elf program -+ * headers have to be created. Assuming crash reserve region to be a single -+ * continuous area fully contained inside one of the memory chunks */ -+static int exclude_crash_reserve_region(int *nr_ranges) -+{ -+ int i, j, tidx = -1; -+ unsigned long cstart, cend; -+ struct memory_range temp_region; -+ -+ /* Crash reserved region. */ -+ cstart = crash_reserved_mem.start; -+ cend = crash_reserved_mem.end; -+ -+ for (i = 0; i < (*nr_ranges); i++) { -+ unsigned long mstart, mend; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (cstart < mend && cend > mstart) { -+ if (cstart != mstart && cend != mend) { -+ /* Split memory region */ -+ crash_memory_range[i].end = cstart - 1; -+ temp_region.start = cend + 1; -+ temp_region.end = mend; -+ temp_region.type = RANGE_RAM; -+ tidx = i+1; -+ } else if (cstart != mstart) -+ crash_memory_range[i].end = cstart - 1; -+ else -+ crash_memory_range[i].start = cend + 1; -+ } -+ } -+ /* Insert split memory region, if any. */ -+ if (tidx >= 0) { -+ if (*nr_ranges == CRASH_MAX_MEMORY_RANGES) { -+ /* No space to insert another element. */ -+ fprintf(stderr, "Error: Number of crash memory ranges" -+ " excedeed the max limit\n"); -+ return -1; -+ } -+ for (j = (*nr_ranges - 1); j >= tidx; j--) -+ crash_memory_range[j+1] = crash_memory_range[j]; -+ crash_memory_range[tidx].start = temp_region.start; -+ crash_memory_range[tidx].end = temp_region.end; -+ crash_memory_range[tidx].type = temp_region.type; -+ (*nr_ranges)++; -+ } -+ return 0; -+} -+ -+static int prepare_crash_memory_elf64_headers(struct kexec_info *info, -+ void *buf, unsigned long size) -+{ -+ Elf64_Ehdr *elf; -+ Elf64_Phdr *phdr; -+ int i; -+ long int nr_cpus = 0; -+ char *bufp = buf; -+ unsigned long notes_addr, notes_offset; -+ -+ /* Setup ELF Header*/ -+ elf = (Elf64_Ehdr *) bufp; -+ bufp += sizeof(Elf64_Ehdr); -+ memcpy(elf->e_ident, ELFMAG, SELFMAG); -+ elf->e_ident[EI_CLASS] = ELFCLASS64; -+ elf->e_ident[EI_DATA] = ELFDATA2LSB; -+ elf->e_ident[EI_VERSION]= EV_CURRENT; -+ elf->e_ident[EI_OSABI] = ELFOSABI_NONE; -+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); -+ elf->e_type = ET_CORE; -+ elf->e_machine = EM_IA_64; -+ elf->e_version = EV_CURRENT; -+ elf->e_entry = 0; -+ elf->e_phoff = sizeof(Elf64_Ehdr); -+ elf->e_shoff = 0; -+ elf->e_flags = 0; -+ elf->e_ehsize = sizeof(Elf64_Ehdr); -+ elf->e_phentsize= sizeof(Elf64_Phdr); -+ elf->e_phnum = 0; -+ elf->e_shentsize= 0; -+ elf->e_shnum = 0; -+ elf->e_shstrndx = 0; -+ -+ /* PT_NOTE program headers. One per cpu*/ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ return -1; -+ } -+ -+ /* Need to find a better way to determine per cpu notes section size. */ -+#define MAX_NOTE_BYTES 1024 -+ -+ for (i = 0; i < nr_cpus; i++) { -+ if (get_crash_notes_section_addr (¬es_addr, i) < 0) -+ break; -+ notes_offset = notes_addr; -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_NOTE; -+ phdr->p_flags = 0; -+ phdr->p_offset = notes_offset; -+ phdr->p_vaddr = phdr->p_paddr = notes_offset; -+ phdr->p_filesz = phdr->p_memsz = MAX_NOTE_BYTES; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ -+ for (i = 0; i < memory_ranges; i++) { -+ unsigned long mstart, mend; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (!mstart && !mend) -+ break; -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ phdr->p_offset = mstart; -+ /*add region 5 mapping for kernel*/ -+ if (kernel_code_start >= mstart && kernel_code_start < mend) { -+ phdr->p_vaddr = mstart + LOAD_OFFSET; -+ phdr->p_paddr = mstart; -+ phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; -+ phdr->p_align = 0; -+ (elf->e_phnum)++; -+ -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ phdr->p_offset = mstart; -+ } -+ phdr->p_vaddr = mstart + PAGE_OFFSET; -+ phdr->p_paddr = mstart; -+ phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; -+ phdr->p_align = 0; -+ (elf->e_phnum)++; -+ } -+ return 0; -+} -+ -+static int get_crash_memory_ranges(struct memory_range **range, int *ranges) -+{ -+ const char iomem[]= "/proc/iomem"; -+ char line[MAX_LINE]; -+ FILE *fp; -+ unsigned long start, end; -+ -+ fp = fopen(iomem, "r"); -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", -+ iomem, strerror(errno)); -+ return -1; -+ } -+ while(fgets(line, sizeof(line), fp) != 0) { -+ char *str; -+ int type, consumed, count; -+ if (memory_ranges >= CRASH_MAX_MEMORY_RANGES) -+ break; -+ count = sscanf(line, "%lx-%lx : %n", -+ &start, &end, &consumed); -+ str = line + consumed; -+ if (count != 2) -+ continue; -+ -+ if (memcmp(str, "System RAM\n", 11) == 0) { -+ type = RANGE_RAM; -+ } else if (memcmp(str, "Crash kernel\n", 13) == 0) { -+ /* Reserved memory region. New kernel can -+ * use this region to boot into. */ -+ crash_reserved_mem.start = start; -+ crash_reserved_mem.end = end; -+ crash_reserved_mem.type = RANGE_RAM; -+ continue; -+ } -+ else if (memcmp(str, "Kernel code\n", 12) == 0) { -+ kernel_code_start = start; -+ continue; -+ }else -+ continue; -+ crash_memory_range[memory_ranges].start = start; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = type; -+ memory_ranges++; -+ } -+ fclose(fp); -+ if (exclude_crash_reserve_region(&memory_ranges) < 0) -+ return -1; -+ *ranges = memory_ranges; -+ return 0; -+} -+ -+static void -+cmdline_add_elfcorehdr(char **cmdline, unsigned long addr) -+{ -+ char *str = *cmdline; -+ char buf[64]; -+ size_t len; -+ sprintf(buf, " elfcorehdr=%ldK", addr/1024); -+ len = strlen(str) + strlen(buf) + 1; -+ str = xmalloc(len); -+ sprintf(str, "%s%s", *cmdline, buf); -+ *cmdline = str; -+} -+ -+int load_crashdump_segments(struct kexec_info *info, struct mem_ehdr *ehdr, -+ unsigned long max_addr, unsigned long min_base, -+ char **cmdline) -+{ -+ //struct memory_range *mem_range, *memmap_p; -+ struct memory_range *mem_range; -+ int nr_ranges; -+ size_t size; -+ void *tmp; -+ if (info->kexec_flags & KEXEC_ON_CRASH ) { -+ if (get_crash_memory_ranges(&mem_range, &nr_ranges) == 0) { -+ size = sizeof(Elf64_Ehdr) + -+ (nr_ranges + 1) * sizeof(Elf64_Phdr); -+ size = (size + EFI_PAGE_SIZE - 1) & ~(EFI_PAGE_SIZE - 1); -+ tmp = xmalloc(size); -+ memset(tmp, 0, size); -+ if (prepare_crash_memory_elf64_headers(info, tmp, size) < 0) -+ return -1; -+ elfcorehdr = add_buffer(info, tmp, size, size, EFI_PAGE_SIZE, min_base, -+ max_addr, -1); -+ loaded_segments[loaded_segments_num].start = elfcorehdr; -+ loaded_segments[loaded_segments_num].end = elfcorehdr + size; -+ loaded_segments[loaded_segments_num].reserved = 1; -+ loaded_segments_num++; -+ cmdline_add_elfcorehdr(cmdline, elfcorehdr); -+ } -+ } -+ add_loaded_segments_info(info, ehdr, max_addr); -+ size = sizeof(struct loaded_segment) * loaded_segments_num; -+ qsort(loaded_segments, loaded_segments_num, -+ sizeof(struct loaded_segment), seg_comp); -+ loaded_segments_base = add_buffer(info, loaded_segments, -+ size, size, 16, 0, max_addr, -1); -+ -+ elf_rel_set_symbol(&info->rhdr, "__loaded_segments", -+ &loaded_segments_base, sizeof(long)); -+ elf_rel_set_symbol(&info->rhdr, "__loaded_segments_num", -+ &loaded_segments_num, sizeof(long)); -+ return 0; -+} -+ -+ -diff -puN /dev/null kexec/arch/ia64/crashdump-ia64.h ---- /dev/null 2006-07-13 05:14:41.629277080 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/arch/ia64/crashdump-ia64.h 2006-07-13 14:42:05.000000000 +0530 -@@ -0,0 +1,13 @@ -+#ifndef CRASHDUMP_IA64_H -+#define CRASHDUMP_IA64_H -+ -+#define PAGE_OFFSET 0xe000000000000000UL -+#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -+extern int load_crashdump_segments(struct kexec_info *info, -+ struct mem_ehdr *ehdr, unsigned long max_addr, -+ unsigned long min_base, char **cmdline); -+ -+#define CRASH_MAX_MEMMAP_NR (KEXEC_MAX_SEGMENTS + 1) -+#define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 2) -+ -+#endif -diff -puN kexec/arch/ia64/kexec-elf-ia64.c~kdump-ia64 kexec/arch/ia64/kexec-elf-ia64.c ---- kexec-tools-1.101-kdump/kexec/arch/ia64/kexec-elf-ia64.c~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/arch/ia64/kexec-elf-ia64.c 2006-07-13 14:42:05.000000000 +0530 -@@ -40,7 +40,9 @@ - #include - #include - #include "../../kexec.h" -+#include "../../kexec-syscall.h" - #include "../../kexec-elf.h" -+#include "crashdump-ia64.h" - #include - - static const int probe_debug = 0; -@@ -80,6 +82,28 @@ void elf_ia64_usage(void) - " --initrd=FILE Use FILE as the kernel's initial ramdisk.\n"); - } - -+/* Move the crash kerenl physical offset to reserved region -+ */ -+static void move_loaded_segments(struct kexec_info *info, struct mem_ehdr *ehdr) -+{ -+ int i; -+ long offset; -+ struct mem_phdr *phdr; -+ for(i = 0; i < ehdr->e_phnum; i++) { -+ phdr = &ehdr->e_phdr[i]; -+ if (phdr->p_type == PT_LOAD) { -+ offset = mem_min - phdr->p_paddr; -+ break; -+ } -+ } -+ ehdr->e_entry += offset; -+ for(i = 0; i < ehdr->e_phnum; i++) { -+ phdr = &ehdr->e_phdr[i]; -+ if (phdr->p_type == PT_LOAD) -+ phdr->p_paddr += offset; -+ } -+} -+ - int elf_ia64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info) - { -@@ -89,9 +113,11 @@ int elf_ia64_load(int argc, char **argv, - off_t ramdisk_size = 0; - unsigned long command_line_len; - unsigned long entry, max_addr, gp_value; -- unsigned command_line_base, ramdisk_base; -+ unsigned long command_line_base, ramdisk_base; -+ unsigned long efi_memmap_base, efi_memmap_size; - int result; - int opt; -+ char *efi_memmap_buf; - #define OPT_APPEND (OPT_ARCH_MAX+0) - #define OPT_RAMDISK (OPT_ARCH_MAX+1) - static const struct option options[] = { -@@ -135,6 +161,15 @@ int elf_ia64_load(int argc, char **argv, - free_elf_info(&ehdr); - return result; - } -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH ) { -+ if ((mem_min == 0x00) && (mem_max = ULONG_MAX)) { -+ fprintf(stderr, "Failed to find crash kernel region in /proc/iomem\n"); -+ return -1; -+ } -+ move_loaded_segments(info, &ehdr); -+ } -+ - entry = ehdr.e_entry; - max_addr = elf_max_addr(&ehdr); - -@@ -149,17 +184,48 @@ int elf_ia64_load(int argc, char **argv, - - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0x80000, ULONG_MAX, 1); -+ 0x0, ULONG_MAX, -1); - -- if (command_line_len) { -+ -+ if (load_crashdump_segments(info, &ehdr, max_addr, 0, -+ &command_line) < 0) -+ return -1; -+ -+ // reserve 8k for efi_memmap -+ efi_memmap_size = 1UL<<14; -+ efi_memmap_buf = xmalloc(efi_memmap_size); -+ efi_memmap_base = add_buffer(info, efi_memmap_buf, -+ efi_memmap_size, efi_memmap_size, 4096, 0, -+ max_addr, -1); -+ -+ elf_rel_set_symbol(&info->rhdr, "__efi_memmap_base", -+ &efi_memmap_base, sizeof(long)); -+ -+ elf_rel_set_symbol(&info->rhdr, "__efi_memmap_size", -+ &efi_memmap_size, sizeof(long)); -+ if (command_line) { -+ command_line_len = strlen(command_line) + 1; -+ } -+ if (command_line_len || (info->kexec_flags & KEXEC_ON_CRASH )) { - char *cmdline = xmalloc(command_line_len); - strcpy(cmdline, command_line); -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ char buf[128]; -+ sprintf(buf," max_addr=%lluM min_addr=%lluM", -+ mem_max>>20, mem_min>>20); -+ command_line_len = strlen(cmdline) + strlen(buf) + 1; -+ cmdline = xrealloc(cmdline, command_line_len); -+ strcat(cmdline, buf); -+ } -+ - command_line_len = (command_line_len + 15)&(~15); -+ command_line_base = add_buffer(info, cmdline, -+ command_line_len, command_line_len, -+ getpagesize(), 0UL, -+ max_addr, -1); - elf_rel_set_symbol(&info->rhdr, "__command_line_len", - &command_line_len, sizeof(long)); -- command_line_base = add_buffer(info, cmdline, -- command_line_len, command_line_len, -- 16, 0, max_addr, 1); - elf_rel_set_symbol(&info->rhdr, "__command_line", - &command_line_base, sizeof(long)); - } -@@ -168,7 +234,7 @@ int elf_ia64_load(int argc, char **argv, - ramdisk_buf = slurp_file(ramdisk, &ramdisk_size); - ramdisk_base = add_buffer(info, ramdisk_buf, ramdisk_size, - ramdisk_size, -- getpagesize(), 0, max_addr, 1); -+ getpagesize(), 0, max_addr, -1); - elf_rel_set_symbol(&info->rhdr, "__ramdisk_base", - &ramdisk_base, sizeof(long)); - elf_rel_set_symbol(&info->rhdr, "__ramdisk_size", -diff -puN kexec/arch/ia64/kexec-elf-rel-ia64.c~kdump-ia64 kexec/arch/ia64/kexec-elf-rel-ia64.c ---- kexec-tools-1.101-kdump/kexec/arch/ia64/kexec-elf-rel-ia64.c~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/arch/ia64/kexec-elf-rel-ia64.c 2006-07-13 14:42:05.000000000 +0530 -@@ -1,3 +1,26 @@ -+/* -+ * Copyright (C) 2005-2006 Zou Nan hai (nanhai.zou@intel.com) -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+/* pugatory relocation code -+ * Most of the code in this file is -+ * based on arch/ia64/kernel/module.c in Linux kernel -+ */ -+ -+ - /* Most of the code in this file is - * based on arch/ia64/kernel/module.c in Linux kernel - */ -@@ -43,6 +66,15 @@ ia64_patch (uint64_t insn_addr, uint64_t - b[1] = (b1 & ~m1) | (v1 & m1); - } - -+static void -+put_unaligned64(unsigned long val, unsigned char *location) -+{ -+ unsigned char *src = (unsigned char *)&val; -+ int i; -+ for (i = 0; i < sizeof(long); i++) -+ *location++ = *src++; -+} -+ - static inline uint64_t - bundle (const uint64_t insn) - { -@@ -102,6 +134,11 @@ void machine_apply_elf_rel(struct mem_eh - | ((value & 0x0fffffUL) << 13) /* bit 0 -> 13 */)); - } - break; -+ case R_IA64_PCREL64LSB: { -+ value = value - address; -+ put_unaligned64(value, location); -+ } break; -+ case R_IA64_GPREL22: - case R_IA64_LTOFF22X: - if (value - gp_value + MAX_LTOFF/2 >= MAX_LTOFF) - die("value out of gp relative range"); -diff -puN kexec/arch/ia64/kexec-ia64.h~kdump-ia64 kexec/arch/ia64/kexec-ia64.h ---- kexec-tools-1.101-kdump/kexec/arch/ia64/kexec-ia64.h~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/arch/ia64/kexec-ia64.h 2006-07-13 14:42:05.000000000 +0530 -@@ -7,5 +7,7 @@ int elf_ia64_probe(const char *buf, off_ - int elf_ia64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); - void elf_ia64_usage(void); -- -+#define MAX_MEMORY_RANGES 1024 -+#define EFI_PAGE_SIZE (1UL<<12) -+#define ELF_PAGE_SIZE (1UL<<16) - #endif /* KEXEC_IA64_H */ -diff -puN kexec/arch/ia64/Makefile~kdump-ia64 kexec/arch/ia64/Makefile ---- kexec-tools-1.101-kdump/kexec/arch/ia64/Makefile~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/arch/ia64/Makefile 2006-07-13 14:42:05.000000000 +0530 -@@ -4,3 +4,5 @@ - KEXEC_C_SRCS+= kexec/arch/ia64/kexec-ia64.c - KEXEC_C_SRCS+= kexec/arch/ia64/kexec-elf-ia64.c - KEXEC_C_SRCS+= kexec/arch/ia64/kexec-elf-rel-ia64.c -+KEXEC_C_SRCS+= kexec/arch/ia64/crashdump-ia64.c -+ -diff -puN kexec/kexec.c~kdump-ia64 kexec/kexec.c ---- kexec-tools-1.101-kdump/kexec/kexec.c~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/kexec.c 2006-07-13 14:42:05.000000000 +0530 -@@ -96,6 +96,9 @@ int valid_memory_range(unsigned long sst - continue; - mstart = memory_range[i].start; - mend = memory_range[i].end; -+ if (i < memory_ranges - 1 && mend == memory_range[i+1].start) -+ mend = memory_range[i+1].end; -+ - /* Check to see if we are fully contained */ - if ((mstart <= sstart) && (mend >= send)) { - return 1; -diff -puN kexec/kexec-sha256.h~kdump-ia64 kexec/kexec-sha256.h ---- kexec-tools-1.101-kdump/kexec/kexec-sha256.h~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/kexec/kexec-sha256.h 2006-07-13 14:42:05.000000000 +0530 -@@ -6,6 +6,6 @@ struct sha256_region { - unsigned long len; - }; - --#define SHA256_REGIONS 8 -+#define SHA256_REGIONS 16 - - #endif /* KEXEC_SHA256_H */ -diff -puN purgatory/arch/ia64/console-ia64.c~kdump-ia64 purgatory/arch/ia64/console-ia64.c ---- kexec-tools-1.101-kdump/purgatory/arch/ia64/console-ia64.c~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/console-ia64.c 2006-07-13 14:42:05.000000000 +0530 -@@ -1,5 +1,47 @@ - #include -+#include "io.h" -+ -+#define VGABASE UNCACHED(0xb8000) -+ -+/* code based on i386 console code -+ * TODO add serial support -+ */ -+#define MAX_YPOS 25 -+#define MAX_XPOS 80 -+ -+unsigned long current_ypos = 1, current_xpos = 0; -+ -+static void putchar_vga(int ch) -+{ -+ int i, k, j; -+ -+ if (current_ypos >= MAX_YPOS) { -+ /* scroll 1 line up */ -+ for (k = 1, j = 0; k < MAX_YPOS; k++, j++) { -+ for (i = 0; i < MAX_XPOS; i++) { -+ writew(readw(VGABASE + 2*(MAX_XPOS*k + i)), -+ VGABASE + 2*(MAX_XPOS*j + i)); -+ } -+ } -+ for (i = 0; i < MAX_XPOS; i++) -+ writew(0x720, VGABASE + 2*(MAX_XPOS*j + i)); -+ current_ypos = MAX_YPOS-1; -+ } -+ if (ch == '\n') { -+ current_xpos = 0; -+ current_ypos++; -+ } else if (ch != '\r') { -+ writew(((0x7 << 8) | (unsigned short) ch), -+ VGABASE + 2*(MAX_XPOS*current_ypos + -+ current_xpos++)); -+ if (current_xpos >= MAX_XPOS) { -+ current_xpos = 0; -+ current_ypos++; -+ } -+ } -+} -+ - void putchar(int ch) - { -- /* Nothing for now */ -+ putchar_vga(ch); - } -diff -puN purgatory/arch/ia64/entry.S~kdump-ia64 purgatory/arch/ia64/entry.S ---- kexec-tools-1.101-kdump/purgatory/arch/ia64/entry.S~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/entry.S 2006-07-13 14:42:05.000000000 +0530 -@@ -1,7 +1,7 @@ - /* - * purgatory: setup code - * -- * Copyright (C) 2005 Zou Nan hai (nanhai.zou@intel.com) -+ * Copyright (C) 2005-2006 Zou Nan hai (nanhai.zou@intel.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -16,6 +16,10 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -+#define DECLARE_DATA8(name) \ -+.global name; \ -+.size name, 8; \ -+name: data8 0x0 - - .global __dummy_efi_function - .align 32 -@@ -35,18 +39,10 @@ purgatory_start: - ld8 gp=[r2];; - br.call.sptk.many b0=purgatory - ;; -- alloc r2 = ar.pfs, 0, 0, 5, 0 -+ alloc r2 = ar.pfs, 0, 0, 2, 0 - ;; - mov out0=r28 -- -- movl r2=__command_line;; -- ld8 out1=[r2];; -- movl r2=__command_line_len;; -- ld8 out2=[r2];; -- movl r2=__ramdisk_base;; -- ld8 out3=[r2];; -- movl r2=__ramdisk_size;; -- ld8 out4=[r2];; -+ movl out1=__ramdisk_base;; - br.call.sptk.many b0=ia64_env_setup - movl r10=__kernel_entry;; - ld8 r14=[r10];; -@@ -58,28 +54,14 @@ purgatory_start: - br.call.sptk.many b0=b6 - .endp purgatory_start - --.align 32 --.global __kernel_entry --.size __kernel_entry, 8 --__kernel_entry: -- data8 0x0 --.global __command_line --.size __command_line, 8 --__command_line: -- data8 0x0 --.global __command_line_len --.size __command_line_len, 8 --__command_line_len: -- data8 0x0 --.global __ramdisk_base --.size __ramdisk_base, 8 --__ramdisk_base: -- data8 0x0 --.global __ramdisk_size --.size __ramdisk_size, 8 --__ramdisk_size: -- data8 0x0 --.global __gp_value --.size __gp_value, 8 --__gp_value: -- data8 0x0 -+DECLARE_DATA8(__kernel_entry) -+DECLARE_DATA8(__ramdisk_base) -+DECLARE_DATA8(__ramdisk_size) -+DECLARE_DATA8(__command_line) -+DECLARE_DATA8(__command_line_len) -+DECLARE_DATA8(__efi_memmap_base) -+DECLARE_DATA8(__efi_memmap_size) -+DECLARE_DATA8(__loaded_segments) -+DECLARE_DATA8(__loaded_segments_num) -+ -+DECLARE_DATA8(__gp_value) -diff -puN /dev/null purgatory/arch/ia64/io.h ---- /dev/null 2006-07-13 05:14:41.629277080 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/io.h 2006-07-13 14:42:05.000000000 +0530 -@@ -0,0 +1,94 @@ -+#ifndef IO_H -+#define IO_H -+#define UNCACHED(x) (void *)((x)|(1UL<<63)) -+#define MF() asm volatile ("mf.a" ::: "memory") -+#define IO_SPACE_ENCODING(p) ((((p) >> 2) << 12) | (p & 0xfff)) -+ -+static inline void *io_addr (unsigned long port) -+{ -+ unsigned long offset; -+ unsigned long io_base; -+ asm volatile ("mov %0=ar.k0":"=r"(io_base)); -+ offset = IO_SPACE_ENCODING(port); -+ return UNCACHED(io_base | offset); -+} -+ -+static inline unsigned int inb (unsigned long port) -+{ -+ volatile unsigned char *addr = io_addr(port); -+ unsigned char ret; -+ ret = *addr; -+ MF(); -+ return ret; -+} -+ -+static inline unsigned int inw (unsigned long port) -+{ -+ volatile unsigned short *addr = io_addr(port); -+ unsigned short ret; -+ -+ ret = *addr; -+ MF(); -+ return ret; -+} -+ -+static inline unsigned int ia64_inl (unsigned long port) -+{ -+ volatile unsigned int *addr = __ia64_mk_io_addr(port); -+ unsigned int ret; -+ ret = *addr; -+ MF(); -+ return ret; -+} -+ -+static inline void outb (unsigned char val, unsigned long port) -+{ -+ volatile unsigned char *addr = io_addr(port); -+ -+ *addr = val; -+ MF(); -+} -+ -+static inline void outw (unsigned short val, unsigned long port) -+{ -+ volatile unsigned short *addr = io_addr(port); -+ -+ *addr = val; -+ MF(); -+} -+ -+static inline void outl (unsigned int val, unsigned long port) -+{ -+ volatile unsigned int *addr = io_addr(port); -+ -+ *addr = val; -+ MF(); -+} -+ -+ -+static inline unsigned char readb(const volatile void *addr) -+{ -+ return *(volatile unsigned char *) addr; -+} -+static inline unsigned short readw(const volatile void *addr) -+{ -+ return *(volatile unsigned short *) addr; -+} -+static inline unsigned int readl(const volatile void *addr) -+{ -+ return *(volatile unsigned int *) addr; -+} -+ -+static inline void writeb(unsigned char b, volatile void *addr) -+{ -+ *(volatile unsigned char *) addr = b; -+} -+static inline void writew(unsigned short b, volatile void *addr) -+{ -+ *(volatile unsigned short *) addr = b; -+} -+static inline void writel(unsigned int b, volatile void *addr) -+{ -+ *(volatile unsigned int *) addr = b; -+} -+#endif -diff -puN purgatory/arch/ia64/Makefile~kdump-ia64 purgatory/arch/ia64/Makefile ---- kexec-tools-1.101-kdump/purgatory/arch/ia64/Makefile~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/Makefile 2006-07-13 14:42:05.000000000 +0530 -@@ -5,5 +5,5 @@ PCFLAGS += -ffixed-r28 - PURGATORY_S_SRCS+= purgatory/arch/ia64/entry.S - PURGATORY_C_SRCS+= purgatory/arch/ia64/purgatory-ia64.c - PURGATORY_C_SRCS+= purgatory/arch/ia64/console-ia64.c --PURGATORY_C_SRCS+= -+PURGATORY_C_SRCS+= purgatory/arch/ia64/vga.c - -diff -puN purgatory/arch/ia64/purgatory-ia64.c~kdump-ia64 purgatory/arch/ia64/purgatory-ia64.c ---- kexec-tools-1.101-kdump/purgatory/arch/ia64/purgatory-ia64.c~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/purgatory-ia64.c 2006-07-13 14:42:05.000000000 +0530 -@@ -1,9 +1,47 @@ -+/* -+ * purgatory: setup code -+ * -+ * Copyright (C) 2005-2006 Zou Nan hai (nanhai.zou@intel.com) -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ - #include - #include - #include - #include "purgatory-ia64.h" - --#define PAGE_OFFSET 0xe000000000000000 -+#define PAGE_OFFSET 0xe000000000000000UL -+ -+#define EFI_PAGE_SHIFT 12 -+#define EFI_PAGE_SIZE (1UL<efi_memmap_base; -+ void *src = (void *)boot_param->efi_memmap; -+ unsigned long len = boot_param->efi_memmap_size; -+ unsigned long memdesc_size = boot_param->efi_memdesc_size; -+ uint64_t orig_type; -+ efi_memory_desc_t *md1, *md2; -+ void *p1, *p2, *src_end = src + len; -+ int i; -+ for (p1 = src, p2 = dest; p1 < src_end; -+ p1 += memdesc_size, p2 += memdesc_size) { -+ unsigned long mstart, mend; -+ md1 = p1; -+ md2 = p2; -+ if (md1->num_pages == 0) -+ continue; -+ mstart = md1->phys_addr; -+ mend = md1->phys_addr + (md1->num_pages -+ << EFI_PAGE_SHIFT); -+ switch (md1->type) { -+ case EFI_LOADER_DATA: -+ *md2 = *md1; -+ md2->type = EFI_CONVENTIONAL_MEMORY; -+ break; -+ default: -+ *md2 = *md1; -+ } -+ // segments are already sorted and aligned to 4K -+ orig_type = md2->type; -+ for (i = 0; i < params->loaded_segments_num; i++) { -+ struct loaded_segment *seg; -+ seg = ¶ms->loaded_segments[i]; -+ if (seg->start >= mstart && seg->start < mend) { -+ unsigned long start_pages, mid_pages, end_pages; -+ if (seg->end > mend) { -+ p1 += memdesc_size; -+ for(; p1 < src_end; -+ p1 += memdesc_size) { -+ md1 = p1; -+ /* TODO check contig and attribute here */ -+ mend = md1->phys_addr -+ + (md1->num_pages << EFI_PAGE_SHIFT); -+ if (seg->end < mend) -+ break; -+ } -+ } -+ start_pages = (seg->start - mstart) -+ >> EFI_PAGE_SHIFT; -+ mid_pages = (seg->end - seg->start) -+ >> EFI_PAGE_SHIFT; -+ end_pages = (mend - seg->end) -+ >> EFI_PAGE_SHIFT; -+ if (start_pages) { -+ md2->num_pages = start_pages; -+ p2 += memdesc_size; -+ md2 = p2; -+ *md2 = *md1; -+ } -+ md2->phys_addr = seg->start; -+ md2->num_pages = mid_pages; -+ md2->type = seg->reserved ? -+ EFI_UNUSABLE_MEMORY:EFI_LOADER_DATA; -+ if (end_pages) { -+ p2 += memdesc_size; -+ md2 = p2; -+ *md2 = *md1; -+ md2->phys_addr = seg->end; -+ md2->num_pages = end_pages; -+ md2->type = orig_type; -+ mstart = seg->end; -+ } else -+ break; -+ } -+ } -+ } -+ -+ boot_param->efi_memmap_size = p2 - dest; -+} -+ -+void -+flush_icache_range(char *start, unsigned long len) - { - unsigned long i; - for (i = 0;i < len; i += 32) -- asm volatile("fc.i %0"::"r"(start+i):"memory"); -+ asm volatile("fc.i %0"::"r"(start + i):"memory"); - asm volatile (";;sync.i;;":::"memory"); - asm volatile ("srlz.i":::"memory"); - } - - extern char __dummy_efi_function[], __dummy_efi_function_end[]; - --void ia64_env_setup(struct ia64_boot_param *boot_param, -- uint64_t command_line, uint64_t command_line_len, -- uint64_t ramdisk_base, uint64_t ramdisk_size) -+ -+void -+ia64_env_setup(struct ia64_boot_param *boot_param, -+ struct kexec_boot_params *params) - { - unsigned long len; - efi_system_table_t *systab; - efi_runtime_services_t *runtime; - unsigned long *set_virtual_address_map; -+ char *command_line = (char *)params->command_line; -+ uint64_t command_line_len = params->command_line_len; - - // patch efi_runtime->set_virtual_address_map to a - // dummy function - len = __dummy_efi_function_end - __dummy_efi_function; -- memcpy((char *)command_line + command_line_len, __dummy_efi_function, -- len); -+ memcpy(command_line + command_line_len, -+ __dummy_efi_function, len); - systab = (efi_system_table_t *)boot_param->efi_systab; - runtime = (efi_runtime_services_t *)PA(systab->runtime); - set_virtual_address_map = - (unsigned long *)PA(runtime->set_virtual_address_map); -- *(set_virtual_address_map)= -- (unsigned long)((char *)command_line + command_line_len); -- flush_icache_range((char *)command_line+command_line_len, len); -+ *(set_virtual_address_map) = -+ (unsigned long)(command_line + command_line_len); -+ flush_icache_range(command_line + command_line_len, len); -+ -+ patch_efi_memmap(params, boot_param); -+ -+ boot_param->efi_memmap = params->efi_memmap_base; - -- boot_param->command_line = command_line; -+ boot_param->command_line = params->command_line; - boot_param->console_info.orig_x = 0; - boot_param->console_info.orig_y = 0; -- boot_param->initrd_start = ramdisk_base; -- boot_param->initrd_size = ramdisk_size; -+ boot_param->initrd_start = params->ramdisk_base; -+ boot_param->initrd_size = params->ramdisk_size; - } - - /* This function can be used to execute after the SHA256 verification. */ -diff -puN purgatory/arch/ia64/purgatory-ia64.h~kdump-ia64 purgatory/arch/ia64/purgatory-ia64.h ---- kexec-tools-1.101-kdump/purgatory/arch/ia64/purgatory-ia64.h~kdump-ia64 2006-07-13 14:42:05.000000000 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/purgatory-ia64.h 2006-07-13 14:42:05.000000000 +0530 -@@ -1,6 +1,5 @@ - #ifndef PURGATORY_IA64_H - #define PURGATORY_IA64_H - --/* nothing yet */ -- -+void reset_vga(void); - #endif /* PURGATORY_IA64_H */ -diff -puN /dev/null purgatory/arch/ia64/vga.c ---- /dev/null 2006-07-13 05:14:41.629277080 +0530 -+++ kexec-tools-1.101-kdump-maneesh/purgatory/arch/ia64/vga.c 2006-07-13 14:42:05.000000000 +0530 -@@ -0,0 +1,143 @@ -+#include "io.h" -+void reset_vga(void) -+{ -+ /* Hello */ -+ inb(0x3da); -+ outb(0, 0x3c0); -+ -+ /* Sequencer registers */ -+ outw(0x0300, 0x3c4); -+ outw(0x0001, 0x3c4); -+ outw(0x0302, 0x3c4); -+ outw(0x0003, 0x3c4); -+ outw(0x0204, 0x3c4); -+ -+ /* Ensure CRTC regs 0-7 are unlocked by clearing bit 7 of CRTC[17] */ -+ outw(0x0e11, 0x3d4); -+ /* CRTC registers */ -+ outw(0x5f00, 0x3d4); -+ outw(0x4f01, 0x3d4); -+ outw(0x5002, 0x3d4); -+ outw(0x8203, 0x3d4); -+ outw(0x5504, 0x3d4); -+ outw(0x8105, 0x3d4); -+ outw(0xbf06, 0x3d4); -+ outw(0x1f07, 0x3d4); -+ outw(0x0008, 0x3d4); -+ outw(0x4f09, 0x3d4); -+ outw(0x200a, 0x3d4); -+ outw(0x0e0b, 0x3d4); -+ outw(0x000c, 0x3d4); -+ outw(0x000d, 0x3d4); -+ outw(0x010e, 0x3d4); -+ outw(0xe00f, 0x3d4); -+ outw(0x9c10, 0x3d4); -+ outw(0x8e11, 0x3d4); -+ outw(0x8f12, 0x3d4); -+ outw(0x2813, 0x3d4); -+ outw(0x1f14, 0x3d4); -+ outw(0x9615, 0x3d4); -+ outw(0xb916, 0x3d4); -+ outw(0xa317, 0x3d4); -+ outw(0xff18, 0x3d4); -+ -+ /* Graphic registers */ -+ outw(0x0000, 0x3ce); -+ outw(0x0001, 0x3ce); -+ outw(0x0002, 0x3ce); -+ outw(0x0003, 0x3ce); -+ outw(0x0004, 0x3ce); -+ outw(0x1005, 0x3ce); -+ outw(0x0e06, 0x3ce); -+ outw(0x0007, 0x3ce); -+ outw(0xff08, 0x3ce); -+ -+ /* Attribute registers */ -+ inb(0x3da); -+ outb(0x00, 0x3c0); -+ outb(0x00, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x01, 0x3c0); -+ outb(0x01, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x02, 0x3c0); -+ outb(0x02, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x03, 0x3c0); -+ outb(0x03, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x04, 0x3c0); -+ outb(0x04, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x05, 0x3c0); -+ outb(0x05, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x06, 0x3c0); -+ outb(0x14, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x07, 0x3c0); -+ outb(0x07, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x08, 0x3c0); -+ outb(0x38, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x09, 0x3c0); -+ outb(0x39, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x0a, 0x3c0); -+ outb(0x3a, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x0b, 0x3c0); -+ outb(0x3b, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x0c, 0x3c0); -+ outb(0x3c, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x0d, 0x3c0); -+ outb(0x3d, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x0e, 0x3c0); -+ outb(0x3e, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x0f, 0x3c0); -+ outb(0x3f, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x10, 0x3c0); -+ outb(0x0c, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x11, 0x3c0); -+ outb(0x00, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x12, 0x3c0); -+ outb(0x0f, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x13, 0x3c0); -+ outb(0x08, 0x3c0); -+ -+ inb(0x3da); -+ outb(0x14, 0x3c0); -+ outb(0x00, 0x3c0); -+ -+ /* Goodbye */ -+ inb(0x3da); -+ outb(0x20, 0x3c0); -+} -_ diff --git a/kexec-tools-1.101-ia64-load-offset.patch b/kexec-tools-1.101-ia64-load-offset.patch deleted file mode 100644 index c381a19..0000000 --- a/kexec-tools-1.101-ia64-load-offset.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ia64/crashdump-ia64.c.orig 2006-12-01 14:16:07.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/crashdump-ia64.c 2006-12-01 14:18:34.000000000 -0500 -@@ -28,7 +28,7 @@ - #include "crashdump-ia64.h" - - int memory_ranges = 0; --#define LOAD_OFFSET (0xa000000000000000UL + 0x100000000UL - (1UL<<26)) -+#define LOAD_OFFSET (0xa000000000000000UL + 0x100000000UL - kernel_code_start) - #define MAX_LINE 160 - /* Stores a sorted list of RAM memory ranges for which to create elf headers. - * A separate program header is created for backup region */ diff --git a/kexec-tools-1.101-ia64-noio-eat.patch b/kexec-tools-1.101-ia64-noio-eat.patch deleted file mode 100644 index 32fd6d7..0000000 --- a/kexec-tools-1.101-ia64-noio-eat.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2006-12-01 14:30:59.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-12-01 14:31:04.000000000 -0500 -@@ -128,7 +128,7 @@ - {"command-line", 1, 0, OPT_APPEND}, - {"append", 1, 0, OPT_APPEND}, - {"initrd", 1, 0, OPT_RAMDISK}, -- {"noio", 1, 0, OPT_NOIO}, -+ {"noio", 0, 0, OPT_NOIO}, - {0, 0, 0, 0}, - }; - diff --git a/kexec-tools-1.101-ia64-noio.patch b/kexec-tools-1.101-ia64-noio.patch deleted file mode 100644 index 45694cc..0000000 --- a/kexec-tools-1.101-ia64-noio.patch +++ /dev/null @@ -1,252 +0,0 @@ -On Thu, Sep 21, 2006 at 01:06:08PM +0800, Zou Nan hai wrote: -> SN platform support PIO in a different way to generic IA64 platform. It -> does not support most of the legacy I/O ports. -> -> Give an --noio option to kexec-tools to disable I/O in purgatory code. -> -> This patch also removed an unused io.h in kexec-tools. -> -> Signed-off-by: Zou Nan hai - -I have merged the following into kexec-tools-test. - --- -Horms - H: http://www.vergenet.net/~horms/ - W: http://www.valinux.co.jp/en/ - -From: Zou Nan hai -Date: 21 Sep 2006 13:06:08 +0800 -Subject: kexec-tools: --noio option to disable I/O in purgatory code. - -SN platform support PIO in a different way to generic IA64 platform. It -does not support most of the legacy I/O ports. - -Give an --noio option to kexec-tools to disable I/O in purgatory code. - -This patch also removed an unused io.h in kexec-tools. - -Signed-off-by: Zou Nan hai - -Edited to consistently use tabs instead of spaces for intentation, -remove one instance of trailing whitespace, and fix indentation -of noio line in options[]. - -Signed-off-by: Simon Horman - -diff -Nraup kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c -kexec-tools-1.101-fix/kexec/arch/ia64/kexec-elf-ia64.c ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-09-20 15:30:40.000000000 +0800 -+++ kexec-tools-1.101-fix/kexec/arch/ia64/kexec-elf-ia64.c 2006-09-21 15:12:20.000000000 +0800 -@@ -116,16 +116,19 @@ int elf_ia64_load(int argc, char **argv, - unsigned long command_line_base, ramdisk_base; - unsigned long efi_memmap_base, efi_memmap_size; - unsigned long boot_param_base; -+ unsigned long noio=0; - int result; - int opt; - char *efi_memmap_buf, *boot_param; - #define OPT_APPEND (OPT_ARCH_MAX+0) - #define OPT_RAMDISK (OPT_ARCH_MAX+1) -+#define OPT_NOIO (OPT_ARCH_MAX+2) - static const struct option options[] = { - KEXEC_ARCH_OPTIONS - {"command-line", 1, 0, OPT_APPEND}, - {"append", 1, 0, OPT_APPEND}, - {"initrd", 1, 0, OPT_RAMDISK}, -+ {"noio", 1, 0, OPT_NOIO}, - {0, 0, 0, 0}, - }; - -@@ -148,6 +151,9 @@ int elf_ia64_load(int argc, char **argv, - case OPT_RAMDISK: - ramdisk = optarg; - break; -+ case OPT_NOIO: /* disable PIO and MMIO in purgatory code*/ -+ noio = 1; -+ break; - } - } - command_line_len = 0; -@@ -196,6 +202,10 @@ int elf_ia64_load(int argc, char **argv, - boot_param = xmalloc(4096); - boot_param_base = add_buffer(info, boot_param, 4096, 4096, 4096, 0, - max_addr, -1); -+ -+ elf_rel_set_symbol(&info->rhdr, "__noio", -+ &noio, sizeof(long)); -+ - elf_rel_set_symbol(&info->rhdr, "__boot_param_base", - &boot_param_base, sizeof(long)); - -diff -Nraup kexec-tools-1.101/purgatory/arch/ia64/entry.S -kexec-tools-1.101-fix/purgatory/arch/ia64/entry.S ---- kexec-tools-1.101/purgatory/arch/ia64/entry.S 2006-09-20 15:30:40.000000000 +0800 -+++ kexec-tools-1.101-fix/purgatory/arch/ia64/entry.S 2006-09-21 15:11:36.000000000 +0800 -@@ -68,3 +68,4 @@ DECLARE_DATA8(__loaded_segments) - DECLARE_DATA8(__loaded_segments_num) - - DECLARE_DATA8(__gp_value) -+DECLARE_DATA8(__noio) -diff -Nraup kexec-tools-1.101/purgatory/arch/ia64/include/arch/io.h -kexec-tools-1.101-fix/purgatory/arch/ia64/include/arch/io.h ---- kexec-tools-1.101/purgatory/arch/ia64/include/arch/io.h 2006-09-20 15:29:29.000000000 +0800 -+++ kexec-tools-1.101-fix/purgatory/arch/ia64/include/arch/io.h 1970-01-01 08:00:00.000000000 +0800 -@@ -1,25 +0,0 @@ --#ifndef ARCH_IO_H --#define ARCH_IO_H -- --#include --/* Helper functions for directly doing I/O */ -- --extern inline uint8_t inb(void *port) --{ -- volatile unsigned char *addr = (unsigned char *)port; -- uint8_t result; -- -- result = *addr; -- asm volatile ("mf.a"::: "memory"); -- return result; --} -- --extern inline void outb (uint8_t value, void *port) --{ -- volatile unsigned char *addr = (unsigned char *)port; -- -- *addr = value; -- asm volatile ("mf.a"::: "memory"); --} -- --#endif /* ARCH_IO_H */ -diff -Nraup kexec-tools-1.101/purgatory/arch/ia64/io.h -kexec-tools-1.101-fix/purgatory/arch/ia64/io.h ---- kexec-tools-1.101/purgatory/arch/ia64/io.h 2006-09-20 15:29:29.000000000 +0800 -+++ kexec-tools-1.101-fix/purgatory/arch/ia64/io.h 2006-09-21 15:11:19.000000000 +0800 -@@ -3,7 +3,7 @@ - #define UNCACHED(x) (void *)((x)|(1UL<<63)) - #define MF() asm volatile ("mf.a" ::: "memory") - #define IO_SPACE_ENCODING(p) ((((p) >> 2) << 12) | (p & 0xfff)) -- -+extern long __noio; - static inline void *io_addr (unsigned long port) - { - unsigned long offset; -@@ -16,28 +16,34 @@ static inline void *io_addr (unsigned lo - static inline unsigned int inb (unsigned long port) - { - volatile unsigned char *addr = io_addr(port); -- unsigned char ret; -- ret = *addr; -- MF(); -+ unsigned char ret = 0; -+ if (!__noio) { -+ ret = *addr; -+ MF(); -+ } - return ret; - } - - static inline unsigned int inw (unsigned long port) - { - volatile unsigned short *addr = io_addr(port); -- unsigned short ret; -+ unsigned short ret = 0; - -- ret = *addr; -- MF(); -+ if (!__noio) { -+ ret = *addr; -+ MF(); -+ } - return ret; - } - --static inline unsigned int ia64_inl (unsigned long port) -+static inline unsigned int inl (unsigned long port) - { -- volatile unsigned int *addr = __ia64_mk_io_addr(port); -- unsigned int ret; -- ret = *addr; -- MF(); -+ volatile unsigned int *addr = io_addr(port); -+ unsigned int ret ; -+ if (!__noio) { -+ ret = *addr; -+ MF(); -+ } - return ret; - } - -@@ -45,50 +51,58 @@ static inline void outb (unsigned char v - { - volatile unsigned char *addr = io_addr(port); - -- *addr = val; -- MF(); -+ if (!__noio) { -+ *addr = val; -+ MF(); -+ } - } - - static inline void outw (unsigned short val, unsigned long port) - { - volatile unsigned short *addr = io_addr(port); - -- *addr = val; -- MF(); -+ if (!__noio) { -+ *addr = val; -+ MF(); -+ } - } - - static inline void outl (unsigned int val, unsigned long port) - { - volatile unsigned int *addr = io_addr(port); - -- *addr = val; -- MF(); -+ if (!__noio) { -+ *addr = val; -+ MF(); -+ } - } - -- - static inline unsigned char readb(const volatile void *addr) - { -- return *(volatile unsigned char *) addr; -+ return __noio ? 0 :*(volatile unsigned char *) addr; - } - static inline unsigned short readw(const volatile void *addr) - { -- return *(volatile unsigned short *) addr; -+ return __noio ? 0 :*(volatile unsigned short *) addr; - } - static inline unsigned int readl(const volatile void *addr) - { -- return *(volatile unsigned int *) addr; -+ return __noio ? 0 :*(volatile unsigned int *) addr; - } - - static inline void writeb(unsigned char b, volatile void *addr) - { -- *(volatile unsigned char *) addr = b; -+ if (!__noio) -+ *(volatile unsigned char *) addr = b; - } - static inline void writew(unsigned short b, volatile void *addr) - { -- *(volatile unsigned short *) addr = b; -+ if (!__noio) -+ *(volatile unsigned short *) addr = b; - } - static inline void writel(unsigned int b, volatile void *addr) - { -- *(volatile unsigned int *) addr = b; -+ if (!__noio) -+ *(volatile unsigned int *) addr = b; - } - #endif - diff --git a/kexec-tools-1.101-ia64-phdr-malloc.patch b/kexec-tools-1.101-ia64-phdr-malloc.patch deleted file mode 100644 index c3f1151..0000000 --- a/kexec-tools-1.101-ia64-phdr-malloc.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ia64/crashdump-ia64.c.orig 2006-11-14 13:38:45.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/crashdump-ia64.c 2006-11-14 14:52:34.000000000 -0500 -@@ -316,10 +316,14 @@ - int nr_ranges; - size_t size; - void *tmp; -+ long int nr_cpus; -+ if ((nr_cpus = sysconf(_SC_NPROCESSORS_CONF)) < 0) -+ return -1; - if (info->kexec_flags & KEXEC_ON_CRASH ) { - if (get_crash_memory_ranges(&mem_range, &nr_ranges) == 0) { -- size = sizeof(Elf64_Ehdr) + -- (nr_ranges + 1) * sizeof(Elf64_Phdr); -+ size = (sizeof(Elf64_Ehdr) + -+ ((nr_cpus +1) * sizeof(Elf64_Phdr)) + -+ ((nr_ranges + 1) * sizeof(Elf64_Phdr))); - size = (size + EFI_PAGE_SIZE - 1) & ~(EFI_PAGE_SIZE - 1); - tmp = xmalloc(size); - memset(tmp, 0, size); diff --git a/kexec-tools-1.101-ia64-tools.patch b/kexec-tools-1.101-ia64-tools.patch deleted file mode 100644 index 7ff7a44..0000000 --- a/kexec-tools-1.101-ia64-tools.patch +++ /dev/null @@ -1,808 +0,0 @@ ---- kexec-tools-1.101/Makefile.orig 2006-10-20 13:38:53.000000000 -0400 -+++ kexec-tools-1.101/Makefile 2006-10-20 13:39:08.000000000 -0400 -@@ -43,6 +43,7 @@ - PKGINCLUDEIR=$(INCLUDEDIR)/$(PACKAGE) - - MAN_PAGES:= kexec/kexec.8 -+MAN_PAGES+= kdump/kdump.8 - BINARIES_i386:= $(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test $(SBINDIR)/kdump - BINARIES_x86_64:=$(SBINDIR)/kexec $(PKGLIBDIR)/kexec_test - BINARIES:=$(SBINDIR)/kexec $(BINARIES_$(ARCH)) ---- /dev/null 2006-10-19 09:27:39.770809345 -0400 -+++ kexec-tools-1.101/kdump/kdump.8 2006-10-20 13:39:08.000000000 -0400 -@@ -0,0 +1,39 @@ -+.\" Hey, EMACS: -*- nroff -*- -+.\" First parameter, NAME, should be all caps -+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection -+.\" other parameters are allowed: see man(7), man(1) -+.TH KDUMP 8 "Jul 27, 2005" -+.\" Please adjust this date whenever revising the manpage. -+.\" -+.\" Some roff macros, for reference: -+.\" .nh disable hyphenation -+.\" .hy enable hyphenation -+.\" .ad l left justify -+.\" .ad b justify to both left and right margins -+.\" .nf disable filling -+.\" .fi enable filling -+.\" .br insert line break -+.\" .sp insert n+1 empty lines -+.\" for manpage-specific macros, see man(7) -+.SH NAME -+kdump \- This is just a placeholder until real man page has been written -+.SH SYNOPSIS -+.B kdump -+.RI [ options ] " start_address" ... -+.SH DESCRIPTION -+.PP -+.\" TeX users may be more comfortable with the \fB\fP and -+.\" \fI\fP escape sequences to invode bold face and italics, -+.\" respectively. -+\fBkdump\fP does not have a man page yet. -+.SH OPTIONS -+.\"These programs follow the usual GNU command line syntax, with long -+.\"options starting with two dashes (`-'). -+.\"A summary of options is included below. -+.\"For a complete description, see the Info files. -+.SH SEE ALSO -+.SH AUTHOR -+kdump was written by Eric Biederman. -+.PP -+This manual page was written by Khalid Aziz , -+for the Debian project (but may be used by others). ---- kexec-tools-1.101/purgatory/arch/ia64/Makefile.orig 2004-12-20 17:44:22.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/ia64/Makefile 2006-10-20 13:39:08.000000000 -0400 -@@ -1,8 +1,8 @@ - # - # Purgatory ia64 - # -- --PURGATORY_S_SRCS+= -+PCFLAGS += -ffixed-r28 -+PURGATORY_S_SRCS+= purgatory/arch/ia64/entry.S - PURGATORY_C_SRCS+= purgatory/arch/ia64/purgatory-ia64.c - PURGATORY_C_SRCS+= purgatory/arch/ia64/console-ia64.c - PURGATORY_C_SRCS+= ---- /dev/null 2006-10-19 09:27:39.770809345 -0400 -+++ kexec-tools-1.101/purgatory/arch/ia64/include/arch/io.h 2006-10-20 13:39:08.000000000 -0400 -@@ -0,0 +1,25 @@ -+#ifndef ARCH_IO_H -+#define ARCH_IO_H -+ -+#include -+/* Helper functions for directly doing I/O */ -+ -+extern inline uint8_t inb(void *port) -+{ -+ volatile unsigned char *addr = (unsigned char *)port; -+ uint8_t result; -+ -+ result = *addr; -+ asm volatile ("mf.a"::: "memory"); -+ return result; -+} -+ -+extern inline void outb (uint8_t value, void *port) -+{ -+ volatile unsigned char *addr = (unsigned char *)port; -+ -+ *addr = value; -+ asm volatile ("mf.a"::: "memory"); -+} -+ -+#endif /* ARCH_IO_H */ ---- /dev/null 2006-10-19 09:27:39.770809345 -0400 -+++ kexec-tools-1.101/purgatory/arch/ia64/entry.S 2006-10-20 13:39:08.000000000 -0400 -@@ -0,0 +1,85 @@ -+/* -+ * purgatory: setup code -+ * -+ * Copyright (C) 2005 Zou Nan hai (nanhai.zou@intel.com) -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+.global __dummy_efi_function -+.align 32 -+.proc __dummy_efi_function -+__dummy_efi_function: -+ mov r8=r0;; -+ br.ret.sptk.many rp;; -+.global __dummy_efi_function_end -+__dummy_efi_function_end: -+.endp __dummy_efi_function -+ -+.global purgatory_start -+.align 32 -+.proc purgatory_start -+purgatory_start: -+ movl r2=__gp_value;; -+ ld8 gp=[r2];; -+ br.call.sptk.many b0=purgatory -+ ;; -+ alloc r2 = ar.pfs, 0, 0, 5, 0 -+ ;; -+ mov out0=r28 -+ -+ movl r2=__command_line;; -+ ld8 out1=[r2];; -+ movl r2=__command_line_len;; -+ ld8 out2=[r2];; -+ movl r2=__ramdisk_base;; -+ ld8 out3=[r2];; -+ movl r2=__ramdisk_size;; -+ ld8 out4=[r2];; -+ br.call.sptk.many b0=ia64_env_setup -+ movl r10=__kernel_entry;; -+ ld8 r14=[r10];; -+ mov b6=r14;; -+ mov ar.lc=r0 -+ mov ar.ec=r0 -+ cover;; -+ invala;; -+ br.call.sptk.many b0=b6 -+.endp purgatory_start -+ -+.align 32 -+.global __kernel_entry -+.size __kernel_entry, 8 -+__kernel_entry: -+ data8 0x0 -+.global __command_line -+.size __command_line, 8 -+__command_line: -+ data8 0x0 -+.global __command_line_len -+.size __command_line_len, 8 -+__command_line_len: -+ data8 0x0 -+.global __ramdisk_base -+.size __ramdisk_base, 8 -+__ramdisk_base: -+ data8 0x0 -+.global __ramdisk_size -+.size __ramdisk_size, 8 -+__ramdisk_size: -+ data8 0x0 -+.global __gp_value -+.size __gp_value, 8 -+__gp_value: -+ data8 0x0 ---- kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c.orig 2006-10-20 13:38:53.000000000 -0400 -+++ kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c 2006-10-20 13:39:08.000000000 -0400 -@@ -1,10 +1,116 @@ - #include -+#include -+#include - #include "purgatory-ia64.h" - -+#define PAGE_OFFSET 0xe000000000000000 -+ -+typedef struct { -+ uint64_t signature; -+ uint32_t revision; -+ uint32_t headersize; -+ uint32_t crc32; -+ uint32_t reserved; -+} efi_table_hdr_t; -+ -+typedef struct { -+ efi_table_hdr_t hdr; -+ unsigned long get_time; -+ unsigned long set_time; -+ unsigned long get_wakeup_time; -+ unsigned long set_wakeup_time; -+ unsigned long set_virtual_address_map; -+ unsigned long convert_pointer; -+ unsigned long get_variable; -+ unsigned long get_next_variable; -+ unsigned long set_variable; -+ unsigned long get_next_high_mono_count; -+ unsigned long reset_system; -+} efi_runtime_services_t; -+ -+typedef struct { -+ efi_table_hdr_t hdr; -+ unsigned long fw_vendor; /* physical addr of CHAR16 vendor string -+ */ -+ uint32_t fw_revision; -+ unsigned long con_in_handle; -+ unsigned long con_in; -+ unsigned long con_out_handle; -+ unsigned long con_out; -+ unsigned long stderr_handle; -+ unsigned long stderr; -+ unsigned long runtime; -+ unsigned long boottime; -+ unsigned long nr_tables; -+ unsigned long tables; -+} efi_system_table_t; -+ -+struct ia64_boot_param { -+ uint64_t command_line; /* physical address of command line arguments */ -+ uint64_t efi_systab; /* physical address of EFI system table */ -+ uint64_t efi_memmap; /* physical address of EFI memory map */ -+ uint64_t efi_memmap_size; /* size of EFI memory map */ -+ uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */ -+ uint32_t efi_memdesc_version; /* memory descriptor version */ -+ struct { -+ uint16_t num_cols; /* number of columns on console output device */ -+ uint16_t num_rows; /* number of rows on console output device */ -+ uint16_t orig_x; /* cursor's x position */ -+ uint16_t orig_y; /* cursor's y position */ -+ } console_info; -+ uint64_t fpswa; /* physical address of the fpswa interface */ -+ uint64_t initrd_start; -+ uint64_t initrd_size; -+}; -+ - void setup_arch(void) - { - /* Nothing for now */ - } -+inline unsigned long PA(unsigned long addr) -+{ -+ return addr - PAGE_OFFSET; -+} -+ -+void flush_icache_range(char *start, unsigned long len) -+{ -+ unsigned long i; -+ for (i = 0;i < len; i += 32) -+ asm volatile("fc.i %0"::"r"(start+i):"memory"); -+ asm volatile (";;sync.i;;":::"memory"); -+ asm volatile ("srlz.i":::"memory"); -+} -+ -+extern char __dummy_efi_function[], __dummy_efi_function_end[]; -+ -+void ia64_env_setup(struct ia64_boot_param *boot_param, -+ uint64_t command_line, uint64_t command_line_len, -+ uint64_t ramdisk_base, uint64_t ramdisk_size) -+{ -+ unsigned long len; -+ efi_system_table_t *systab; -+ efi_runtime_services_t *runtime; -+ unsigned long *set_virtual_address_map; -+ -+ // patch efi_runtime->set_virtual_address_map to a -+ // dummy function -+ len = __dummy_efi_function_end - __dummy_efi_function; -+ memcpy((char *)command_line + command_line_len, __dummy_efi_function, -+ len); -+ systab = (efi_system_table_t *)boot_param->efi_systab; -+ runtime = (efi_runtime_services_t *)PA(systab->runtime); -+ set_virtual_address_map = -+ (unsigned long *)PA(runtime->set_virtual_address_map); -+ *(set_virtual_address_map)= -+ (unsigned long)((char *)command_line + command_line_len); -+ flush_icache_range((char *)command_line+command_line_len, len); -+ -+ boot_param->command_line = command_line; -+ boot_param->console_info.orig_x = 0; -+ boot_param->console_info.orig_y = 0; -+ boot_param->initrd_start = ramdisk_base; -+ boot_param->initrd_size = ramdisk_size; -+} - - /* This function can be used to execute after the SHA256 verification. */ - void post_verification_setup_arch(void) ---- kexec-tools-1.101/kexec/Makefile.orig 2006-10-20 13:38:53.000000000 -0400 -+++ kexec-tools-1.101/kexec/Makefile 2006-10-20 13:39:08.000000000 -0400 -@@ -28,6 +28,7 @@ - KEXEC_OBJS:= $(KEXEC_C_OBJS) $(KEXEC_S_OBJS) - KEXEC_DEPS:= $(KEXEC_C_DEPS) $(KEXEC_S_DEPS) - KEXEC:= $(SBINDIR)/kexec -+KEXEC_MANPAGE:= $(MANDIR)/man8/kexec.8 - - include $(KEXEC_DEPS) - -@@ -51,6 +52,9 @@ - mkdir -p $(@D) - $(CC) $(KCFLAGS) -o $@ $(KEXEC_OBJS) $(UTIL_LIB) $(LIBS) - -+$(KEXEC_MANPAGE): kexec/kexec.8 -+ $(MKDIR) -p $(MANDIR)/man8 -+ cp kexec/kexec.8 $(KEXEC_MANPAGE) - echo:: - @echo "KEXEC_C_SRCS $(KEXEC_C_SRCS)" - @echo "KEXEC_C_DEPS $(KEXEC_C_DEPS)" ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h.orig 2004-12-19 18:52:38.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.h 2006-10-20 13:39:08.000000000 -0400 -@@ -1,6 +1,8 @@ - #ifndef KEXEC_IA64_H - #define KEXEC_IA64_H - -+#define MAX_MEMORY_RANGES 1024 -+ - int elf_ia64_probe(const char *buf, off_t len); - int elf_ia64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-rel-ia64.c.orig 2004-12-20 17:43:23.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-rel-ia64.c 2006-10-20 13:39:08.000000000 -0400 -@@ -1,8 +1,14 @@ -+/* Most of the code in this file is -+ * based on arch/ia64/kernel/module.c in Linux kernel -+ */ -+ - #include - #include - #include "../../kexec.h" - #include "../../kexec-elf.h" - -+#define MAX_LTOFF ((uint64_t) (1 << 22)) -+ - int machine_verify_elf_rel(struct mem_ehdr *ehdr) - { - if (ehdr->ei_data != ELFDATA2LSB) { -@@ -17,12 +23,40 @@ - return 1; - } - -+static void -+ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val) -+{ -+ uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16); -+# define insn_mask ((1UL << 41) - 1) -+ unsigned long shift; -+ -+ b0 = b[0]; b1 = b[1]; -+ shift = 5 + 41 * (insn_addr % 16); /* 5 bits of template, then 3 x 41-bit instructions */ -+ if (shift >= 64) { -+ m1 = mask << (shift - 64); -+ v1 = val << (shift - 64); -+ } else { -+ m0 = mask << shift; m1 = mask >> (64 - shift); -+ v0 = val << shift; v1 = val >> (64 - shift); -+ b[0] = (b0 & ~m0) | (v0 & m0); -+ } -+ b[1] = (b1 & ~m1) | (v1 & m1); -+} -+ -+static inline uint64_t -+bundle (const uint64_t insn) -+{ -+ return insn & ~0xfUL; -+} -+ - void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, - void *location, unsigned long address, unsigned long value) - { -+ uint64_t gp_value = ehdr->rel_addr + 0x200000; - switch(r_type) { - case R_IA64_NONE: - break; -+ case R_IA64_SEGREL64LSB: - case R_IA64_DIR64LSB: - *((uint64_t *)location) = value; - break; -@@ -31,15 +65,67 @@ - if (value != *((uint32_t *)location)) - goto overflow; - break; -- case R_IA64_PCREL21B: -+ case R_IA64_IMM64: -+ ia64_patch((uint64_t)location, 0x01fffefe000UL, -+ /* bit 63 -> 36 */ -+ (((value & 0x8000000000000000UL) >> 27) -+ /* bit 21 -> 21 */ -+ | ((value & 0x0000000000200000UL) << 0) -+ /* bit 16 -> 22 */ -+ | ((value & 0x00000000001f0000UL) << 6) -+ /* bit 7 -> 27 */ -+ | ((value & 0x000000000000ff80UL) << 20) -+ /* bit 0 -> 13 */ -+ | ((value & 0x000000000000007fUL) << 13))); -+ ia64_patch((uint64_t)location - 1, 0x1ffffffffffUL, value>>22); -+ break; -+ case R_IA64_IMM22: -+ if (value + (1 << 21) >= (1 << 22)) -+ die("value out of IMM22 range\n"); -+ ia64_patch((uint64_t)location, 0x01fffcfe000UL, -+ /* bit 21 -> 36 */ -+ (((value & 0x200000UL) << 15) -+ /* bit 16 -> 22 */ -+ | ((value & 0x1f0000UL) << 6) -+ /* bit 7 -> 27 */ -+ | ((value & 0x00ff80UL) << 20) -+ /* bit 0 -> 13 */ -+ | ((value & 0x00007fUL) << 13) )); -+ break; -+ case R_IA64_PCREL21B: { -+ uint64_t delta = ((int64_t)value - (int64_t)address)/16; -+ if (delta + (1 << 20) >= (1 << 21)) -+ die("value out of IMM21B range\n"); -+ value = ((int64_t)(value - bundle(address)))/16; -+ ia64_patch((uint64_t)location, 0x11ffffe000UL, -+ (((value & 0x100000UL) << 16) /* bit 20 -> 36 */ -+ | ((value & 0x0fffffUL) << 13) /* bit 0 -> 13 */)); -+ } -+ break; -+ case R_IA64_LTOFF22X: -+ if (value - gp_value + MAX_LTOFF/2 >= MAX_LTOFF) -+ die("value out of gp relative range"); -+ value -= gp_value; -+ ia64_patch((uint64_t)location, 0x01fffcfe000UL, -+ (((value & 0x200000UL) << 15) /* bit 21 -> 36 */ -+ |((value & 0x1f0000UL) << 6) /* bit 16 -> 22 */ -+ |((value & 0x00ff80UL) << 20) /* bit 7 -> 27 */ -+ |((value & 0x00007fUL) << 13) /* bit 0 -> 13 */)); -+ break; -+ case R_IA64_LDXMOV: -+ if (value - gp_value + MAX_LTOFF/2 >= MAX_LTOFF) -+ die("value out of gp relative range"); -+ ia64_patch((uint64_t)location, 0x1fff80fe000UL, 0x10000000000UL); -+ break; - case R_IA64_LTOFF22: -- case R_IA64_SEGREL64LSB: -+ - default: -- die("Unknown rela relocation: %lu\n", r_type); -+ die("Unknown rela relocation: 0x%lx 0x%lx\n", -+ r_type, address); - break; - } - return; -- overflow: -+overflow: - die("overflow in relocation type %lu val %Lx\n", -- r_type, value); -+ r_type, value); - } ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2004-12-21 15:01:37.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2006-10-20 13:39:08.000000000 -0400 -@@ -6,6 +6,7 @@ - * Copyright (C) 2004 Silicon Graphics, Inc. - * Jesse Barnes - * Copyright (C) 2004 Khalid Aziz Hewlett Packard Co -+ * Copyright (C) 2005 Zou Nan hai Intel Corp - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -34,6 +35,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -74,23 +76,29 @@ - { - printf( - " --command-line=STRING Set the kernel command line to STRING.\n" -- " --append=STRING Set the kernel command line to STRING.\n"); -+ " --append=STRING Set the kernel command line to STRING.\n" -+ " --initrd=FILE Use FILE as the kernel's initial ramdisk.\n"); - } - - int elf_ia64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info) - { - struct mem_ehdr ehdr; -- const char *command_line; -- int command_line_len; -- unsigned long entry, max_addr; -+ const char *command_line, *ramdisk=0; -+ char *ramdisk_buf = NULL; -+ off_t ramdisk_size = 0; -+ unsigned long command_line_len; -+ unsigned long entry, max_addr, gp_value; -+ unsigned command_line_base, ramdisk_base; - int result; - int opt; - #define OPT_APPEND (OPT_ARCH_MAX+0) -+#define OPT_RAMDISK (OPT_ARCH_MAX+1) - static const struct option options[] = { - KEXEC_ARCH_OPTIONS - {"command-line", 1, 0, OPT_APPEND}, - {"append", 1, 0, OPT_APPEND}, -+ {"initrd", 1, 0, OPT_RAMDISK}, - {0, 0, 0, 0}, - }; - -@@ -110,11 +118,14 @@ - case OPT_APPEND: - command_line = optarg; - break; -+ case OPT_RAMDISK: -+ ramdisk = optarg; -+ break; - } - } - command_line_len = 0; - if (command_line) { -- command_line_len = strlen(command_line) + 1; -+ command_line_len = strlen(command_line) + 16; - } - - /* Parse the Elf file */ -@@ -129,13 +140,46 @@ - - /* Load the Elf data */ - result = elf_exec_load(&ehdr, info); -- free_elf_info(&ehdr); - if (result < 0) { - fprintf(stderr, "ELF load failed\n"); -+ free_elf_info(&ehdr); - return result; - } -+ -+ -+ /* Load the setup code */ -+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -+ 0x80000, ULONG_MAX, 1); -+ -+ if (command_line_len) { -+ char *cmdline = xmalloc(command_line_len); -+ strcpy(cmdline, command_line); -+ command_line_len = (command_line_len + 15)&(~15); -+ elf_rel_set_symbol(&info->rhdr, "__command_line_len", -+ &command_line_len, sizeof(long)); -+ command_line_base = add_buffer(info, cmdline, -+ command_line_len, command_line_len, -+ 16, 0, max_addr, 1); -+ elf_rel_set_symbol(&info->rhdr, "__command_line", -+ &command_line_base, sizeof(long)); -+ } - -- /* For now we don't have arguments to pass :( */ -- info->entry = (void *)entry; -+ if (ramdisk) { -+ ramdisk_buf = slurp_file(ramdisk, &ramdisk_size); -+ ramdisk_base = add_buffer(info, ramdisk_buf, ramdisk_size, -+ ramdisk_size, -+ getpagesize(), 0, max_addr, 1); -+ elf_rel_set_symbol(&info->rhdr, "__ramdisk_base", -+ &ramdisk_base, sizeof(long)); -+ elf_rel_set_symbol(&info->rhdr, "__ramdisk_size", -+ &ramdisk_size, sizeof(long)); -+ } -+ -+ gp_value = info->rhdr.rel_addr + 0x200000; -+ elf_rel_set_symbol(&info->rhdr, "__gp_value", &gp_value, -+ sizeof(gp_value)); -+ -+ elf_rel_set_symbol(&info->rhdr, "__kernel_entry", &entry, sizeof(entry)); -+ free_elf_info(&ehdr); - return 0; - } ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c.orig 2006-10-20 13:38:53.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2006-10-20 13:39:08.000000000 -0400 -@@ -27,42 +27,87 @@ - #include - #include - #include -+#include - #include - #include "../../kexec.h" - #include "../../kexec-syscall.h" - #include "kexec-ia64.h" - #include - --#define MAX_MEMORY_RANGES 64 - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - - /* Return a sorted list of available memory ranges. */ - int get_memory_ranges(struct memory_range **range, int *ranges, - unsigned long kexec_flags) - { -- int memory_ranges; -- /* -- * /proc/iomem on ia64 does not show where all memory is. If -- * that is fixed up, we can make use of that to validate -- * the memory range kernel will be loade din. Until then..... -- * -- Khalid Aziz -- */ -- -- /* Note that the ia64 architecture mandates all systems will -- * have at least 64MB at 0-64M. The SGI altix does not follow -- * that restriction, but a reasonable guess is better than nothing -- * at all. -- * -- Eric Biederman -- */ -- fprintf(stderr, "Warning assuming memory at 0-64MB is present\n"); -- memory_ranges = 0; -- memory_range[memory_ranges].start = 0x00010000; -- memory_range[memory_ranges].end = 0x10000000; -- memory_range[memory_ranges].type = RANGE_RAM; -- memory_ranges++; -- *range = memory_range; -- *ranges = memory_ranges; -- return 0; -+ const char iomem[]= "/proc/iomem"; -+ int memory_ranges = 0; -+ char line[MAX_LINE]; -+ FILE *fp; -+ fp = fopen(iomem, "r"); -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", -+ iomem, strerror(errno)); -+ return -1; -+ } -+ -+ while(fgets(line, sizeof(line), fp) != 0) { -+ unsigned long start, end; -+ char *str; -+ int type; -+ int consumed; -+ int count; -+ if (memory_ranges >= MAX_MEMORY_RANGES) -+ break; -+ count = sscanf(line, "%lx-%lx : %n", -+ &start, &end, &consumed); -+ if (count != 2) -+ continue; -+ str = line + consumed; -+ end = end + 1; -+ if (memcmp(str, "System RAM\n", 11) == 0) { -+ type = RANGE_RAM; -+ } -+ else if (memcmp(str, "reserved\n", 9) == 0) { -+ type = RANGE_RESERVED; -+ } -+ else if (memcmp(str, "Crash kernel\n", 13) == 0) { -+ /* Redefine the memory region boundaries if kernel -+ * exports the limits and if it is panic kernel. -+ * Override user values only if kernel exported -+ * values are subset of user defined values. -+ */ -+ -+ if (kexec_flags & KEXEC_ON_CRASH) { -+ if (start > mem_min) -+ mem_min = start; -+ if (end < mem_max) -+ mem_max = end; -+ } -+ continue; -+ } else -+ continue; -+ /* -+ * Check if this memory range can be coalesced with -+ * the previous range -+ */ -+ if ((memory_ranges > 0) && -+ (start == memory_range[memory_ranges-1].end) && -+ (type == memory_range[memory_ranges-1].type)) { -+ memory_range[memory_ranges-1].end = end; -+ } -+ else { -+ memory_range[memory_ranges].start = start; -+ memory_range[memory_ranges].end = end; -+ memory_range[memory_ranges].type = type; -+ memory_ranges++; -+ } -+ } -+ fclose(fp); -+ *range = memory_range; -+ *ranges = memory_ranges; -+ -+ return 0; - } - - /* Supported file types and callbacks */ -@@ -76,9 +121,6 @@ - { - } - --static struct { --} arch_options = { --}; - int arch_process_options(int argc, char **argv) - { - static const struct option options[] = { -@@ -88,6 +130,12 @@ - static const char short_options[] = KEXEC_ARCH_OPT_STR; - int opt; - -+ /* execute from monarch processor */ -+ cpu_set_t affinity; -+ CPU_ZERO(&affinity); -+ CPU_SET(0, &affinity); -+ sched_setaffinity(0, sizeof(affinity), &affinity); -+ - opterr = 0; /* Don't complain about unrecognized options here */ - while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { - switch(opt) { -@@ -113,10 +161,7 @@ - } - if (strcmp(utsname.machine, "ia64") == 0) - { -- /* For compatibility with older patches -- * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_IA64 here. -- */ -- info->kexec_flags |= KEXEC_ARCH_DEFAULT; -+ info->kexec_flags |= KEXEC_ARCH_IA_64; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", ---- kexec-tools-1.101/kexec/kexec.8.orig 2004-12-19 17:27:31.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec.8 2006-10-20 13:39:08.000000000 -0400 -@@ -2,7 +2,7 @@ - .\" First parameter, NAME, should be all caps - .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection - .\" other parameters are allowed: see man(7), man(1) --.TH KEXEC-TOOLS 8 "October 13, 2004" -+.TH KEXEC 8 "October 13, 2004" - .\" Please adjust this date whenever revising the manpage. - .\" - .\" Some roff macros, for reference: -@@ -16,30 +16,60 @@ - .\" .sp insert n+1 empty lines - .\" for manpage-specific macros, see man(7) - .SH NAME --kexec-tools \- Tool to load a kernel for warm reboot and initiate a warm reboot -+kexec \- Tool to load a kernel for warm reboot and initiate a warm reboot - .SH SYNOPSIS --.B kexec-tools -+.B kexec - .RI [ options ] " files" ... - .SH DESCRIPTION - .PP - .\" TeX users may be more comfortable with the \fB\fP and - .\" \fI\fP escape sequences to invode bold face and italics, - .\" respectively. --\fBkexec-tools\fP does not have a man page yet. Please use "kexec -h" for help. -+\fBkexec\fP allows one to load another kernel from the currently running -+Linux kernel. Normally one would load a kernel, and possibly an initial -+ramdisk, into the currently running kernel using kexec and then initiate -+a warm reboot by executing kexec again with appropriate option. - .SH OPTIONS - These programs follow the usual GNU command line syntax, with long - options starting with two dashes (`-'). - A summary of options is included below. --For a complete description, see the Info files. - .TP - .B \-h, \-\-help - Show summary of options. - .TP - .B \-v, \-\-version - Show version of program. --.SH SEE ALSO -+.TP -+.B \-f, \-\-force -+Force an immediate kexec without calling shutdown. -+.TP -+.B \-x, \-\-no-ifdown -+Don't bring down network interfaces. (if used, must be last option specified) -+.TP -+.B \-l, \-\-load -+Load the new kernel into the current kernel. -+.TP -+.B \-p, \-\-load-panic -+Load the new kernel for use on panic. -+.TP -+.B \-u, \-\-unload -+Unload the current kexec target kernel. -+.TP -+.B \-e, \-\-exec -+Execute a currently loaded kernel. -+.TP -+.B \-t, \-\-type=TYPE -+Specify the new kernel is of this type. -+.TP -+.B \-\-mem\-min= -+Specify the lowest memory addres to load code into. -+.TP -+.B \-\-mem\-max= -+Specify the highest memory addres to load code into. -+.TP -+There may be additional options supported on individual architectures. Use --help option to see those options. - .SH AUTHOR --kexec-tools was written by Eric Biederman. -+kexec was written by Eric Biederman. - .PP --This manual page was written by Khalid Aziz , -+This manual page was written by Khalid Aziz , - for the Debian project (but may be used by others). diff --git a/kexec-tools-1.101-ifdown.patch b/kexec-tools-1.101-ifdown.patch deleted file mode 100644 index 28111aa..0000000 --- a/kexec-tools-1.101-ifdown.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- kexec-tools-1.101/kexec/kexec.c.orig1 2006-10-13 14:01:39.000000000 -0400 -+++ kexec-tools-1.101/kexec/kexec.c 2006-10-13 14:10:28.000000000 -0400 -@@ -698,6 +698,19 @@ void usage(void) - printf("\n"); - } - -+static int kexec_loaded(void) -+{ -+ int ret; -+ FILE *fp; -+ -+ fp = fopen("/sys/kernel/kexec_loaded", "r"); -+ if (fp == NULL) -+ return -1; -+ fscanf(fp, "%d", &ret); -+ fclose(fp); -+ return ret; -+} -+ - int main(int argc, char *argv[]) - { - int do_load = 1; -@@ -801,6 +814,10 @@ int main(int argc, char *argv[]) - if (do_load && (result == 0)) { - result = my_load(type, fileind, argc, argv, kexec_flags); - } -+ /* Don't shutdown unless there is something to reboot to! */ -+ if ((result == 0) && (do_shutdown || do_exec) && !kexec_loaded()) { -+ die("Nothing has been loaded!\n"); -+ } - if ((result == 0) && do_shutdown) { - result = my_shutdown(); - } diff --git a/kexec-tools-1.101-kdump.patch b/kexec-tools-1.101-kdump.patch deleted file mode 100644 index ac75fbf..0000000 --- a/kexec-tools-1.101-kdump.patch +++ /dev/null @@ -1,5943 +0,0 @@ -diff -urNp -X dontdiff kexec-tools-1.101/configure kexec-tools-1.101-kdump/configure ---- kexec-tools-1.101/configure 2005-02-16 18:07:44.000000000 +0530 -+++ kexec-tools-1.101-kdump/configure 2006-02-22 11:30:09.912285648 +0530 -@@ -1384,12 +1384,18 @@ case $host_cpu in - powerpc ) - host_cpu="ppc" - ;; -+ powerpc64 ) -+ host_cpu="ppc64" -+ ;; -+ s390x ) -+ host_cpu="s390" -+ ;; - * ) - host_cpu="$host_cpu" - ;; - esac - case $host_cpu in -- i386|ppc|x86_64|alpha|ppc64|ia64) -+ i386|ppc|x86_64|alpha|ppc64|ia64|s390) - ;; - * ) - { { echo "$as_me:$LINENO: error: unsupported architecture $host_cpu" >&5 -@@ -1406,6 +1412,12 @@ if test "${host_alias}" ; then - fi - EXTRA_CFLAGS="" - -+# Check whether ppc64. Add -m64 for building 64-bit binary -+# Add -mcall-aixdesc to generate dot-symbols as in gcc 3.3.3 -+if test "$ARCH" = ppc64; then -+ EXTRA_CFLAGS="$EXTRA_CFLAGS -m64 -mcall-aixdesc" -+fi; -+ - # Check whether --with-objdir or --without-objdir was given. - if test "${with_objdir+set}" = set; then - withval="$with_objdir" -@@ -1421,7 +1433,6 @@ if test "${with_gamecube+set}" = set; th - EXTRA_CFLAGS="$EXTRA_CFLAGS -DCONFIG_GAMECUBE=1" - fi; - -- - # Check whether --with-zlib or --without-zlib was given. - if test "${with_zlib+set}" = set; then - withval="$with_zlib" -diff -urNp -X dontdiff kexec-tools-1.101/configure.ac kexec-tools-1.101-kdump/configure.ac ---- kexec-tools-1.101/configure.ac 2005-01-09 07:06:57.000000000 +0530 -+++ kexec-tools-1.101-kdump/configure.ac 2006-02-22 11:30:08.809453304 +0530 -@@ -25,12 +25,18 @@ case $host_cpu in - powerpc ) - host_cpu="ppc" - ;; -+ powerpc64 ) -+ host_cpu="ppc64" -+ ;; -+ s390x ) -+ host_cpu="s390" -+ ;; - * ) - host_cpu="$host_cpu" - ;; - esac - case $host_cpu in -- i386|ppc|x86_64|alpha|ppc64|ia64) -+ i386|ppc|x86_64|alpha|ppc64|ia64|s390) - ;; - * ) - AC_MSG_ERROR([ unsupported architecture $host_cpu]) -@@ -45,6 +51,13 @@ if test "${host_alias}" ; then - OBJDIR="$OBJDIR-${host_alias}" - fi - EXTRA_CFLAGS="" -+ -+# Check whether ppc64. Add -m64 for building 64-bit binary -+# Add -mcall-aixdesc to generate dot-symbols as in gcc 3.3.3 -+if test "$ARCH" = ppc64; then -+ EXTRA_CFLAGS="$EXTRA_CFLAGS -m64 -mcall-aixdesc" -+fi; -+ - AC_ARG_WITH([objdir], AC_HELP_STRING([--with-objdir=],[select directory for object files]), - [ OBJDIR="$withval" ], [ OBJDIR="$OBJDIR" ]) - -diff -urNp -X dontdiff kexec-tools-1.101/kdump/kdump.c kexec-tools-1.101-kdump/kdump/kdump.c ---- kexec-tools-1.101/kdump/kdump.c 2005-02-06 07:28:15.000000000 +0530 -+++ kexec-tools-1.101-kdump/kdump/kdump.c 2006-02-22 11:30:11.080108112 +0530 -@@ -54,7 +54,7 @@ static void *xmalloc(size_t size) - result = malloc(size); - if (result == NULL) { - fprintf(stderr, "malloc of %u bytes failed: %s\n", -- size, strerror(errno)); -+ (unsigned int)size, strerror(errno)); - exit(7); - } - return result; -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c kexec-tools-1.101-kdump/kexec/arch/i386/crashdump-x86.c ---- kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/crashdump-x86.c 2006-02-22 11:30:01.525560624 +0530 -@@ -0,0 +1,728 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: Vivek Goyal (vgoyal@in.ibm.com) -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-elf.h" -+#include "../../kexec-syscall.h" -+#include "../../crashdump.h" -+#include "kexec-x86.h" -+#include "crashdump-x86.h" -+#include -+ -+extern struct arch_options_t arch_options; -+ -+/* Forward Declaration. */ -+static int exclude_crash_reserve_region(int *nr_ranges); -+ -+/* Stores a sorted list of RAM memory ranges for which to create elf headers. -+ * A separate program header is created for backup region */ -+static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; -+ -+/* Memory region reserved for storing panic kernel and other data. */ -+static struct memory_range crash_reserved_mem; -+ -+/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to -+ * create Elf headers. Keeping it separate from get_memory_ranges() as -+ * requirements are different in the case of normal kexec and crashdumps. -+ * -+ * Normal kexec needs to look at all of available physical memory irrespective -+ * of the fact how much of it is being used by currently running kernel. -+ * Crashdumps need to have access to memory regions actually being used by -+ * running kernel. Expecting a different file/data structure than /proc/iomem -+ * 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) -+{ -+ const char iomem[]= "/proc/iomem"; -+ int memory_ranges = 0; -+ char line[MAX_LINE]; -+ FILE *fp; -+ unsigned long long start, end; -+ -+ fp = fopen(iomem, "r"); -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", -+ iomem, strerror(errno)); -+ return -1; -+ } -+ -+ /* 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++; -+ -+ while(fgets(line, sizeof(line), fp) != 0) { -+ char *str; -+ int type, consumed, count; -+ if (memory_ranges >= CRASH_MAX_MEMORY_RANGES) -+ break; -+ count = sscanf(line, "%Lx-%Lx : %n", -+ &start, &end, &consumed); -+ if (count != 2) -+ continue; -+ str = line + consumed; -+#if 0 -+ printf("%016Lx-%016Lx : %s", -+ start, end, str); -+#endif -+ /* Only Dumping memory of type System RAM. */ -+ if (memcmp(str, "System RAM\n", 11) == 0) { -+ type = RANGE_RAM; -+ } else if (memcmp(str, "Crash kernel\n", 13) == 0) { -+ /* Reserved memory region. New kernel can -+ * use this region to boot into. */ -+ crash_reserved_mem.start = start; -+ crash_reserved_mem.end = end; -+ crash_reserved_mem.type = RANGE_RAM; -+ continue; -+ } else { -+ continue; -+ } -+ -+ /* First 640K already registered */ -+ if (start >= 0x00000000 && end <= 0x0009ffff) -+ continue; -+ -+ crash_memory_range[memory_ranges].start = start; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = type; -+ memory_ranges++; -+ -+ /* Segregate linearly mapped region. */ -+ if ((MAXMEM - 1) >= start && (MAXMEM - 1) <= end) { -+ crash_memory_range[memory_ranges-1].end = MAXMEM -1; -+ -+ /* Add segregated region. */ -+ crash_memory_range[memory_ranges].start = MAXMEM; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = type; -+ memory_ranges++; -+ } -+ } -+ fclose(fp); -+ if (exclude_crash_reserve_region(&memory_ranges) < 0) -+ return -1; -+ *range = crash_memory_range; -+ *ranges = memory_ranges; -+#if 0 -+ int i; -+ printf("CRASH MEMORY RANGES\n"); -+ for(i = 0; i < memory_ranges; i++) { -+ start = crash_memory_range[i].start; -+ end = crash_memory_range[i].end; -+ printf("%016Lx-%016Lx\n", start, end); -+ } -+#endif -+ return 0; -+} -+ -+/* Removes crash reserve region from list of memory chunks for whom elf program -+ * headers have to be created. Assuming crash reserve region to be a single -+ * continuous area fully contained inside one of the memory chunks */ -+static int exclude_crash_reserve_region(int *nr_ranges) -+{ -+ int i, j, tidx = -1; -+ unsigned long long cstart, cend; -+ struct memory_range temp_region; -+ -+ /* Crash reserved region. */ -+ cstart = crash_reserved_mem.start; -+ cend = crash_reserved_mem.end; -+ -+ for (i = 0; i < (*nr_ranges); i++) { -+ unsigned long long mstart, mend; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (cstart < mend && cend > mstart) { -+ if (cstart != mstart && cend != mend) { -+ /* Split memory region */ -+ crash_memory_range[i].end = cstart - 1; -+ temp_region.start = cend + 1; -+ temp_region.end = mend; -+ temp_region.type = RANGE_RAM; -+ tidx = i+1; -+ } else if (cstart != mstart) -+ crash_memory_range[i].end = cstart - 1; -+ else -+ crash_memory_range[i].start = cend + 1; -+ } -+ } -+ /* Insert split memory region, if any. */ -+ if (tidx >= 0) { -+ if (*nr_ranges == CRASH_MAX_MEMORY_RANGES) { -+ /* No space to insert another element. */ -+ fprintf(stderr, "Error: Number of crash memory ranges" -+ " excedeed the max limit\n"); -+ return -1; -+ } -+ for (j = (*nr_ranges - 1); j >= tidx; j--) -+ crash_memory_range[j+1] = crash_memory_range[j]; -+ crash_memory_range[tidx].start = temp_region.start; -+ crash_memory_range[tidx].end = temp_region.end; -+ crash_memory_range[tidx].type = temp_region.type; -+ (*nr_ranges)++; -+ } -+ return 0; -+} -+ -+/* Adds a segment from list of memory regions which new kernel can use to -+ * boot. Segment start and end should be aligned to 1K boundary. */ -+static int add_memmap(struct memory_range *memmap_p, unsigned long long addr, -+ size_t size) -+{ -+ int i, j, nr_entries = 0, tidx = 0, align = 1024; -+ unsigned long long mstart, mend; -+ -+ /* Do alignment check. */ -+ if ((addr%align) || (size%align)) -+ return -1; -+ -+ /* Make sure at least one entry in list is free. */ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (!mstart && !mend) -+ break; -+ else -+ nr_entries++; -+ } -+ if (nr_entries == CRASH_MAX_MEMMAP_NR) -+ return -1; -+ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) -+ break; -+ if (mstart <= (addr+size-1) && mend >=addr) -+ /* Overlapping region. */ -+ return -1; -+ else if (addr > mend) -+ tidx = i+1; -+ } -+ /* Insert the memory region. */ -+ for (j = nr_entries-1; j >= tidx; j--) -+ memmap_p[j+1] = memmap_p[j]; -+ memmap_p[tidx].start = addr; -+ memmap_p[tidx].end = addr + size - 1; -+#if 0 -+ printf("Memmap after adding segment\n"); -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) -+ break; -+ printf("%016llx - %016llx\n", -+ mstart, mend); -+ } -+#endif -+ return 0; -+} -+ -+/* Removes a segment from list of memory regions which new kernel can use to -+ * boot. Segment start and end should be aligned to 1K boundary. */ -+static int delete_memmap(struct memory_range *memmap_p, unsigned long long addr, -+ size_t size) -+{ -+ int i, j, nr_entries = 0, tidx = -1, operation = 0, align = 1024; -+ unsigned long long mstart, mend; -+ struct memory_range temp_region; -+ -+ /* Do alignment check. */ -+ if ((addr%align) || (size%align)) -+ return -1; -+ -+ /* Make sure at least one entry in list is free. */ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (!mstart && !mend) -+ break; -+ else -+ nr_entries++; -+ } -+ if (nr_entries == CRASH_MAX_MEMMAP_NR) -+ /* List if full */ -+ return -1; -+ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) -+ /* Did not find the segment in the list. */ -+ return -1; -+ if (mstart <= addr && mend >= (addr + size - 1)) { -+ if (mstart == addr && mend == (addr + size - 1)) { -+ /* Exact match. Delete region */ -+ operation = -1; -+ tidx = i; -+ break; -+ } -+ if (mstart != addr && mend != (addr + size - 1)) { -+ /* Split in two */ -+ memmap_p[i].end = addr - 1; -+ temp_region.start = addr + size; -+ temp_region.end = mend; -+ operation = 1; -+ tidx = i; -+ break; -+ } -+ -+ /* No addition/deletion required. Adjust the existing.*/ -+ if (mstart != addr) { -+ memmap_p[i].end = addr - 1; -+ break; -+ } else { -+ memmap_p[i].start = addr + size; -+ break; -+ } -+ } -+ } -+ if ((operation == 1) && tidx >=0) { -+ /* Insert the split memory region. */ -+ for (j = nr_entries-1; j > tidx; j--) -+ memmap_p[j+1] = memmap_p[j]; -+ memmap_p[tidx+1] = temp_region; -+ } -+ if ((operation == -1) && tidx >=0) { -+ /* Delete the exact match memory region. */ -+ for (j = i+1; j < CRASH_MAX_MEMMAP_NR; j++) -+ memmap_p[j-1] = memmap_p[j]; -+ memmap_p[j-1].start = memmap_p[j-1].end = 0; -+ } -+#if 0 -+ printf("Memmap after deleting segment\n"); -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) { -+ break; -+ } -+ printf("%016llx - %016llx\n", -+ mstart, mend); -+ } -+#endif -+ return 0; -+} -+ -+/* Converts unsigned long to ascii string. */ -+static void ultoa(unsigned long i, char *str) -+{ -+ int j = 0, k; -+ char tmp; -+ -+ do { -+ str[j++] = i % 10 + '0'; -+ } while ((i /=10) > 0); -+ str[j] = '\0'; -+ -+ /* Reverse the string. */ -+ for (j = 0, k = strlen(str) - 1; j < k; j++, k--) { -+ tmp = str[k]; -+ str[k] = str[j]; -+ str[j] = tmp; -+ } -+} -+ -+/* Adds the appropriate memmap= options to command line, indicating the -+ * memory regions the new kernel can use to boot into. */ -+static int cmdline_add_memmap(char *cmdline, struct memory_range *memmap_p) -+{ -+ int i, cmdlen, len, min_sizek = 100; -+ char str_mmap[256], str_tmp[20]; -+ -+ /* Exact map */ -+ strcpy(str_mmap, " memmap=exactmap"); -+ len = strlen(str_mmap); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str_mmap); -+ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ unsigned long startk, endk; -+ startk = (memmap_p[i].start/1024); -+ endk = ((memmap_p[i].end + 1)/1024); -+ if (!startk && !endk) -+ /* All regions traversed. */ -+ break; -+ -+ /* A region is not worth adding if region size < 100K. It eats -+ * up precious command line length. */ -+ if ((endk - startk) < min_sizek) -+ continue; -+ strcpy (str_mmap, " memmap="); -+ ultoa((endk-startk), str_tmp); -+ strcat (str_mmap, str_tmp); -+ strcat (str_mmap, "K@"); -+ ultoa(startk, str_tmp); -+ strcat (str_mmap, str_tmp); -+ strcat (str_mmap, "K"); -+ len = strlen(str_mmap); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str_mmap); -+ } -+ -+#if 0 -+ printf("Command line after adding memmap\n"); -+ printf("%s\n", cmdline); -+#endif -+ return 0; -+} -+ -+/* Adds the elfcorehdr= command line parameter to command line. */ -+static int cmdline_add_elfcorehdr(char *cmdline, unsigned long addr) -+{ -+ int cmdlen, len, align = 1024; -+ char str[30], *ptr; -+ -+ /* Passing in elfcorehdr=xxxK format. Saves space required in cmdline. -+ * Ensure 1K alignment*/ -+ if (addr%align) -+ return -1; -+ addr = addr/align; -+ ptr = str; -+ strcpy(str, " elfcorehdr="); -+ ptr += strlen(str); -+ ultoa(addr, ptr); -+ strcat(str, "K"); -+ len = strlen(str); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str); -+#if 0 -+ printf("Command line after adding elfcorehdr\n"); -+ printf("%s\n", cmdline); -+#endif -+ return 0; -+} -+ -+ -+/* -+ * This routine is specific to i386 architecture to maintain the -+ * backward compatibility, other architectures can use the per -+ * cpu version get_crash_notes_per_cpu() directly. -+ */ -+static int get_crash_notes(int cpu, uint64_t *addr) -+{ -+ char crash_notes[PATH_MAX]; -+ char line[MAX_LINE]; -+ FILE *fp; -+ unsigned long vaddr; -+ int count; -+ -+ sprintf(crash_notes, "/sys/kernel/crash_notes"); -+ fp = fopen(crash_notes, "r"); -+ if (fp) { -+ if (fgets(line, sizeof(line), fp) != 0) { -+ count = sscanf(line, "%lx", &vaddr); -+ if (count != 1) -+ die("Cannot parse %s: %s\n", crash_notes, -+ strerror(errno)); -+ } -+ *addr = __pa(vaddr + (cpu * MAX_NOTE_BYTES)); -+#if 0 -+ printf("crash_notes addr = %Lx\n", *addr); -+#endif -+ return 0; -+ } else -+ return get_crash_notes_per_cpu(cpu, addr); -+} -+ -+/* Prepares the crash memory elf64 headers and stores in supplied buffer. */ -+static int prepare_crash_memory_elf64_headers(struct kexec_info *info, -+ void *buf, unsigned long size) -+{ -+ Elf64_Ehdr *elf; -+ Elf64_Phdr *phdr; -+ int i; -+ char *bufp; -+ long int nr_cpus = 0; -+ uint64_t notes_addr; -+ -+ bufp = (char*) buf; -+ -+ /* Setup ELF Header*/ -+ elf = (Elf64_Ehdr *) bufp; -+ bufp += sizeof(Elf64_Ehdr); -+ memcpy(elf->e_ident, ELFMAG, SELFMAG); -+ elf->e_ident[EI_CLASS] = ELFCLASS64; -+ elf->e_ident[EI_DATA] = ELFDATA2LSB; -+ elf->e_ident[EI_VERSION]= EV_CURRENT; -+ elf->e_ident[EI_OSABI] = ELFOSABI_NONE; -+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); -+ elf->e_type = ET_CORE; -+ elf->e_machine = EM_386; -+ elf->e_version = EV_CURRENT; -+ elf->e_entry = 0; -+ elf->e_phoff = sizeof(Elf64_Ehdr); -+ elf->e_shoff = 0; -+ elf->e_flags = 0; -+ elf->e_ehsize = sizeof(Elf64_Ehdr); -+ elf->e_phentsize= sizeof(Elf64_Phdr); -+ elf->e_phnum = 0; -+ elf->e_shentsize= 0; -+ elf->e_shnum = 0; -+ elf->e_shstrndx = 0; -+ -+ /* PT_NOTE program headers. One per cpu*/ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ return -1; -+ } -+ -+ for (i = 0; i < nr_cpus; i++) { -+ if (get_crash_notes(i, ¬es_addr) < 0) { -+ /* This cpu is not present. Skip it. */ -+ continue; -+ } -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_NOTE; -+ phdr->p_flags = 0; -+ phdr->p_offset = phdr->p_paddr = notes_addr; -+ phdr->p_vaddr = 0; -+ phdr->p_filesz = phdr->p_memsz = MAX_NOTE_BYTES; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ -+ /* Setup PT_LOAD type program header for every system RAM chunk. -+ * A seprate program header for Backup Region*/ -+ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -+ unsigned long long mstart, mend; -+ if (crash_memory_range[i].type != RANGE_RAM) -+ continue; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (!mstart && !mend) -+ continue; -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ if (mstart == BACKUP_START && mend == BACKUP_END) -+ phdr->p_offset = info->backup_start; -+ else -+ phdr->p_offset = mstart; -+ /* Handle linearly mapped region.*/ -+ if (mend <= (MAXMEM - 1)) -+ phdr->p_vaddr = mstart + PAGE_OFFSET; -+ else -+ phdr->p_vaddr = -1ULL; -+ phdr->p_paddr = mstart; -+ phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ return 0; -+} -+ -+/* Prepares the crash memory elf32 headers and stores in supplied buffer. */ -+static int prepare_crash_memory_elf32_headers(struct kexec_info *info, -+ void *buf, unsigned long size) -+{ -+ Elf32_Ehdr *elf; -+ Elf32_Phdr *phdr; -+ int i; -+ char *bufp; -+ long int nr_cpus = 0; -+ uint64_t notes_addr; -+ -+ bufp = (char*) buf; -+ -+ /* Setup ELF Header*/ -+ elf = (Elf32_Ehdr *) bufp; -+ bufp += sizeof(Elf32_Ehdr); -+ memcpy(elf->e_ident, ELFMAG, SELFMAG); -+ elf->e_ident[EI_CLASS] = ELFCLASS32; -+ elf->e_ident[EI_DATA] = ELFDATA2LSB; -+ elf->e_ident[EI_VERSION]= EV_CURRENT; -+ elf->e_ident[EI_OSABI] = ELFOSABI_NONE; -+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); -+ elf->e_type = ET_CORE; -+ elf->e_machine = EM_386; -+ elf->e_version = EV_CURRENT; -+ elf->e_entry = 0; -+ elf->e_phoff = sizeof(Elf32_Ehdr); -+ elf->e_shoff = 0; -+ elf->e_flags = 0; -+ elf->e_ehsize = sizeof(Elf32_Ehdr); -+ elf->e_phentsize= sizeof(Elf32_Phdr); -+ elf->e_phnum = 0; -+ elf->e_shentsize= 0; -+ elf->e_shnum = 0; -+ elf->e_shstrndx = 0; -+ -+ /* PT_NOTE program headers. One per cpu*/ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ return -1; -+ } -+ -+ /* Need to find a better way to determine per cpu notes section size. */ -+#define MAX_NOTE_BYTES 1024 -+ for (i = 0; i < nr_cpus; i++) { -+ if (get_crash_notes(i, ¬es_addr) < 0) { -+ /* This cpu is not present. Skip it. */ -+ return -1; -+ } -+ phdr = (Elf32_Phdr *) bufp; -+ bufp += sizeof(Elf32_Phdr); -+ phdr->p_type = PT_NOTE; -+ phdr->p_flags = 0; -+ phdr->p_offset = phdr->p_paddr = notes_addr; -+ phdr->p_vaddr = 0; -+ phdr->p_filesz = phdr->p_memsz = MAX_NOTE_BYTES; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ -+ /* Setup PT_LOAD type program header for every system RAM chunk. -+ * A seprate program header for Backup Region*/ -+ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -+ unsigned long long mstart, mend; -+ if (crash_memory_range[i].type != RANGE_RAM) -+ continue; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (!mstart && !mend) -+ continue; -+ phdr = (Elf32_Phdr *) bufp; -+ bufp += sizeof(Elf32_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ if (mstart == BACKUP_START && mend == BACKUP_END) -+ phdr->p_offset = info->backup_start; -+ else -+ phdr->p_offset = mstart; -+ /* Handle linearly mapped region.*/ -+ if (mend <= (MAXMEM - 1)) -+ phdr->p_vaddr = mstart + PAGE_OFFSET; -+ else -+ phdr->p_vaddr = UINT_MAX; -+ phdr->p_paddr = mstart; -+ phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ return 0; -+} -+ -+/* Loads additional segments in case of a panic kernel is being loaded. -+ * One segment for backup region, another segment for storing elf headers -+ * for crash memory image. -+ */ -+int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, -+ unsigned long max_addr, unsigned long min_base) -+{ -+ void *tmp; -+ unsigned long sz, elfcorehdr; -+ int nr_ranges, align = 1024; -+ long int nr_cpus = 0; -+ struct memory_range *mem_range, *memmap_p; -+ -+ if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) -+ return -1; -+ -+ /* Memory regions which panic kernel can safely use to boot into */ -+ sz = (sizeof(struct memory_range) * (KEXEC_MAX_SEGMENTS + 1)); -+ memmap_p = xmalloc(sz); -+ memset(memmap_p, 0, sz); -+ add_memmap(memmap_p, BACKUP_START, BACKUP_SIZE); -+ sz = crash_reserved_mem.end - crash_reserved_mem.start +1; -+ add_memmap(memmap_p, crash_reserved_mem.start, sz); -+ -+ /* Create a backup region segment to store backup data*/ -+ sz = (BACKUP_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. */ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ fprintf(stderr,"kexec_load (elf header segment)" -+ " failed: %s\n", strerror(errno)); -+ return -1; -+ } -+ if (arch_options.core_header_type == CORE_TYPE_ELF64) { -+ sz = sizeof(Elf64_Ehdr) + -+ nr_cpus * sizeof(Elf64_Phdr) + -+ nr_ranges * sizeof(Elf64_Phdr); -+ } else { -+ sz = sizeof(Elf32_Ehdr) + -+ nr_cpus * sizeof(Elf32_Phdr) + -+ nr_ranges * sizeof(Elf32_Phdr); -+ } -+ sz = (sz + align - 1) & ~(align -1); -+ tmp = xmalloc(sz); -+ memset(tmp, 0, sz); -+ if (arch_options.core_header_type == CORE_TYPE_ELF64) { -+ if (prepare_crash_memory_elf64_headers(info, tmp, sz) < 0) -+ return -1; -+ } else { -+ if (prepare_crash_memory_elf32_headers(info, tmp, sz) < 0) -+ return -1; -+ } -+ -+ /* Hack: With some ld versions (GNU ld version 2.14.90.0.4 20030523), -+ * vmlinux program headers show a gap of two pages between bss segment -+ * and data segment but effectively kernel considers it as bss segment -+ * and overwrites the any data placed there. Hence bloat the memsz of -+ * elf core header segment to 16K to avoid being placed in such gaps. -+ * This is a makeshift solution until it is fixed in kernel. -+ */ -+ elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, -+ max_addr, 1); -+ if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) -+ return -1; -+ cmdline_add_memmap(mod_cmdline, memmap_p); -+ cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr); -+ return 0; -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/crashdump-x86.h kexec-tools-1.101-kdump/kexec/arch/i386/crashdump-x86.h ---- kexec-tools-1.101/kexec/arch/i386/crashdump-x86.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/crashdump-x86.h 2006-01-19 11:41:30.000000000 +0530 -@@ -0,0 +1,21 @@ -+#ifndef CRASHDUMP_X86_H -+#define CRASHDUMP_X86_H -+ -+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline, -+ unsigned long max_addr, unsigned long min_base); -+ -+#define PAGE_OFFSET 0xc0000000 -+#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -+ -+#define __VMALLOC_RESERVE (128 << 20) -+#define MAXMEM (-PAGE_OFFSET-__VMALLOC_RESERVE) -+ -+#define CRASH_MAX_MEMMAP_NR (KEXEC_MAX_SEGMENTS + 1) -+#define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 2) -+ -+/* Backup Region, First 640K of System RAM. */ -+#define BACKUP_START 0x00000000 -+#define BACKUP_END 0x0009ffff -+#define BACKUP_SIZE (BACKUP_END - BACKUP_START + 1) -+ -+#endif /* CRASHDUMP_X86_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/include/arch/options.h kexec-tools-1.101-kdump/kexec/arch/i386/include/arch/options.h ---- kexec-tools-1.101/kexec/arch/i386/include/arch/options.h 2004-12-22 02:23:37.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/include/arch/options.h 2006-01-19 11:41:36.000000000 +0530 -@@ -6,7 +6,9 @@ - #define OPT_SERIAL_BAUD (OPT_MAX+2) - #define OPT_CONSOLE_VGA (OPT_MAX+3) - #define OPT_CONSOLE_SERIAL (OPT_MAX+4) --#define OPT_ARCH_MAX (OPT_MAX+5) -+#define OPT_ELF32_CORE (OPT_MAX+5) -+#define OPT_ELF64_CORE (OPT_MAX+6) -+#define OPT_ARCH_MAX (OPT_MAX+7) - - #define KEXEC_ARCH_OPTIONS \ - KEXEC_OPTIONS \ -@@ -15,6 +17,8 @@ - { "serial-baud", 1, 0, OPT_SERIAL_BAUD }, \ - { "console-vga", 0, 0, OPT_CONSOLE_VGA }, \ - { "console-serial", 0, 0, OPT_CONSOLE_SERIAL }, \ -+ { "elf32-core-headers", 0, 0, OPT_ELF32_CORE }, \ -+ { "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \ - - #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" - -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c kexec-tools-1.101-kdump/kexec/arch/i386/kexec-bzImage.c ---- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2005-01-13 19:02:01.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/kexec-bzImage.c 2006-01-19 11:41:27.000000000 +0530 -@@ -214,7 +214,7 @@ int do_bzImage_load(struct kexec_info *i - - /* Fill in the information BIOS calls would normally provide. */ - if (!real_mode_entry) { -- setup_linux_system_parameters(real_mode); -+ setup_linux_system_parameters(real_mode, info->kexec_flags); - } - - return 0; -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c kexec-tools-1.101-kdump/kexec/arch/i386/kexec-elf-x86.c ---- kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c 2005-01-13 19:29:19.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/kexec-elf-x86.c 2006-01-19 11:41:32.000000000 +0530 -@@ -32,10 +32,12 @@ - #include - #include - #include "../../kexec.h" -+#include "../../kexec-syscall.h" - #include "../../kexec-elf.h" - #include "../../kexec-elf-boot.h" - #include "x86-linux-setup.h" - #include "kexec-x86.h" -+#include "crashdump-x86.h" - #include - - static const int probe_debug = 0; -@@ -86,7 +88,9 @@ int elf_x86_load(int argc, char **argv, - { - struct mem_ehdr ehdr; - const char *command_line; -+ char *modified_cmdline; - int command_line_len; -+ int modified_cmdline_len; - const char *ramdisk; - unsigned long entry, max_addr; - int arg_style; -@@ -119,6 +123,8 @@ int elf_x86_load(int argc, char **argv, - */ - arg_style = ARG_STYLE_ELF; - command_line = 0; -+ modified_cmdline = 0; -+ modified_cmdline_len = 0; - ramdisk = 0; - while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { - switch(opt) { -@@ -156,6 +162,20 @@ int elf_x86_load(int argc, char **argv, - command_line_len = strlen(command_line) +1; - } - -+ /* Need to append some command line parameters internally in case of -+ * taking crash dumps. -+ */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ modified_cmdline = xmalloc(COMMAND_LINE_SIZE); -+ memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); -+ if (command_line) { -+ strncpy(modified_cmdline, command_line, -+ COMMAND_LINE_SIZE); -+ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; -+ } -+ modified_cmdline_len = strlen(modified_cmdline); -+ } -+ - /* Load the ELF executable */ - elf_exec_build_load(info, &ehdr, buf, len); - -@@ -203,10 +223,20 @@ int elf_x86_load(int argc, char **argv, - const unsigned char *ramdisk_buf; - off_t ramdisk_length; - struct entry32_regs regs; -+ int rc = 0; - - /* Get the linux parameter header */ - hdr = xmalloc(sizeof(*hdr)); -- param_base = add_buffer(info, hdr, sizeof(*hdr), sizeof(*hdr), -+ -+ /* Hack: With some ld versions, vmlinux program headers show -+ * a gap of two pages between bss segment and data segment -+ * but effectively kernel considers it as bss segment and -+ * overwrites the any data placed there. Hence bloat the -+ * memsz of parameter segment to 16K to avoid being placed -+ * in such gaps. -+ * This is a makeshift solution until it is fixed in kernel -+ */ -+ param_base = add_buffer(info, hdr, sizeof(*hdr), 16*1024, - 16, 0, max_addr, 1); - - /* Initialize the parameter header */ -@@ -216,9 +246,19 @@ int elf_x86_load(int argc, char **argv, - /* Add a ramdisk to the current image */ - ramdisk_buf = NULL; - ramdisk_length = 0; -- if (ramdisk) { -- unsigned char *ramdisk_buf; -+ if (ramdisk) - ramdisk_buf = slurp_file(ramdisk, &ramdisk_length); -+ -+ /* If panic kernel is being loaded, additional segments need -+ * to be created. */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ rc = load_crashdump_segments(info, modified_cmdline, -+ max_addr, 0); -+ if (rc < 0) -+ return -1; -+ /* Use new command line. */ -+ command_line = modified_cmdline; -+ command_line_len = strlen(modified_cmdline) + 1; - } - - /* Tell the kernel what is going on */ -@@ -228,7 +268,7 @@ int elf_x86_load(int argc, char **argv, - ramdisk_buf, ramdisk_length); - - /* Fill in the information bios calls would usually provide */ -- setup_linux_system_parameters(&hdr->hdr); -+ setup_linux_system_parameters(&hdr->hdr, info->kexec_flags); - - /* Initialize the registers */ - elf_rel_get_symbol(&info->rhdr, "entry32_regs", ®s, sizeof(regs)); -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c kexec-tools-1.101-kdump/kexec/arch/i386/kexec-multiboot-x86.c ---- kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c 2005-01-25 01:28:04.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/kexec-multiboot-x86.c 2006-01-19 11:41:27.000000000 +0530 -@@ -246,7 +246,8 @@ int multiboot_x86_load(int argc, char ** - mbi->boot_loader_name = sizeof(*mbi) + command_line_len; - - /* Memory map */ -- if ((get_memory_ranges(&range, &ranges) < 0) || ranges == 0) { -+ if ((get_memory_ranges(&range, &ranges, info->kexec_flags) < 0) -+ || ranges == 0) { - fprintf(stderr, "Cannot get memory information\n"); - return -1; - } -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/kexec-x86.c kexec-tools-1.101-kdump/kexec/arch/i386/kexec-x86.c ---- kexec-tools-1.101/kexec/arch/i386/kexec-x86.c 2005-02-06 04:54:35.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/kexec-x86.c 2006-01-19 18:19:07.000000000 +0530 -@@ -30,14 +30,14 @@ - #include "../../kexec-elf.h" - #include "../../kexec-syscall.h" - #include "kexec-x86.h" -+#include "crashdump-x86.h" - #include - --#define MAX_MEMORY_RANGES 64 --#define MAX_LINE 160 - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - - /* Return a sorted list of memory ranges. */ --int get_memory_ranges(struct memory_range **range, int *ranges) -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags) - { - const char iomem[]= "/proc/iomem"; - int memory_ranges = 0; -@@ -79,6 +79,20 @@ int get_memory_ranges(struct memory_rang - else if (memcmp(str, "ACPI Non-volatile Storage\n", 26) == 0) { - type = RANGE_ACPI_NVS; - } -+ else if (memcmp(str, "Crash kernel\n", 13) == 0) { -+ /* Redefine the memory region boundaries if kernel -+ * exports the limits and if it is panic kernel. -+ * Override user values only if kernel exported values are -+ * subset of user defined values. -+ */ -+ if (kexec_flags & KEXEC_ON_CRASH) { -+ if (start > mem_min) -+ mem_min = start; -+ if (end < mem_max) -+ mem_max = end; -+ } -+ continue; -+ } - else { - continue; - } -@@ -120,21 +134,18 @@ void arch_usage(void) - " --serial-baud= Specify the serial port baud rate\n" - " --console-vga Enable the vga console\n" - " --console-serial Enable the serial console\n" -+ " --elf32-core-headers Prepare core headers in ELF32 format\n" -+ " --elf64-core-headers Prepare core headers in ELF64 format\n" - ); - } - --static struct { -- uint8_t reset_vga; -- uint16_t serial_base; -- uint32_t serial_baud; -- uint8_t console_vga; -- uint8_t console_serial; --} arch_options = { -+struct arch_options_t arch_options = { - .reset_vga = 0, - .serial_base = 0x3f8, - .serial_baud = 0, - .console_vga = 0, - .console_serial = 0, -+ .core_header_type = CORE_TYPE_ELF64, - }; - - int arch_process_options(int argc, char **argv) -@@ -198,6 +209,12 @@ int arch_process_options(int argc, char - } - arch_options.serial_baud = value; - break; -+ case OPT_ELF32_CORE: -+ arch_options.core_header_type = CORE_TYPE_ELF32; -+ break; -+ case OPT_ELF64_CORE: -+ arch_options.core_header_type = CORE_TYPE_ELF64; -+ break; - } - } - /* Reset getopt for the next pass; called in other source modules */ -@@ -206,7 +223,7 @@ int arch_process_options(int argc, char - return 0; - } - --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+int arch_compat_trampoline(struct kexec_info *info) - { - int result; - struct utsname utsname; -@@ -224,11 +241,11 @@ int arch_compat_trampoline(struct kexec_ - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_386 here. - */ -- *flags |= KEXEC_ARCH_DEFAULT; -+ info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else if (strcmp(utsname.machine, "x86_64") == 0) - { -- *flags |= KEXEC_ARCH_X86_64; -+ info->kexec_flags |= KEXEC_ARCH_X86_64; - if (!info->rhdr.e_shdr) { - fprintf(stderr, - "A trampoline is required for cross architecture support\n"); -@@ -249,6 +266,8 @@ int arch_compat_trampoline(struct kexec_ - - void arch_update_purgatory(struct kexec_info *info) - { -+ uint8_t panic_kernel = 0; -+ - elf_rel_set_symbol(&info->rhdr, "reset_vga", - &arch_options.reset_vga, sizeof(arch_options.reset_vga)); - elf_rel_set_symbol(&info->rhdr, "serial_base", -@@ -259,4 +278,11 @@ void arch_update_purgatory(struct kexec_ - &arch_options.console_vga, sizeof(arch_options.console_vga)); - elf_rel_set_symbol(&info->rhdr, "console_serial", - &arch_options.console_serial, sizeof(arch_options.console_serial)); -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ panic_kernel = 1; -+ elf_rel_set_symbol(&info->rhdr, "backup_start", -+ &info->backup_start, sizeof(info->backup_start)); -+ } -+ elf_rel_set_symbol(&info->rhdr, "panic_kernel", -+ &panic_kernel, sizeof(panic_kernel)); - } -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/kexec-x86.h kexec-tools-1.101-kdump/kexec/arch/i386/kexec-x86.h ---- kexec-tools-1.101/kexec/arch/i386/kexec-x86.h 2005-02-06 04:41:32.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/kexec-x86.h 2006-01-19 11:41:29.000000000 +0530 -@@ -1,6 +1,10 @@ - #ifndef KEXEC_X86_H - #define KEXEC_X86_H - -+#define MAX_MEMORY_RANGES 64 -+#define CORE_TYPE_ELF32 1 -+#define CORE_TYPE_ELF64 2 -+ - extern unsigned char compat_x86_64[]; - extern uint32_t compat_x86_64_size, compat_x86_64_entry32; - -@@ -35,6 +39,15 @@ struct entry16_regs { - uint16_t pad; - }; - -+struct arch_options_t { -+ uint8_t reset_vga; -+ uint16_t serial_base; -+ uint32_t serial_baud; -+ uint8_t console_vga; -+ uint8_t console_serial; -+ int core_header_type; -+}; -+ - int multiboot_x86_probe(const char *buf, off_t len); - int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/Makefile kexec-tools-1.101-kdump/kexec/arch/i386/Makefile ---- kexec-tools-1.101/kexec/arch/i386/Makefile 2005-02-06 04:53:58.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/Makefile 2006-01-19 11:41:29.000000000 +0530 -@@ -9,3 +9,4 @@ KEXEC_C_SRCS+= kexec/arch/i386/kexec-mul - KEXEC_C_SRCS+= kexec/arch/i386/kexec-beoboot-x86.c - KEXEC_C_SRCS+= kexec/arch/i386/kexec-nbi.c - KEXEC_C_SRCS+= kexec/arch/i386/x86-linux-setup.c -+KEXEC_C_SRCS+= kexec/arch/i386/crashdump-x86.c -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c kexec-tools-1.101-kdump/kexec/arch/i386/x86-linux-setup.c ---- kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c 2005-01-13 18:40:01.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/x86-linux-setup.c 2006-02-01 14:41:09.000000000 +0530 -@@ -94,7 +94,8 @@ void setup_linux_bootloader_parameters( - cmdline_ptr[cmdline_len - 1] = '\0'; - } - --void setup_linux_system_parameters(struct x86_linux_param_header *real_mode) -+void setup_linux_system_parameters(struct x86_linux_param_header *real_mode, -+ unsigned long kexec_flags) - { - /* Fill in information the BIOS would usually provide */ - struct memory_range *range; -@@ -135,7 +136,7 @@ void setup_linux_system_parameters(struc - real_mode->aux_device_info = 0; - - /* Fill in the memory info */ -- if ((get_memory_ranges(&range, &ranges) < 0) || ranges == 0) { -+ if ((get_memory_ranges(&range, &ranges, kexec_flags) < 0) || ranges == 0) { - die("Cannot get memory information\n"); - } - if (ranges > E820MAX) { -@@ -164,7 +165,7 @@ void setup_linux_system_parameters(struc - if (range[i].type != RANGE_RAM) - continue; - if ((range[i].start <= 0x100000) && range[i].end > 0x100000) { -- unsigned long long mem_k = (range[i].end >> 10) - 0x100000; -+ unsigned long long mem_k = (range[i].end >> 10) - 0x400; - real_mode->ext_mem_k = mem_k; - real_mode->alt_mem_k = mem_k; - if (mem_k > 0xfc00) { -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.h kexec-tools-1.101-kdump/kexec/arch/i386/x86-linux-setup.h ---- kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.h 2004-12-20 17:50:22.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/i386/x86-linux-setup.h 2006-01-19 11:41:27.000000000 +0530 -@@ -7,7 +7,8 @@ void setup_linux_bootloader_parameters( - unsigned long real_mode_base, unsigned long cmdline_offset, - const char *cmdline, off_t cmdline_len, - const unsigned char *initrd_buf, off_t initrd_size); --void setup_linux_system_parameters(struct x86_linux_param_header *real_mode); -+void setup_linux_system_parameters(struct x86_linux_param_header *real_mode, -+ unsigned long kexec_flags); - - - #define SETUP_BASE 0x90000 -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c kexec-tools-1.101-kdump/kexec/arch/ia64/kexec-ia64.c ---- kexec-tools-1.101/kexec/arch/ia64/kexec-ia64.c 2005-01-11 11:58:36.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ia64/kexec-ia64.c 2006-01-19 18:19:07.000000000 +0530 -@@ -34,11 +34,11 @@ - #include - - #define MAX_MEMORY_RANGES 64 --#define MAX_LINE 160 - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - - /* Return a sorted list of available memory ranges. */ --int get_memory_ranges(struct memory_range **range, int *ranges) -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags) - { - int memory_ranges; - /* -@@ -103,7 +103,7 @@ int arch_process_options(int argc, char - return 0; - } - --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+int arch_compat_trampoline(struct kexec_info *info) - { - int result; - struct utsname utsname; -@@ -115,7 +115,7 @@ int arch_compat_trampoline(struct kexec_ - } - if (strcmp(utsname.machine, "ia64") == 0) - { -- *flags |= KEXEC_ARCH_X86_64; -+ info->kexec_flags |= KEXEC_ARCH_X86_64; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", -@@ -125,7 +125,7 @@ int arch_compat_trampoline(struct kexec_ - return 0; - } - --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+int arch_compat_trampoline(struct kexec_info *info) - { - int result; - struct utsname utsname; -@@ -140,7 +140,7 @@ int arch_compat_trampoline(struct kexec_ - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_IA64 here. - */ -- *flags |= KEXEC_ARCH_DEFAULT; -+ info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc/kexec-ppc.c kexec-tools-1.101-kdump/kexec/arch/ppc/kexec-ppc.c ---- kexec-tools-1.101/kexec/arch/ppc/kexec-ppc.c 2005-01-11 11:58:03.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc/kexec-ppc.c 2006-01-19 18:19:07.000000000 +0530 -@@ -19,11 +19,11 @@ - #include - - #define MAX_MEMORY_RANGES 64 --#define MAX_LINE 160 - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - - /* Return a sorted list of memory ranges. */ --int get_memory_ranges(struct memory_range **range, int *ranges) -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags) - { - int memory_ranges = 0; - #ifdef CONFIG_GAMECUBE -@@ -120,7 +120,7 @@ int arch_process_options(int argc, char - return 0; - } - --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+int arch_compat_trampoline(struct kexec_info *info) - { - int result; - struct utsname utsname; -@@ -135,7 +135,7 @@ int arch_compat_trampoline(struct kexec_ - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_PPC here. - */ -- *flags |= KEXEC_ARCH_DEFAULT; -+ info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.c kexec-tools-1.101-kdump/kexec/arch/ppc64/crashdump-ppc64.c ---- kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/crashdump-ppc64.c 2006-01-19 18:20:07.000000000 +0530 -@@ -0,0 +1,511 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: R Sharada (sharada@in.ibm.com) -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-elf.h" -+#include "../../kexec-syscall.h" -+#include "../../crashdump.h" -+#include "kexec-ppc64.h" -+#include "crashdump-ppc64.h" -+ -+extern struct arch_options_t arch_options; -+ -+/* Stores a sorted list of RAM memory ranges for which to create elf headers. -+ * A separate program header is created for backup region -+ */ -+static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; -+ -+/* -+ * Used to save various memory ranges/regions needed for the captured -+ * kernel to boot. (lime memmap= option in other archs) -+ */ -+mem_rgns_t usablemem_rgns = {0, }; -+ -+/* array to store memory regions to be excluded from elf header creation */ -+mem_rgns_t exclude_rgns = {0, }; -+ -+/* -+ * To store the memory size of the first kernel and this value will be -+ * passed to the second kernel as command line (savemaxmem=xM). -+ * The second kernel will be calculated saved_max_pfn based on this -+ * variable. -+ * Since we are creating/using usable-memory property, there is no way -+ * we can determine the RAM size unless parsing the device-tree/memoy@/reg -+ * property in the kernel. -+ */ -+unsigned long saved_max_mem = 0; -+ -+static int sort_regions(mem_rgns_t *rgn); -+ -+/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to -+ * create Elf headers. Keeping it separate from get_memory_ranges() as -+ * requirements are different in the case of normal kexec and crashdumps. -+ * -+ * Normal kexec needs to look at all of available physical memory irrespective -+ * of the fact how much of it is being used by currently running kernel. -+ * Crashdumps need to have access to memory regions actually being used by -+ * running kernel. Expecting a different file/data structure than /proc/iomem -+ * 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) -+{ -+ -+ int memory_ranges = 0; -+ char device_tree[256] = "/proc/device-tree/"; -+ char fname[256]; -+ char buf[MAXBYTES-1]; -+ DIR *dir, *dmem; -+ FILE *file; -+ struct dirent *dentry, *mentry; -+ int i, n, match; -+ unsigned long long start, end, cstart, cend; -+ -+ /* create a separate program header for the backup region */ -+ crash_memory_range[0].start = 0x0000000000000000; -+ crash_memory_range[0].end = 0x0000000000008000; -+ crash_memory_range[0].type = RANGE_RAM; -+ memory_ranges++; -+ -+ if ((dir = opendir(device_tree)) == NULL) { -+ perror(device_tree); -+ return -1; -+ } -+ while ((dentry = readdir(dir)) != NULL) { -+ if (strncmp(dentry->d_name, "memory@", 7)) -+ continue; -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ if ((dmem = opendir(fname)) == NULL) { -+ perror(fname); -+ closedir(dir); -+ return -1; -+ } -+ while ((mentry = readdir(dmem)) != NULL) { -+ if (strcmp(mentry->d_name, "reg")) -+ continue; -+ strcat(fname, "/reg"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(dmem); -+ closedir(dir); -+ return -1; -+ } -+ if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { -+ perror(fname); -+ fclose(file); -+ closedir(dmem); -+ closedir(dir); -+ return -1; -+ } -+ if (memory_ranges >= MAX_MEMORY_RANGES) -+ break; -+ start = ((unsigned long long *)buf)[0]; -+ end = start + ((unsigned long long *)buf)[1]; -+ if (start == 0 && end >= 0x8000) -+ start = 0x8000; -+ match = 0; -+ sort_regions(&exclude_rgns); -+ -+ /* exclude crash reserved regions */ -+ for (i = 0; i < exclude_rgns.size; i++) { -+ cstart = exclude_rgns.ranges[i].start; -+ cend = exclude_rgns.ranges[i].end; -+ if (cstart < end && cend > start) { -+ if ((cstart == start) && (cend == end)) { -+ match = 1; -+ continue; -+ } -+ if (start < cstart && end > cend) { -+ match = 1; -+ crash_memory_range[memory_ranges].start = start; -+ crash_memory_range[memory_ranges].end = cstart - 1; -+ crash_memory_range[memory_ranges].type = RANGE_RAM; -+ memory_ranges++; -+ crash_memory_range[memory_ranges].start = cend + 1; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = RANGE_RAM; -+ memory_ranges++; -+ break; -+ } else if (start < cstart) { -+ match = 1; -+ crash_memory_range[memory_ranges].start = start; -+ crash_memory_range[memory_ranges].end = cstart - 1; -+ crash_memory_range[memory_ranges].type = RANGE_RAM; -+ memory_ranges++; -+ end = cstart - 1; -+ continue; -+ } else if (end > cend){ -+ match = 1; -+ crash_memory_range[memory_ranges].start = cend + 1; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = RANGE_RAM; -+ memory_ranges++; -+ start = cend + 1; -+ continue; -+ } -+ } -+ -+ } /* end of for loop */ -+ if (!match) { -+ crash_memory_range[memory_ranges].start = start; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = RANGE_RAM; -+ memory_ranges++; -+ } -+ -+ fclose(file); -+ } -+ closedir(dmem); -+ } -+ closedir(dir); -+ -+ /* -+ * Can not trust the memory regions order that we read from -+ * device-tree. Hence, get the MAX end value. -+ */ -+ for (i = 0; i < memory_ranges; i++) -+ if (saved_max_mem < crash_memory_range[i].end) -+ saved_max_mem = crash_memory_range[i].end; -+ -+ *range = crash_memory_range; -+ *ranges = memory_ranges; -+#if DEBUG -+ int i; -+ printf("CRASH MEMORY RANGES\n"); -+ for(i = 0; i < *ranges; i++) { -+ start = crash_memory_range[i].start; -+ end = crash_memory_range[i].end; -+ fprintf(stderr, "%016Lx-%016Lx\n", start, end); -+ } -+#endif -+ return 0; -+} -+ -+/* Converts unsigned long to ascii string. */ -+static void ultoa(unsigned long i, char *str) -+{ -+ int j = 0, k; -+ char tmp; -+ -+ do { -+ str[j++] = i % 10 + '0'; -+ } while ((i /=10) > 0); -+ str[j] = '\0'; -+ -+ /* Reverse the string. */ -+ for (j = 0, k = strlen(str) - 1; j < k; j++, k--) { -+ tmp = str[k]; -+ str[k] = str[j]; -+ str[j] = tmp; -+ } -+} -+ -+static int add_cmdline_param(char *cmdline, unsigned long addr, -+ char *cmdstr, char *byte) -+{ -+ int cmdlen, len, align = 1024; -+ char str[COMMAND_LINE_SIZE], *ptr; -+ -+ /* Passing in =xxxK / =xxxM format. Saves space required in cmdline.*/ -+ switch (byte[0]) { -+ case 'K': -+ if (addr%align) -+ return -1; -+ addr = addr/align; -+ break; -+ case 'M': -+ addr = addr/(align *align); -+ break; -+ } -+ ptr = str; -+ strcpy(str, cmdstr); -+ ptr += strlen(str); -+ ultoa(addr, ptr); -+ strcat(str, byte); -+ len = strlen(str); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str); -+#if DEBUG -+ fprintf(stderr, "Command line after adding elfcorehdr: %s\n", cmdline); -+#endif -+ return 0; -+} -+ -+/* Prepares the crash memory elf64 headers and stores in supplied buffer. */ -+static int prepare_crash_memory_elf64_headers(struct kexec_info *info, -+ void *buf, unsigned long size) -+{ -+ Elf64_Ehdr *elf; -+ Elf64_Phdr *phdr; -+ int i; -+ char *bufp; -+ long int nr_cpus = 0; -+ unsigned long notes_addr; -+ -+ bufp = (char*) buf; -+ -+ /* Setup ELF Header*/ -+ elf = (Elf64_Ehdr *) bufp; -+ bufp += sizeof(Elf64_Ehdr); -+ memcpy(elf->e_ident, ELFMAG, SELFMAG); -+ elf->e_ident[EI_CLASS] = ELFCLASS64; -+ elf->e_ident[EI_DATA] = ELFDATA2MSB; -+ elf->e_ident[EI_VERSION]= EV_CURRENT; -+ elf->e_ident[EI_OSABI] = ELFOSABI_NONE; -+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); -+ elf->e_type = ET_CORE; -+ elf->e_machine = EM_PPC64; -+ elf->e_version = EV_CURRENT; -+ elf->e_entry = 0; -+ elf->e_phoff = sizeof(Elf64_Ehdr); -+ elf->e_shoff = 0; -+ elf->e_flags = 0; -+ elf->e_ehsize = sizeof(Elf64_Ehdr); -+ elf->e_phentsize= sizeof(Elf64_Phdr); -+ elf->e_phnum = 0; -+ elf->e_shentsize= 0; -+ elf->e_shnum = 0; -+ elf->e_shstrndx = 0; -+ -+ /* PT_NOTE program headers. One per cpu*/ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) -+ return -1; -+ -+ /* Need to find a better way to determine per cpu notes section size. */ -+#define MAX_NOTE_BYTES 1024 -+ for (i = 0; i < nr_cpus; i++) { -+ if (get_crash_notes_per_cpu(i, ¬es_addr) < 0) { -+ /* This cpu is not present. Skip it. */ -+ continue; -+ } -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_NOTE; -+ phdr->p_flags = 0; -+ phdr->p_offset = phdr->p_paddr = notes_addr; -+ phdr->p_vaddr = 0; -+ phdr->p_filesz = phdr->p_memsz = MAX_NOTE_BYTES; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ -+ /* Setup PT_LOAD type program header for every system RAM chunk. -+ * A seprate program header for Backup Region -+ */ -+ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -+ unsigned long long mstart, mend; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (!mstart && !mend) -+ break; -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ if (mstart == BACKUP_START && mend == BACKUP_END) -+ phdr->p_offset = info->backup_start; -+ else -+ phdr->p_offset = mstart; -+ /* Handle linearly mapped region.*/ -+ if (mend <= (MAXMEM - 1)) -+ phdr->p_vaddr = mstart + PAGE_OFFSET; -+ else -+ phdr->p_vaddr = -1ULL; -+ phdr->p_paddr = mstart; -+ phdr->p_filesz = phdr->p_memsz = mend - mstart; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ return 0; -+} -+ -+/* Loads additional segments in case of a panic kernel is being loaded. -+ * One segment for backup region, another segment for storing elf headers -+ * for crash memory image. -+ */ -+int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, -+ unsigned long max_addr, unsigned long min_base) -+{ -+ void *tmp; -+ unsigned long sz, elfcorehdr; -+ int nr_ranges, align = 1024; -+ long int nr_cpus = 0; -+ struct memory_range *mem_range; -+ -+ if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) -+ return -1; -+ -+ /* Create a backup region segment to store backup data*/ -+ sz = (BACKUP_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); -+ reserve(info->backup_start, sz); -+ /* Create elf header segment and store crash image data. */ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ fprintf(stderr,"kexec_load (elf header segment)" -+ " failed: %s\n", strerror(errno)); -+ return -1; -+ } -+ if (arch_options.core_header_type == CORE_TYPE_ELF64) { -+ sz = sizeof(Elf64_Ehdr) + -+ nr_cpus * sizeof(Elf64_Phdr) + -+ nr_ranges * sizeof(Elf64_Phdr); -+ } else { -+ sz = sizeof(Elf32_Ehdr) + -+ nr_cpus * sizeof(Elf32_Phdr) + -+ nr_ranges * sizeof(Elf32_Phdr); -+ } -+ sz = (sz + align - 1) & ~(align -1); -+ tmp = xmalloc(sz); -+ memset(tmp, 0, sz); -+ if (arch_options.core_header_type == CORE_TYPE_ELF64) { -+ if (prepare_crash_memory_elf64_headers(info, tmp, sz) < 0) -+ return -1; -+ } -+ -+ elfcorehdr = add_buffer(info, tmp, sz, sz, align, min_base, -+ max_addr, 1); -+ reserve(elfcorehdr, sz); -+ /* modify and store the cmdline in a global array. This is later -+ * read by flatten_device_tree and modified if required -+ */ -+ add_cmdline_param(mod_cmdline, elfcorehdr, " elfcorehdr=", "K"); -+ add_cmdline_param(mod_cmdline, saved_max_mem, " savemaxmem=", "M"); -+ return 0; -+} -+ -+/* -+ * Used to save various memory regions needed for the captured kernel. -+ */ -+ -+void add_usable_mem_rgns(unsigned long long base, unsigned long long size) -+{ -+ int i; -+ unsigned long long end = base + size; -+ unsigned long long ustart, uend; -+ -+ base = _ALIGN_DOWN(base, PAGE_SIZE); -+ end = _ALIGN_UP(end, PAGE_SIZE); -+ -+ for (i=0; i < usablemem_rgns.size; i++) { -+ ustart = usablemem_rgns.ranges[i].start; -+ uend = usablemem_rgns.ranges[i].end; -+ if (base < uend && end > ustart) { -+ if ((base >= ustart) && (end <= uend)) -+ return; -+ if (base < ustart && end > uend) { -+ usablemem_rgns.ranges[i].start = base; -+ usablemem_rgns.ranges[i].end = end; -+ return; -+ } else if (base < ustart) { -+ usablemem_rgns.ranges[i].start = base; -+ return; -+ } else if (end > uend){ -+ usablemem_rgns.ranges[i].end = end; -+ return; -+ } -+ } -+ } -+ usablemem_rgns.ranges[usablemem_rgns.size].start = base; -+ usablemem_rgns.ranges[usablemem_rgns.size++].end = end; -+ -+#ifdef DEBUG -+ fprintf(stderr, "usable memory rgns size:%d base:%lx size:%lx\n", usablemem_rgns.size, base, size); -+#endif -+} -+ -+/* -+ * Used to exclude various memory regions that do not need elf hdr generation -+ */ -+ -+void add_exclude_rgns(unsigned long long base, unsigned long long size) -+{ -+ int i; -+ unsigned long long end = base + size; -+ unsigned long long xstart, xend; -+ -+ for (i=0; i < exclude_rgns.size; i++) { -+ xstart = exclude_rgns.ranges[i].start; -+ xend = exclude_rgns.ranges[i].end; -+ if (base < xend && end > xstart) { -+ if ((base >= xstart) && (end <= xend)) -+ return; -+ if (base < xstart && end > xend) { -+ exclude_rgns.ranges[i].start = base; -+ exclude_rgns.ranges[i].end = end; -+ return; -+ } else if (base < xstart) { -+ exclude_rgns.ranges[i].start = base; -+ exclude_rgns.ranges[i].end = xend; -+ return; -+ } else if (end > xend){ -+ exclude_rgns.ranges[i].start = xstart; -+ exclude_rgns.ranges[i].end = end; -+ return; -+ } -+ } -+ } -+ exclude_rgns.ranges[exclude_rgns.size].start = base; -+ exclude_rgns.ranges[exclude_rgns.size++].end = end; -+ -+#ifdef DEBUG -+ fprintf(stderr, "exclude rgns size:%d base:%lx end:%lx size:%lx\n", exclude_rgns.size, base, end, size); -+#endif -+} -+ -+static int sort_regions(mem_rgns_t *rgn) -+{ -+ int i, j; -+ unsigned long long tstart, tend; -+ for (i = 0; i < rgn->size; i++) { -+ for (j = 0; j < rgn->size - i - 1; j++) { -+ if (rgn->ranges[j].start > rgn->ranges[j+1].start) { -+ tstart = rgn->ranges[j].start; -+ tend = rgn->ranges[j].end; -+ rgn->ranges[j].start = rgn->ranges[j+1].start; -+ rgn->ranges[j].end = rgn->ranges[j+1].end; -+ rgn->ranges[j+1].start = tstart; -+ rgn->ranges[j+1].end = tend; -+ } -+ } -+ } -+ return 0; -+ -+} -+ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.h kexec-tools-1.101-kdump/kexec/arch/ppc64/crashdump-ppc64.h ---- kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/crashdump-ppc64.h 2006-02-22 11:30:11.080108112 +0530 -@@ -0,0 +1,35 @@ -+#ifndef CRASHDUMP_PPC64_H -+#define CRASHDUMP_PPC64_H -+ -+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline, -+ unsigned long max_addr, unsigned long min_base); -+void add_usable_mem_rgns(unsigned long long base, unsigned long long size); -+void add_exclude_rgns(unsigned long long base, unsigned long long size); -+ -+#define PAGE_OFFSET 0xC000000000000000 -+#define KERNELBASE PAGE_OFFSET -+#define VMALLOCBASE 0xD000000000000000 -+ -+#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -+ -+#define MAXMEM (-KERNELBASE-VMALLOCBASE) -+ -+#define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 6) -+ -+#define COMMAND_LINE_SIZE 512 /* from kernel */ -+/* Backup Region, First 32K of System RAM. */ -+#define BACKUP_START 0x0000 -+#define BACKUP_END 0x8000 -+#define BACKUP_SIZE (BACKUP_END - BACKUP_START + 1) -+ -+#define KDUMP_BACKUP_LIMIT 0x8000 -+#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) -+#define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) -+#ifndef PAGE_SIZE -+#define PAGE_SIZE 4096 -+#endif -+ -+extern unsigned long long crash_base; -+extern unsigned long long crash_size; -+ -+#endif /* CRASHDUMP_PPC64_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c kexec-tools-1.101-kdump/kexec/arch/ppc64/fs2dt.c ---- kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/fs2dt.c 2006-02-22 11:41:54.993097072 +0530 -@@ -0,0 +1,462 @@ -+/* -+ * fs2dt: creates a flattened device-tree -+ * -+ * Copyright (C) 2004,2005 Milton D Miller II, IBM Corporation -+ * Copyright (C) 2005 R Sharada (sharada@in.ibm.com), IBM Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "kexec-ppc64.h" -+#include "crashdump-ppc64.h" -+ -+#define MAXPATH 1024 /* max path name length */ -+#define NAMESPACE 16384 /* max bytes for property names */ -+#define TREEWORDS 65536 /* max 32 bit words for property values */ -+#define MEMRESERVE 256 /* max number of reserved memory blocks */ -+ -+enum { -+ ERR_NONE, -+ ERR_USAGE, -+ ERR_OPENDIR, -+ ERR_READDIR, -+ ERR_STAT, -+ ERR_OPEN, -+ ERR_READ, -+ ERR_RESERVE, -+}; -+ -+void err(const char *str, int rc) -+{ -+ if (errno) -+ perror(str); -+ else -+ fprintf(stderr, "%s: unrecoverable error\n", str); -+ exit(rc); -+} -+ -+typedef unsigned dvt; -+struct stat statbuf[1]; -+char pathname[MAXPATH], *pathstart; -+char propnames[NAMESPACE]; -+dvt dtstruct[TREEWORDS], *dt; -+unsigned long long mem_rsrv[2*MEMRESERVE]; -+ -+static int initrd_found = 0; -+static int crash_param = 0; -+char local_cmdline[COMMAND_LINE_SIZE] = { "" }; -+dvt *dt_len; /* changed len of modified cmdline in flat device-tree */ -+extern mem_rgns_t usablemem_rgns; -+struct bootblock bb[1]; -+ -+void reserve(unsigned long long where, unsigned long long length) -+{ -+ unsigned long long *mr; -+ -+ mr = mem_rsrv; -+ -+ while(mr[1]) -+ mr += 2; -+ -+ mr[0] = where; -+ mr[1] = length; -+} -+ -+/* look for properties we need to reserve memory space for */ -+void checkprop(char *name, dvt *data) -+{ -+ static unsigned long long base, size, end; -+ -+ if ((data == NULL) && (base || size || end)) -+ err((void *)data, ERR_RESERVE); -+ else if (!strcmp(name, "linux,rtas-base")) -+ base = *data; -+ else if (!strcmp(name, "linux,tce-base")) -+ base = *(unsigned long long *) data; -+ else if (!strcmp(name, "rtas-size") || -+ !strcmp(name, "linux,tce-size")) -+ size = *data; -+ -+ if (size && end) -+ err(name, ERR_RESERVE); -+ if (base && size) { -+ reserve(base, size); -+ base = size = 0; -+ } -+ if (base && end) { -+ reserve(base, end-base); -+ base = end = 0; -+ } -+} -+ -+/* -+ * return the property index for a property name, creating a new one -+ * if needed. -+ */ -+dvt propnum(const char *name) -+{ -+ dvt offset = 0; -+ -+ while(propnames[offset]) -+ if (strcmp(name, propnames+offset)) -+ offset += strlen(propnames+offset)+1; -+ else -+ return offset; -+ -+ strcpy(propnames+offset, name); -+ -+ return offset; -+} -+ -+void add_usable_mem_property(int fd, int len) -+{ -+ char fname[MAXPATH], *bname; -+ char buf[MAXBYTES +1]; -+ unsigned long ranges[2*MAX_MEMORY_RANGES]; -+ unsigned long long base, end, loc_base, loc_end; -+ int range, rlen = 0; -+ -+ strcpy(fname, pathname); -+ bname = strrchr(fname,'/'); -+ bname[0] = '\0'; -+ bname = strrchr(fname,'/'); -+ if (strncmp(bname, "/memory@", 8)) -+ return; -+ -+ lseek(fd, 0, SEEK_SET); -+ if (read(fd, buf, len) != len) -+ err(pathname, ERR_READ); -+ -+ base = ((unsigned long long *)buf)[0]; -+ end = base + ((unsigned long long *)buf)[1]; -+ -+ for (range = 0; range < usablemem_rgns.size; range++) { -+ loc_base = usablemem_rgns.ranges[range].start; -+ loc_end = usablemem_rgns.ranges[range].end; -+ if (loc_base >= base && loc_end <= end) { -+ ranges[rlen++] = loc_base; -+ ranges[rlen++] = loc_end - loc_base; -+ } else if (base < loc_end && end > loc_base) { -+ if (loc_base < base) -+ loc_base = base; -+ if (loc_end > end) -+ loc_end = end; -+ ranges[rlen++] = loc_base; -+ ranges[rlen++] = loc_end - loc_base; -+ } -+ } -+ -+ if (!rlen) { -+ /* -+ * User did not pass any ranges for thsi region. Hence, write -+ * (0,0) duple in linux,usable-memory property such that -+ * this region will be ignored. -+ */ -+ ranges[rlen++] = 0; -+ ranges[rlen++] = 0; -+ } -+ -+ rlen = rlen * sizeof(unsigned long); -+ /* -+ * No add linux,usable-memory property. -+ */ -+ *dt++ = 3; -+ *dt++ = rlen; -+ *dt++ = propnum("linux,usable-memory"); -+ if ((rlen >= 8) && ((unsigned long)dt & 0x4)) -+ dt++; -+ memcpy(dt,&ranges,rlen); -+ dt += (rlen + 3)/4; -+} -+ -+/* put all properties (files) in the property structure */ -+void putprops(char *fn, struct dirent **nlist, int numlist) -+{ -+ struct dirent *dp; -+ int i = 0; -+ -+ for (i = 0; i < numlist; i++) { -+ dp = nlist[i]; -+ strcpy(fn, dp->d_name); -+ -+ if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) -+ continue; -+ -+ if (lstat(pathname, statbuf)) -+ err(pathname, ERR_STAT); -+ -+ if (!crash_param && !strcmp(fn,"linux,crashkernel-base")) -+ continue; -+ -+ if (!crash_param && !strcmp(fn,"linux,crashkernel-size")) -+ continue; -+ -+ /* -+ * This property will be created for each node during kexec -+ * boot. So, ignore it. -+ */ -+ if (!strcmp(dp->d_name, "linux,pci-domain") || -+ !strcmp(dp->d_name, "linux,htab-base") || -+ !strcmp(dp->d_name, "linux,htab-size") || -+ !strcmp(dp->d_name, "linux,kernel-end")) -+ continue; -+ -+ /* This property will be created/modified later in putnode() -+ * So ignore it. -+ */ -+ if (!strcmp(dp->d_name, "linux,initrd-start") || -+ !strcmp(dp->d_name, "linux,initrd-end")) -+ continue; -+ -+ if (S_ISREG(statbuf[0].st_mode)) { -+ int fd, len = statbuf[0].st_size; -+ -+ *dt++ = 3; -+ dt_len = dt; -+ *dt++ = len; -+ *dt++ = propnum(fn); -+ -+ if ((len >= 8) && ((unsigned long)dt & 0x4)) -+ dt++; -+ -+ fd = open(pathname, O_RDONLY); -+ if (fd == -1) -+ err(pathname, ERR_OPEN); -+ -+ if (read(fd, dt, len) != len) -+ err(pathname, ERR_READ); -+ -+ checkprop(fn, dt); -+ -+ /* Get the cmdline from the device-tree and modify it */ -+ if (!strcmp(dp->d_name, "bootargs")) { -+ int cmd_len; -+ char temp_cmdline[COMMAND_LINE_SIZE] = { "" }; -+ char *param = NULL; -+ cmd_len = strlen(local_cmdline); -+ if (cmd_len != 0) { -+ param = strstr(local_cmdline, -+ "crashkernel="); -+ if (param) -+ crash_param = 1; -+ param = strstr(local_cmdline, "root="); -+ } -+ if (!param) { -+ char *old_param; -+ memcpy(temp_cmdline, dt, len); -+ param = strstr(temp_cmdline, "root="); -+ old_param = strtok(param, " "); -+ if (cmd_len != 0) -+ strcat(local_cmdline, " "); -+ strcat(local_cmdline, old_param); -+ } -+ strcat(local_cmdline, " "); -+ cmd_len = strlen(local_cmdline); -+ cmd_len = cmd_len + 1; -+ memcpy(dt,local_cmdline,cmd_len); -+ len = cmd_len; -+ *dt_len = cmd_len; -+ fprintf(stderr, "Modified cmdline:%s\n", local_cmdline); -+ } -+ -+ dt += (len + 3)/4; -+ if (!strcmp(dp->d_name, "reg") && usablemem_rgns.size) -+ add_usable_mem_property(fd, len); -+ close(fd); -+ } -+ } -+ fn[0] = '\0'; -+ if(errno == ENOSYS) -+ errno = 0; -+ if (errno) -+ err(pathname, ERR_READDIR); -+ checkprop(pathname, NULL); -+} -+ -+/* -+ * Compare function used to sort the device-tree directories -+ * This function will be passed to scandir. -+ */ -+int comparefunc(const void *dentry1, const void *dentry2) -+{ -+ char *str1 = (*(struct dirent **)dentry1)->d_name; -+ char *str2 = (*(struct dirent **)dentry2)->d_name; -+ -+ /* -+ * strcmp scans from left to right and fails to idetify for some -+ * strings such as memory@10000000 and memory@f000000. -+ * Therefore, we get the wrong sorted order like memory@10000000 and -+ * memory@f000000. -+ */ -+ if (strchr(str1, '@') && strchr(str2, '@') && -+ (strlen(str1) > strlen(str2))) -+ return 1; -+ -+ return strcmp(str1, str2); -+} -+ -+/* -+ * put a node (directory) in the property structure. first properties -+ * then children. -+ */ -+void putnode(void) -+{ -+ char *dn; -+ struct dirent *dp; -+ char *basename; -+ struct dirent **namelist; -+ int numlist, i; -+ -+ *dt++ = 1; -+ strcpy((void *)dt, *pathstart ? pathstart : "/"); -+ while(*dt) -+ dt++; -+ if (dt[-1] & 0xff) -+ dt++; -+ -+ numlist = scandir(pathname, &namelist, 0, comparefunc); -+ if (numlist == 0) -+ err(pathname, ERR_OPENDIR); -+ -+ basename = strrchr(pathname,'/'); -+ -+ strcat(pathname, "/"); -+ dn = pathname + strlen(pathname); -+ -+ putprops(dn, namelist, numlist); -+ -+ /* Add initrd entries to the second kernel if first kernel does not -+ * have and second kernel needs. -+ */ -+ if (initrd_base && !initrd_found && !strcmp(basename,"/chosen/")) { -+ int len = 8; -+ unsigned long long initrd_end; -+ *dt++ = 3; -+ *dt++ = len; -+ *dt++ = propnum("linux,initrd-start"); -+ -+ if ((len >= 8) && ((unsigned long)dt & 0x4)) -+ dt++; -+ -+ memcpy(dt,&initrd_base,len); -+ dt += (len + 3)/4; -+ -+ len = 8; -+ *dt++ = 3; -+ *dt++ = len; -+ *dt++ = propnum("linux,initrd-end"); -+ -+ initrd_end = initrd_base + initrd_size; -+ if ((len >= 8) && ((unsigned long)dt & 0x4)) -+ dt++; -+ -+ memcpy(dt,&initrd_end,len); -+ dt += (len + 3)/4; -+ -+ reserve(initrd_base, initrd_size); -+ } -+ -+ for (i=0; i < numlist; i++) { -+ dp = namelist[i]; -+ strcpy(dn, dp->d_name); -+ free(namelist[i]); -+ -+ if (!strcmp(dn, ".") || !strcmp(dn, "..")) -+ continue; -+ -+ if (lstat(pathname, statbuf)) -+ err(pathname, ERR_STAT); -+ -+ if (S_ISDIR(statbuf[0].st_mode)) -+ putnode(); -+ } -+ if (errno) -+ err(pathname, ERR_READDIR); -+ -+ *dt++ = 2; -+ dn[-1] = '\0'; -+ free(namelist); -+} -+ -+int create_flatten_tree(struct kexec_info *info, unsigned char **bufp, -+ unsigned long *sizep, char *cmdline) -+{ -+ unsigned long len; -+ unsigned long tlen; -+ unsigned char *buf; -+ unsigned long me; -+ -+ me = 0; -+ -+ strcpy(pathname, "/proc/device-tree/"); -+ -+ pathstart = pathname + strlen(pathname); -+ dt = dtstruct; -+ -+ if (cmdline) -+ strcpy(local_cmdline, cmdline); -+ -+ putnode(); -+ *dt++ = 9; -+ -+ len = sizeof(bb[0]); -+ len += 7; len &= ~7; -+ -+ bb->off_mem_rsvmap = len; -+ -+ for (len = 1; mem_rsrv[len]; len += 2) -+ ; -+ len+= 3; -+ len *= sizeof(mem_rsrv[0]); -+ -+ bb->off_dt_struct = bb->off_mem_rsvmap + len; -+ -+ len = dt - dtstruct; -+ len *= sizeof(dvt); -+ bb->off_dt_strings = bb->off_dt_struct + len; -+ -+ len = propnum(""); -+ len += 3; len &= ~3; -+ bb->totalsize = bb->off_dt_strings + len; -+ -+ bb->magic = 0xd00dfeed; -+ bb->version = 2; -+ bb->last_comp_version = 2; -+ -+ reserve(me, bb->totalsize); /* patched later in kexec_load */ -+ -+ buf = (unsigned char *) malloc(bb->totalsize); -+ *bufp = buf; -+ memcpy(buf, bb, bb->off_mem_rsvmap); -+ tlen = bb->off_mem_rsvmap; -+ memcpy(buf+tlen, mem_rsrv, bb->off_dt_struct - bb->off_mem_rsvmap); -+ tlen = tlen + (bb->off_dt_struct - bb->off_mem_rsvmap); -+ memcpy(buf+tlen, dtstruct, bb->off_dt_strings - bb->off_dt_struct); -+ tlen = tlen + (bb->off_dt_strings - bb->off_dt_struct); -+ memcpy(buf+tlen, propnames, bb->totalsize - bb->off_dt_strings); -+ tlen = tlen + bb->totalsize - bb->off_dt_strings; -+ *sizep = tlen; -+ return 0; -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/include/arch/options.h kexec-tools-1.101-kdump/kexec/arch/ppc64/include/arch/options.h ---- kexec-tools-1.101/kexec/arch/ppc64/include/arch/options.h 2004-12-22 01:56:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/include/arch/options.h 2006-01-19 18:20:07.000000000 +0530 -@@ -2,9 +2,11 @@ - #define KEXEC_ARCH_PPC64_OPTIONS_H - - #define OPT_ARCH_MAX (OPT_MAX+0) -+#define OPT_ELF64_CORE (OPT_MAX+1) - - #define KEXEC_ARCH_OPTIONS \ - KEXEC_OPTIONS \ -+ { "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \ - - #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" - -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-elf-ppc64.c ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c 2004-12-17 15:02:04.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-elf-ppc64.c 2006-02-22 11:38:31.003108264 +0530 -@@ -3,6 +3,8 @@ - * - * Copyright (C) 2004 Adam Litke (agl@us.ibm.com) - * Copyright (C) 2004 IBM Corp. -+ * Copyright (C) 2005 R Sharada (sharada@in.ibm.com) -+ * Copyright (C) 2006 Mohan Kumar M (mohan@in.ibm.com) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by -@@ -32,46 +34,19 @@ - #include - #include "../../kexec.h" - #include "../../kexec-elf.h" -+#include "../../kexec-syscall.h" - #include "kexec-ppc64.h" -+#include "crashdump-ppc64.h" -+#include - - #define BOOTLOADER "kexec" - #define BOOTLOADER_VERSION VERSION --#define MAX_COMMAND_LINE 256 - --#define UPSZ(X) ((sizeof(X) + 3) & ~3) --static struct boot_notes { -- Elf_Bhdr hdr; -- Elf_Nhdr bl_hdr; -- unsigned char bl_desc[UPSZ(BOOTLOADER)]; -- Elf_Nhdr blv_hdr; -- unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)]; -- Elf_Nhdr cmd_hdr; -- unsigned char command_line[0]; --} elf_boot_notes = { -- .hdr = { -- .b_signature = 0x0E1FB007, -- .b_size = sizeof(elf_boot_notes), -- .b_checksum = 0, -- .b_records = 3, -- }, -- .bl_hdr = { -- .n_namesz = 0, -- .n_descsz = sizeof(BOOTLOADER), -- .n_type = EBN_BOOTLOADER_NAME, -- }, -- .bl_desc = BOOTLOADER, -- .blv_hdr = { -- .n_namesz = 0, -- .n_descsz = sizeof(BOOTLOADER_VERSION), -- .n_type = EBN_BOOTLOADER_VERSION, -- }, -- .blv_desc = BOOTLOADER_VERSION, -- .cmd_hdr = { -- .n_namesz = 0, -- .n_descsz = 0, -- .n_type = EBN_COMMAND_LINE, -- }, --}; -+unsigned long initrd_base, initrd_size; -+ -+int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *, -+ char *); -+int my_r2(struct mem_ehdr *ehdr); - - int elf_ppc64_probe(const char *buf, off_t len) - { -@@ -94,12 +69,94 @@ int elf_ppc64_probe(const char *buf, off - return result; - } - --int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, -- struct kexec_info *info) -+int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, -+ struct kexec_info *info) - { - struct mem_ehdr ehdr; -+ char *cmdline, *modified_cmdline; -+ const char *ramdisk, *devicetreeblob; -+ int cmdline_len, modified_cmdline_len; -+ unsigned long long max_addr, hole_addr; -+ unsigned char *seg_buf = NULL; -+ off_t seg_size = 0; -+ struct mem_phdr *phdr; -+ size_t size; -+ unsigned long long *rsvmap_ptr; -+ struct bootblock *bb_ptr; -+ unsigned int nr_segments, i; -+ int result, opt; -+ unsigned long my_kernel, my_dt_offset; -+ unsigned int my_panic_kernel; -+ unsigned long my_stack, my_backup_start; -+ unsigned long toc_addr; -+ -+#define OPT_APPEND (OPT_ARCH_MAX+0) -+#define OPT_RAMDISK (OPT_ARCH_MAX+1) -+#define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2) -+ -+ static const struct option options[] = { -+ KEXEC_ARCH_OPTIONS -+ { "command-line", 1, NULL, OPT_APPEND }, -+ { "append", 1, NULL, OPT_APPEND }, -+ { "ramdisk", 1, NULL, OPT_RAMDISK }, -+ { "initrd", 1, NULL, OPT_RAMDISK }, -+ { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, -+ { 0, 0, NULL, 0 }, -+ }; -+ -+ static const char short_options[] = KEXEC_OPT_STR ""; - - /* Parse command line arguments */ -+ initrd_base = 0; -+ initrd_size = 0; -+ cmdline = 0; -+ ramdisk = 0; -+ devicetreeblob = 0; -+ max_addr = 0xFFFFFFFFFFFFFFFFUL; -+ hole_addr = 0; -+ -+ while ((opt = getopt_long(argc, argv, short_options, -+ options, 0)) != -1) { -+ switch (opt) { -+ default: -+ /* Ignore core options */ -+ if (opt < OPT_ARCH_MAX) -+ break; -+ case '?': -+ usage(); -+ return -1; -+ case OPT_APPEND: -+ cmdline = optarg; -+ break; -+ case OPT_RAMDISK: -+ ramdisk = optarg; -+ break; -+ case OPT_DEVICETREEBLOB: -+ devicetreeblob = optarg; -+ break; -+ } -+ } -+ -+ cmdline_len = 0; -+ if (cmdline) -+ cmdline_len = strlen(cmdline) + 1; -+ else -+ fprintf(stdout, "Warning: append= option is not passed. Using the first kernel root partition\n"); -+ -+ setup_memory_ranges(info->kexec_flags); -+ -+ /* Need to append some command line parameters internally in case of -+ * taking crash dumps. -+ */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ modified_cmdline = xmalloc(COMMAND_LINE_SIZE); -+ memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); -+ if (cmdline) { -+ strncpy(modified_cmdline, cmdline, COMMAND_LINE_SIZE); -+ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; -+ } -+ modified_cmdline_len = strlen(modified_cmdline); -+ } - - /* Parse the Elf file */ - result = build_elf_exec_info(buf, len, &ehdr); -@@ -108,13 +165,173 @@ int elf_ppc64_load(int argc, char **argv - return result; - } - -- /* Load the Elf data */ -+ /* Load the Elf data. Physical load addresses in elf64 header do not -+ * show up correctly. Use user supplied address for now to patch the -+ * elf header -+ */ -+ -+ phdr = &ehdr.e_phdr[0]; -+ size = phdr->p_filesz; -+ if (size > phdr->p_memsz) -+ size = phdr->p_memsz; -+ -+ hole_addr = (unsigned long)locate_hole(info, size, 0, 0, -+ max_addr, 1); -+ ehdr.e_phdr[0].p_paddr = hole_addr; - result = elf_exec_load(&ehdr, info); - if (result < 0) { - free_elf_info(&ehdr); - return result; - } -- return 1; -+ -+ /* If panic kernel is being loaded, additional segments need -+ * to be created. -+ */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ result = load_crashdump_segments(info, modified_cmdline, -+ max_addr, 0); -+ if (result < 0) -+ return -1; -+ /* Use new command line. */ -+ cmdline = modified_cmdline; -+ cmdline_len = strlen(modified_cmdline) + 1; -+ } -+ -+ /* Add v2wrap to the current image */ -+ seg_buf = NULL; -+ seg_size = 0; -+ -+ seg_buf = (unsigned char *) malloc(purgatory_size); -+ if (seg_buf == NULL) { -+ free_elf_info(&ehdr); -+ return -1; -+ } -+ memcpy(seg_buf, purgatory, purgatory_size); -+ seg_size = purgatory_size; -+ elf_rel_build_load(info, &info->rhdr, (const char *)purgatory, -+ purgatory_size, 0, max_addr, 1); -+ -+ /* Add a ram-disk to the current image -+ * Note: Add the ramdisk after elf_rel_build_load -+ */ -+ if (ramdisk) { -+ if (devicetreeblob) { -+ fprintf(stderr, -+ "Can't use ramdisk with device tree blob input\n"); -+ return -1; -+ } -+ seg_buf = (unsigned char *)slurp_file(ramdisk, &seg_size); -+ add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, 1); -+ hole_addr = (unsigned long long) -+ info->segment[info->nr_segments-1].mem; -+ initrd_base = hole_addr; -+ initrd_size = (unsigned long long) -+ info->segment[info->nr_segments-1].memsz; -+ } /* ramdisk */ -+ -+ if (devicetreeblob) { -+ unsigned char *blob_buf = NULL; -+ off_t blob_size = 0; -+ -+ /* Grab device tree from buffer */ -+ blob_buf = -+ (unsigned char *)slurp_file(devicetreeblob, &blob_size); -+ add_buffer(info, blob_buf, blob_size, blob_size, 0, 0, -+ max_addr, -1); -+ -+ } else { -+ /* create from fs2dt */ -+ seg_buf = NULL; -+ seg_size = 0; -+ create_flatten_tree(info, (unsigned char **)&seg_buf, -+ (unsigned long *)&seg_size,cmdline); -+ add_buffer(info, seg_buf, seg_size, seg_size, -+ 0, 0, max_addr, -1); -+ } -+ -+ /* patch reserve map address for flattened device-tree -+ * find last entry (both 0) in the reserve mem list. Assume DT -+ * entry is before this one -+ */ -+ bb_ptr = (struct bootblock *)( -+ (unsigned char *)info->segment[(info->nr_segments)-1].buf); -+ rsvmap_ptr = (unsigned long long *)( -+ (unsigned char *)info->segment[(info->nr_segments)-1].buf + -+ bb_ptr->off_mem_rsvmap); -+ while (*rsvmap_ptr || *(rsvmap_ptr+1)) -+ rsvmap_ptr += 2; -+ rsvmap_ptr -= 2; -+ *rsvmap_ptr = (unsigned long long)( -+ info->segment[(info->nr_segments)-1].mem); -+ rsvmap_ptr++; -+ *rsvmap_ptr = (unsigned long long)bb_ptr->totalsize; -+ -+ nr_segments = info->nr_segments; -+ -+ /* Set kernel */ -+ my_kernel = (unsigned long )info->segment[0].mem; -+ elf_rel_set_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); -+ -+ /* Set dt_offset */ -+ my_dt_offset = (unsigned long )info->segment[nr_segments-1].mem; -+ elf_rel_set_symbol(&info->rhdr, "dt_offset", &my_dt_offset, -+ sizeof(my_dt_offset)); -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ my_panic_kernel = 1; -+ /* Set panic flag */ -+ elf_rel_set_symbol(&info->rhdr, "panic_kernel", -+ &my_panic_kernel, sizeof(my_panic_kernel)); -+ -+ /* Set backup address */ -+ my_backup_start = info->backup_start; -+ elf_rel_set_symbol(&info->rhdr, "backup_start", -+ &my_backup_start, sizeof(my_backup_start)); -+ } -+ -+ /* Set stack address */ -+ my_stack = locate_hole(info, 16*1024, 0, 0, max_addr, 1); -+ my_stack += 16*1024; -+ elf_rel_set_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); -+ -+ /* Set toc */ -+ toc_addr = (unsigned long) my_r2(&info->rhdr); -+ elf_rel_set_symbol(&info->rhdr, "my_toc", &toc_addr, sizeof(toc_addr)); -+ -+#ifdef DEBUG -+ my_kernel = 0; -+ my_dt_offset = 0; -+ my_panic_kernel = 0; -+ my_backup_start = 0; -+ my_stack = 0; -+ toc_addr = 0; -+ -+ elf_rel_get_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); -+ elf_rel_get_symbol(&info->rhdr, "dt_offset", &my_dt_offset, -+ sizeof(my_dt_offset)); -+ elf_rel_get_symbol(&info->rhdr, "panic_kernel", &my_panic_kernel, -+ sizeof(my_panic_kernel)); -+ elf_rel_get_symbol(&info->rhdr, "backup_start", &my_backup_start, -+ sizeof(my_backup_start)); -+ elf_rel_get_symbol(&info->rhdr, "stack", &my_stack, sizeof(my_stack)); -+ elf_rel_get_symbol(&info->rhdr, "my_toc", &toc_addr, -+ sizeof(toc_addr)); -+ -+ fprintf(stderr, "info->entry is %p\n", info->entry); -+ fprintf(stderr, "kernel is %Lx\n", my_kernel); -+ fprintf(stderr, "dt_offset is %Lx\n", my_dt_offset); -+ fprintf(stderr, "panic_kernel is %x\n", my_panic_kernel); -+ fprintf(stderr, "backup_start is %Lx\n", my_backup_start); -+ fprintf(stderr, "stack is %Lx\n", my_stack); -+ fprintf(stderr, "toc_addr is %Lx\n", toc_addr); -+ fprintf(stderr, "purgatory size is %d\n", purgatory_size); -+#endif -+ -+ for (i = 0; i < nr_segments; i++) -+ fprintf(stderr, "segment[%d].mem:%p memsz:%ld\n", i, -+ info->segment[i].mem, info->segment[i].memsz); -+ -+ return 0; - } - - void elf_ppc64_usage(void) -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-rel-ppc64.c kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-elf-rel-ppc64.c ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-rel-ppc64.c 2004-12-20 07:36:04.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-elf-rel-ppc64.c 2006-02-22 11:30:11.082107808 +0530 -@@ -1,5 +1,6 @@ - #include - #include -+#include - #include "../../kexec.h" - #include "../../kexec-elf.h" - -@@ -21,20 +22,20 @@ static struct mem_shdr *toc_section(cons - { - struct mem_shdr *shdr, *shdr_end; - unsigned char *strtab; -- strtab = ehdr->e_shdr[ehdr->e_shstrndx].sh_data; -- shdr_end = &ehdr->e_shdr[ehdr->shnum]; -- for(shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) { -- if (strcmp(shdr->sh_name, ".toc") == 0) { -+ strtab = (unsigned char *)ehdr->e_shdr[ehdr->e_shstrndx].sh_data; -+ shdr_end = &ehdr->e_shdr[ehdr->e_shnum]; -+ for(shdr = ehdr->e_shdr; shdr != shdr_end; shdr++) -+ if ( shdr->sh_size && -+ strcmp((char *)&strtab[shdr->sh_name], -+ ".toc") == 0) - return shdr; -- } -- } - return NULL; - } - - /* r2 is the TOC pointer: it actually points 0x8000 into the TOC (this - gives the value maximum span in an instruction which uses a signed - offset) */ --static unsigned long my_r2(const struct mem_ehdr *ehdr) -+unsigned long my_r2(const struct mem_ehdr *ehdr) - { - struct mem_shdr *shdr; - shdr = toc_section(ehdr); -@@ -53,7 +54,7 @@ void machine_apply_elf_rel(struct mem_eh - /* Simply set it */ - *(uint32_t *)location = value; - break; -- -+ - case R_PPC64_ADDR64: - /* Simply set it */ - *(uint64_t *)location = value; -@@ -78,15 +79,34 @@ void machine_apply_elf_rel(struct mem_eh - /* Convert value to relative */ - value -= address; - if (value + 0x2000000 > 0x3ffffff || (value & 3) != 0){ -- die("REL24 %li out of range!\n", -+ die("REL24 %li out of range!\n", - (long int)value); - } - - /* Only replace bits 2 through 26 */ -- *(uint32_t *)location -- = (*(uint32_t *)location & ~0x03fffffc) -- | (value & 0x03fffffc); -+ *(uint32_t *)location = (*(uint32_t *)location & ~0x03fffffc) -+ | (value & 0x03fffffc); -+ break; -+ -+ case R_PPC64_ADDR16_LO: -+ *(uint16_t *)location = value & 0xffff; -+ break; -+ -+ case R_PPC64_ADDR16_HI: -+ *(uint16_t *)location = (value>>16) & 0xffff; - break; -+ -+ case R_PPC64_ADDR16_HA: -+ *(uint16_t *)location = ((value>>16) & 0xffff); -+ break; -+ -+ case R_PPC64_ADDR16_HIGHEST: -+ *(uint16_t *)location = ((value>>48) & 0xffff); -+ break; -+ case R_PPC64_ADDR16_HIGHER: -+ *(uint16_t *)location = ((value>>32) & 0xffff); -+ break; -+ - default: - die("Unknown rela relocation: %lu\n", r_type); - break; -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-ppc64.c ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-ppc64.c 2006-01-19 18:20:07.000000000 +0530 -@@ -0,0 +1,640 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Copyright (C) 2003-2005 Eric Biederman (ebiederm@xmission.com) -+ * Copyright (C) 2005 R Sharada (sharada@in.ibm.com), IBM Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-syscall.h" -+#include "kexec-ppc64.h" -+#include "crashdump-ppc64.h" -+#include -+ -+/* Platforms supported by kexec on PPC64 */ -+#define PLATFORM_PSERIES 0x0100 -+#define PLATFORM_PSERIES_LPAR 0x0101 -+ -+static struct exclude_range exclude_range[MAX_MEMORY_RANGES]; -+static unsigned long long rmo_top; -+static unsigned int platform; -+static struct memory_range memory_range[MAX_MEMORY_RANGES]; -+static struct memory_range base_memory_range[MAX_MEMORY_RANGES]; -+unsigned long long memory_max = 0; -+static int nr_memory_ranges, nr_exclude_ranges; -+unsigned long long crash_base, crash_size; -+ -+static int sort_base_ranges(); -+ -+/* Get base memory ranges */ -+static int get_base_ranges() -+{ -+ int local_memory_ranges = 0; -+ char device_tree[256] = "/proc/device-tree/"; -+ char fname[256]; -+ char buf[MAXBYTES-1]; -+ DIR *dir, *dmem; -+ FILE *file; -+ struct dirent *dentry, *mentry; -+ int n; -+ -+ if ((dir = opendir(device_tree)) == NULL) { -+ perror(device_tree); -+ return -1; -+ } -+ while ((dentry = readdir(dir)) != NULL) { -+ if (strncmp(dentry->d_name, "memory@", 7)) -+ continue; -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ if ((dmem = opendir(fname)) == NULL) { -+ perror(fname); -+ closedir(dir); -+ return -1; -+ } -+ while ((mentry = readdir(dmem)) != NULL) { -+ if (strcmp(mentry->d_name, "reg")) -+ continue; -+ strcat(fname, "/reg"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(dmem); -+ closedir(dir); -+ return -1; -+ } -+ if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { -+ perror(fname); -+ fclose(file); -+ closedir(dmem); -+ closedir(dir); -+ return -1; -+ } -+ if (local_memory_ranges >= MAX_MEMORY_RANGES) -+ break; -+ base_memory_range[local_memory_ranges].start = -+ ((unsigned long long *)buf)[0]; -+ base_memory_range[local_memory_ranges].end = -+ base_memory_range[local_memory_ranges].start + -+ ((unsigned long long *)buf)[1]; -+ base_memory_range[local_memory_ranges].type = RANGE_RAM; -+ local_memory_ranges++; -+#ifdef DEBUG -+ fprintf(stderr, "%016Lx-%016Lx : %x\n", memory_range[local_memory_ranges-1].start, memory_range[local_memory_ranges-1].end, memory_range[local_memory_ranges].type); -+#endif -+ fclose(file); -+ } -+ closedir(dmem); -+ } -+ closedir(dir); -+ nr_memory_ranges = local_memory_ranges; -+ sort_base_ranges(); -+ memory_max = base_memory_range[nr_memory_ranges - 1].end; -+#ifdef DEBUG -+ fprintf(stderr, "get base memory ranges:%d\n", nr_memory_ranges); -+#endif -+ return 0; -+} -+ -+/* Sort the base ranges in memory - this is useful for ensuring that our -+ * ranges are in ascending order, even if device-tree read of memory nodes -+ * is done differently. Also, could be used for other range coalescing later -+ */ -+static int sort_base_ranges() -+{ -+ int i, j; -+ unsigned long long tstart, tend; -+ -+ for (i = 0; i < nr_memory_ranges - 1; i++) { -+ for (j = 0; j < nr_memory_ranges - i - 1; j++) { -+ if (base_memory_range[j].start > base_memory_range[j+1].start) { -+ tstart = base_memory_range[j].start; -+ tend = base_memory_range[j].end; -+ base_memory_range[j].start = base_memory_range[j+1].start; -+ base_memory_range[j].end = base_memory_range[j+1].end; -+ base_memory_range[j+1].start = tstart; -+ base_memory_range[j+1].end = tend; -+ } -+ } -+ } -+ return 0; -+} -+ -+/* Sort the exclude ranges in memory */ -+static int sort_ranges() -+{ -+ int i, j; -+ unsigned long long tstart, tend; -+ for (i = 0; i < nr_exclude_ranges - 1; i++) { -+ for (j = 0; j < nr_exclude_ranges - i - 1; j++) { -+ if (exclude_range[j].start > exclude_range[j+1].start) { -+ tstart = exclude_range[j].start; -+ tend = exclude_range[j].end; -+ exclude_range[j].start = exclude_range[j+1].start; -+ exclude_range[j].end = exclude_range[j+1].end; -+ exclude_range[j+1].start = tstart; -+ exclude_range[j+1].end = tend; -+ } -+ } -+ } -+ return 0; -+} -+ -+/* Get devtree details and create exclude_range array -+ * Also create usablemem_ranges for KEXEC_ON_CRASH -+ */ -+static int get_devtree_details(unsigned long kexec_flags) -+{ -+ unsigned long long rmo_base; -+ unsigned long long tce_base; -+ unsigned int tce_size; -+ unsigned int rtas_base, rtas_size; -+ unsigned long long htab_base, htab_size; -+ unsigned long long kernel_end; -+ char buf[MAXBYTES-1]; -+ char device_tree[256] = "/proc/device-tree/"; -+ char fname[256]; -+ DIR *dir, *cdir; -+ FILE *file; -+ struct dirent *dentry; -+ int n, i = 0; -+ -+ if ((dir = opendir(device_tree)) == NULL) { -+ perror(device_tree); -+ return -1; -+ } -+ -+ while ((dentry = readdir(dir)) != NULL) { -+ if (strncmp(dentry->d_name, "chosen", 6) && -+ strncmp(dentry->d_name, "memory@0", 8) && -+ strncmp(dentry->d_name, "pci@", 4) && -+ strncmp(dentry->d_name, "rtas", 4)) -+ continue; -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ if ((cdir = opendir(fname)) == NULL) { -+ perror(fname); -+ closedir(dir); -+ return -1; -+ } -+ -+ if (strncmp(dentry->d_name, "chosen", 6) == 0) { -+ /* get platform details from /chosen node */ -+ strcat(fname, "/linux,platform"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&platform, sizeof(int), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ fclose(file); -+ -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/linux,kernel-end"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&kernel_end, sizeof(unsigned long), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ fclose(file); -+ -+ /* Add kernel memory to exclude_range */ -+ exclude_range[i].start = 0x0UL; -+ exclude_range[i].end = kernel_end; -+ i++; -+ -+ if (kexec_flags & KEXEC_ON_CRASH) { -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/linux,crashkernel-base"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&crash_base, sizeof(unsigned long), 1, -+ file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ fclose(file); -+ -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/linux,crashkernel-size"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&crash_size, sizeof(unsigned long), 1, -+ file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ -+ if (crash_base > mem_min) -+ mem_min = crash_base; -+ if (crash_base + crash_size < mem_max) -+ mem_max = crash_base + crash_size; -+ -+ add_usable_mem_rgns(0, crash_base + crash_size); -+ reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT); -+ } -+ -+ /* if LPAR, no need to read any more from /chosen */ -+ if (platform != PLATFORM_PSERIES) { -+ closedir(cdir); -+ continue; -+ } -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/linux,htab-base"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&htab_base, sizeof(unsigned long), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/linux,htab-size"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&htab_size, sizeof(unsigned long), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ /* Add htab address to exclude_range - NON-LPAR only */ -+ exclude_range[i].start = htab_base; -+ exclude_range[i].end = htab_base + htab_size; -+ i++; -+ } /* chosen */ -+ -+ if (strncmp(dentry->d_name, "rtas", 4) == 0) { -+ strcat(fname, "/linux,rtas-base"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&rtas_base, sizeof(unsigned int), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/rtas-size"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&rtas_size, sizeof(unsigned int), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ closedir(cdir); -+ /* Add rtas to exclude_range */ -+ exclude_range[i].start = rtas_base; -+ exclude_range[i].end = rtas_base + rtas_size; -+ i++; -+ if (kexec_flags & KEXEC_ON_CRASH) -+ add_usable_mem_rgns(rtas_base, rtas_size); -+ } /* rtas */ -+ -+ if (strncmp(dentry->d_name, "memory@0", 8) == 0) { -+ strcat(fname, "/reg"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if ((n = fread(buf, 1, MAXBYTES, file)) < 0) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ rmo_base = ((unsigned long long *)buf)[0]; -+ rmo_top = rmo_base + ((unsigned long long *)buf)[1]; -+ if (platform == PLATFORM_PSERIES) { -+ if (rmo_top > 0x30000000UL) -+ rmo_top = 0x30000000UL; -+ } -+ fclose(file); -+ closedir(cdir); -+ } /* memory */ -+ -+ if (strncmp(dentry->d_name, "pci@", 4) == 0) { -+ if (platform != PLATFORM_PSERIES) { -+ closedir(cdir); -+ continue; -+ } -+ strcat(fname, "/linux,tce-base"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&tce_base, sizeof(unsigned long), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ memset(fname, 0, sizeof(fname)); -+ strcpy(fname, device_tree); -+ strcat(fname, dentry->d_name); -+ strcat(fname, "/linux,tce-size"); -+ if ((file = fopen(fname, "r")) == NULL) { -+ perror(fname); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ if (fread(&tce_size, sizeof(unsigned int), 1, file) != 1) { -+ perror(fname); -+ fclose(file); -+ closedir(cdir); -+ closedir(dir); -+ return -1; -+ } -+ /* Add tce to exclude_range - NON-LPAR only */ -+ exclude_range[i].start = tce_base; -+ exclude_range[i].end = tce_base + tce_size; -+ i++; -+ if (kexec_flags & KEXEC_ON_CRASH) -+ add_usable_mem_rgns(tce_base, tce_size); -+ closedir(cdir); -+ } /* pci */ -+ } -+ closedir(dir); -+ -+ nr_exclude_ranges = i; -+ -+ sort_ranges(); -+ -+ /* add crash_region and remove rtas range from exclude regions if it -+ * lies within crash region -+ */ -+ if (kexec_flags & KEXEC_ON_CRASH) { -+ unsigned long new_crash_size; -+ if (crash_base < rtas_base && -+ ((crash_base + crash_size) > (rtas_base + rtas_size))){ -+ new_crash_size = rtas_base - crash_base; -+ add_exclude_rgns(crash_base, new_crash_size); -+ new_crash_size = (crash_base + crash_size) - (rtas_base + rtas_size); -+ add_exclude_rgns(rtas_base + rtas_size, new_crash_size); -+ } else if (crash_base < rtas_base && -+ ((rtas_base + rtas_size) > (crash_base + crash_size))){ -+ new_crash_size = rtas_base - crash_base; -+ add_exclude_rgns(crash_base, new_crash_size); -+ } else if (crash_base > rtas_base && -+ ((rtas_base + rtas_size) < (crash_base + crash_size))){ -+ new_crash_size = (crash_base + crash_size) - (rtas_base + rtas_size); -+ add_exclude_rgns(rtas_base + rtas_size, new_crash_size); -+ } else -+ add_exclude_rgns(crash_base, crash_size); -+ } -+ -+#ifdef DEBUG -+ int k; -+ for (k = 0; k < i; k++) -+ fprintf(stderr, "exclude_range sorted exclude_range[%d] start:%lx, end:%lx\n", k, exclude_range[k].start, exclude_range[k].end); -+#endif -+ return 0; -+} -+ -+/* Setup a sorted list of memory ranges. */ -+int setup_memory_ranges(unsigned long kexec_flags) -+{ -+ int i, j = 0; -+ -+ /* Get the base list of memory ranges from /proc/device-tree/memory -+ * nodes. Build list of ranges to be excluded from valid memory -+ */ -+ -+ get_base_ranges(); -+ get_devtree_details(kexec_flags); -+ -+ for (i = 0; i < nr_exclude_ranges; i++) { -+ /* If first exclude range does not start with 0, include the -+ * first hole of valid memory from 0 - exclude_range[0].start -+ */ -+ if (i == 0) { -+ if (exclude_range[i].start != 0) { -+ memory_range[j].start = 0; -+ memory_range[j].end = exclude_range[i].start - 1; -+ memory_range[j].type = RANGE_RAM; -+ j++; -+ } -+ } /* i == 0 */ -+ /* If the last exclude range does not end at memory_max, include -+ * the last hole of valid memory from exclude_range[last].end - -+ * memory_max -+ */ -+ if (i == nr_exclude_ranges - 1) { -+ if (exclude_range[i].end < memory_max) { -+ memory_range[j].start = exclude_range[i].end + 1; -+ memory_range[j].end = memory_max; -+ memory_range[j].type = RANGE_RAM; -+ j++; -+ /* Limit the end to rmo_top */ -+ if (memory_range[j-1].start >= rmo_top) { -+ j--; -+ break; -+ } -+ if ((memory_range[j-1].start < rmo_top) && -+ (memory_range[j-1].end >= rmo_top)) { -+ memory_range[j-1].end = rmo_top; -+ break; -+ } -+ continue; -+ } -+ } /* i == nr_exclude_ranges - 1 */ -+ /* contiguous exclude ranges - skip */ -+ if (exclude_range[i+1].start == exclude_range[i].end + 1) -+ continue; -+ memory_range[j].start = exclude_range[i].end + 1; -+ memory_range[j].end = exclude_range[i+1].start - 1; -+ memory_range[j].type = RANGE_RAM; -+ j++; -+ /* Limit range to rmo_top */ -+ if (memory_range[j-1].start >= rmo_top) { -+ j--; -+ break; -+ } -+ if ((memory_range[j-1].start < rmo_top) && -+ (memory_range[j-1].end >= rmo_top)) { -+ memory_range[j-1].end = rmo_top; -+ break; -+ } -+ } -+ nr_memory_ranges = j; -+ -+#ifdef DEBUG -+ int k; -+ for (k = 0; k < j; k++) -+ fprintf(stderr, "setup_memory_ranges memory_range[%d] start:%lx, end:%lx\n", k, memory_range[k].start, memory_range[k].end); -+#endif -+ return 0; -+} -+ -+/* Return a list of valid memory ranges */ -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags) -+{ -+ setup_memory_ranges(kexec_flags); -+ *range = memory_range; -+ *ranges = nr_memory_ranges; -+ fprintf(stderr, "get memory ranges:%d\n", nr_memory_ranges); -+ return 0; -+} -+ -+struct file_type file_type[] = { -+ { "elf-ppc64", elf_ppc64_probe, elf_ppc64_load, elf_ppc64_usage }, -+}; -+int file_types = sizeof(file_type) / sizeof(file_type[0]); -+ -+void arch_usage(void) -+{ -+ fprintf(stderr, " --devicetreeblob= Specify device tree blob file.\n"); -+ fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n"); -+} -+ -+struct arch_options_t arch_options = { -+ .core_header_type = CORE_TYPE_ELF64, -+}; -+ -+int arch_process_options(int argc, char **argv) -+{ -+ static const struct option options[] = { -+ KEXEC_ARCH_OPTIONS -+ { 0, 0, NULL, 0 }, -+ }; -+ static const char short_options[] = KEXEC_ARCH_OPT_STR; -+ int opt; -+ -+ opterr = 0; /* Don't complain about unrecognized options here */ -+ while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { -+ switch(opt) { -+ default: -+ break; -+ case OPT_ELF64_CORE: -+ arch_options.core_header_type = CORE_TYPE_ELF64; -+ break; -+ } -+ } -+ /* Reset getopt for the next pass; called in other source modules */ -+ opterr = 1; -+ optind = 1; -+ return 0; -+} -+ -+int arch_compat_trampoline(struct kexec_info *info) -+{ -+ int result; -+ struct utsname utsname; -+ result = uname(&utsname); -+ if (result < 0) { -+ fprintf(stderr, "uname failed: %s\n", -+ strerror(errno)); -+ return -1; -+ } -+ if (strcmp(utsname.machine, "ppc64") == 0) -+ { -+ /* We are running a 32-bit kexec-tools on 64-bit ppc64. -+ * So pass KEXEC_ARCH_PPC64 here -+ */ -+ info->kexec_flags |= KEXEC_ARCH_PPC64; -+ } -+ else { -+ fprintf(stderr, "Unsupported machine type: %s\n", -+ utsname.machine); -+ return -1; -+ } -+ return 0; -+} -+ -+void arch_update_purgatory(struct kexec_info *info) -+{ -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.h kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-ppc64.h ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.h 2004-12-17 12:14:42.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-ppc64.h 2006-01-19 18:20:07.000000000 +0530 -@@ -1,9 +1,44 @@ - #ifndef KEXEC_PPC64_H - #define KEXEC_PPC64_H - -+#define MAX_MEMORY_RANGES 256 /* TO FIX - needs to be dynamically set */ -+#define MAXBYTES 128 -+#define MAX_LINE 160 -+#define CORE_TYPE_ELF32 1 -+#define CORE_TYPE_ELF64 2 -+ -+int setup_memory_ranges(unsigned long kexec_flags); -+ - int elf_ppc64_probe(const char *buf, off_t len); - int elf_ppc64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); - void elf_ppc64_usage(void); -+void reserve(unsigned long long where, unsigned long long length); -+ -+extern unsigned long initrd_base, initrd_size; -+/* boot block version 2 as defined by the linux kernel */ -+struct bootblock { -+ unsigned magic, -+ totalsize, -+ off_dt_struct, -+ off_dt_strings, -+ off_mem_rsvmap, -+ version, -+ last_comp_version, -+ boot_physid; -+}; -+ -+struct arch_options_t { -+ int core_header_type; -+}; -+ -+struct exclude_range { -+ unsigned long long start, end; -+}; -+ -+typedef struct mem_rgns { -+ unsigned int size; -+ struct exclude_range ranges[MAX_MEMORY_RANGES]; -+} mem_rgns_t; - --#endif /* KEXEC_PPC_H */ -+#endif /* KEXEC_PPC64_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/kexec-zImage-ppc64.c kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-zImage-ppc64.c ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-zImage-ppc64.c 2004-12-16 17:47:51.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/kexec-zImage-ppc64.c 2006-02-22 11:30:11.082107808 +0530 -@@ -153,7 +153,8 @@ int zImage_ppc64_load(FILE *file, int ar - return -1; - } - mem_offset = p->p_vaddr - load_loc; -- if (fread(segment->buf+mem_offset, p->p_filesz, 1, file) != 1) { -+ if (fread((void *)segment->buf+mem_offset, p->p_filesz, 1, -+ file) != 1) { - perror("read error: "); - return -1; - } -@@ -161,7 +162,7 @@ int zImage_ppc64_load(FILE *file, int ar - segment->mem = (void *) load_loc; - segment->memsz = memsize; - segment->bufsz = filesize; -- *ret_entry = elf.e_entry; -+ *ret_entry = (void *)((uint64_t)elf.e_entry); - *ret_nr_segments = i - 1; - free(ph); - return 0; -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/ppc64/Makefile kexec-tools-1.101-kdump/kexec/arch/ppc64/Makefile ---- kexec-tools-1.101/kexec/arch/ppc64/Makefile 2004-12-17 12:05:30.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/ppc64/Makefile 2006-01-19 18:20:06.000000000 +0530 -@@ -2,6 +2,10 @@ - # kexec ppc64 (linux booting linux) - # - KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-elf-rel-ppc64.c --KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-zImage-ppc64.c -+KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-zImage-ppc64.c -+KEXEC_C_SRCS+= kexec/arch/ppc64/fs2dt.c -+KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-elf-ppc64.c -+KEXEC_C_SRCS+= kexec/arch/ppc64/kexec-ppc64.c -+KEXEC_C_SRCS+= kexec/arch/ppc64/crashdump-ppc64.c - - KEXEC_S_SRCS+= -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/s390/include/arch/options.h kexec-tools-1.101-kdump/kexec/arch/s390/include/arch/options.h ---- kexec-tools-1.101/kexec/arch/s390/include/arch/options.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/s390/include/arch/options.h 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,11 @@ -+#ifndef KEXEC_ARCH_S390_OPTIONS_H -+#define KEXEC_ARCH_S390_OPTIONS_H -+ -+#define OPT_ARCH_MAX (OPT_MAX+0) -+ -+#define KEXEC_ARCH_OPTIONS \ -+ KEXEC_OPTIONS \ -+ -+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR "" -+ -+#endif /* KEXEC_ARCH_S390_OPTIONS_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/s390/kexec-elf-rel-s390.c kexec-tools-1.101-kdump/kexec/arch/s390/kexec-elf-rel-s390.c ---- kexec-tools-1.101/kexec/arch/s390/kexec-elf-rel-s390.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/s390/kexec-elf-rel-s390.c 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,23 @@ -+/* -+ * kexec/arch/s390/kexec-elf-rel-s390.c -+ * -+ * (C) Copyright IBM Corp. 2005 -+ * -+ * Author(s): Heiko Carstens -+ * -+ */ -+ -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-elf.h" -+ -+int machine_verify_elf_rel(struct mem_ehdr *ehdr) -+{ -+ return 0; -+} -+ -+void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, -+ void *location, unsigned long address, unsigned long value) -+{ -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/s390/kexec-image.c kexec-tools-1.101-kdump/kexec/arch/s390/kexec-image.c ---- kexec-tools-1.101/kexec/arch/s390/kexec-image.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/s390/kexec-image.c 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,137 @@ -+/* -+ * kexec/arch/s390/kexec-image.c -+ * -+ * (C) Copyright IBM Corp. 2005 -+ * -+ * Author(s): Rolf Adelsberger -+ * Heiko Carstens -+ * -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "kexec-s390.h" -+ -+#define OPT_APPEND OPT_MAX+0 -+#define OPT_RAMDISK OPT_MAX+1 -+ -+int -+image_s390_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info) -+{ -+ void *krnl_buffer; -+ char *rd_buffer; -+ const char *command_line; -+ const char *ramdisk; -+ int command_line_len; -+ off_t ramdisk_len; -+ unsigned int ramdisk_origin; -+ int opt; -+ -+ static const struct option options[] = -+ { -+ KEXEC_OPTIONS -+ {"command-line", 1, 0, OPT_APPEND}, -+ {"initrd", 1, 0, OPT_RAMDISK}, -+ {0, 0, 0, 0}, -+ }; -+ static const char short_options[] = KEXEC_OPT_STR ""; -+ -+ ramdisk = NULL; -+ command_line = NULL; -+ ramdisk_len = 0; -+ ramdisk_origin = 0; -+ -+ while ((opt = getopt_long(argc,argv,short_options,options,0)) != -1) { -+ switch(opt) { -+ case '?': -+ usage(); -+ return -1; -+ break; -+ case OPT_APPEND: -+ command_line = optarg; -+ break; -+ case OPT_RAMDISK: -+ ramdisk = optarg; -+ break; -+ } -+ } -+ -+ /* Process a given command_line: */ -+ if (command_line) { -+ command_line_len = strlen(command_line) + 1; /* Remember the '\0' */ -+ if (command_line_len > COMMAND_LINESIZE) { -+ fprintf(stderr, "Command line too long.\n"); -+ return -1; -+ } -+ } -+ -+ /* Add kernel segment */ -+ add_segment(info, kernel_buf + IMAGE_READ_OFFSET, -+ kernel_size - IMAGE_READ_OFFSET, IMAGE_READ_OFFSET, -+ kernel_size - IMAGE_READ_OFFSET); -+ -+ /* We do want to change the kernel image */ -+ krnl_buffer = (void *) kernel_buf + IMAGE_READ_OFFSET; -+ -+ /* Load ramdisk if present */ -+ if (ramdisk) { -+ rd_buffer = slurp_file(ramdisk, &ramdisk_len); -+ if (rd_buffer == NULL) { -+ fprintf(stderr, "Could not read ramdisk.\n"); -+ return -1; -+ } -+ ramdisk_origin = RAMDISK_ORIGIN_ADDR; -+ add_segment(info, rd_buffer, ramdisk_len, RAMDISK_ORIGIN_ADDR, ramdisk_len); -+ } -+ -+ /* Register the ramdisk in the kernel. */ -+ { -+ unsigned long long *tmp; -+ -+ tmp = krnl_buffer + INITRD_START_OFFS; -+ *tmp = (unsigned long long) ramdisk_origin; -+ -+ tmp = krnl_buffer + INITRD_SIZE_OFFS; -+ *tmp = (unsigned long long) ramdisk_len; -+ } -+ -+ /* -+ * We will write a probably given command line. -+ * First, erase the old area, then setup the new parameters: -+ */ -+ if (command_line) { -+ memset(krnl_buffer + COMMAND_LINE_OFFS, 0, COMMAND_LINESIZE); -+ memcpy(krnl_buffer + COMMAND_LINE_OFFS, command_line, strlen(command_line)); -+ } -+ -+ info->entry = (void *) IMAGE_READ_OFFSET; -+ -+ return 0; -+} -+ -+int -+image_s390_probe(const char *kernel_buf, off_t kernel_size) -+{ -+ /* -+ * Can't reliably tell if an image is valid, -+ * therefore everything is valid. -+ */ -+ return 0; -+} -+ -+void -+image_s390_usage(void) -+{ -+ printf("--command-line=STRING Pass a custom command line STRING to the kernel.\n" -+ "--initrd=FILENAME Use the file FILENAME as a ramdisk.\n" -+ ); -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/s390/kexec-s390.c kexec-tools-1.101-kdump/kexec/arch/s390/kexec-s390.c ---- kexec-tools-1.101/kexec/arch/s390/kexec-s390.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/s390/kexec-s390.c 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,104 @@ -+/* -+ * kexec/arch/s390/kexec-s390.c -+ * -+ * (C) Copyright IBM Corp. 2005 -+ * -+ * Author(s): Rolf Adelsberger -+ * -+ */ -+ -+#define _GNU_SOURCE -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-syscall.h" -+#include "kexec-s390.h" -+#include -+ -+#define MAX_MEMORY_RANGES 64 -+static struct memory_range memory_range[MAX_MEMORY_RANGES]; -+ -+/* -+ * get_memory_ranges: -+ * Return a list of memory ranges by parsing /proc/iomem -+ * -+ * INPUT: -+ * - Pointer to an array of memory_range structures. -+ * - Pointer to an integer with holds the number of memory ranges. -+ * -+ * RETURN: -+ * - 0 on normal execution. -+ * - (-1) if something went wrong. -+ */ -+ -+int get_memory_ranges(struct memory_range **range, int *ranges) -+{ -+ char sys_ram[] = "System RAM\n"; -+ char iomem[] = "/proc/iomem"; -+ FILE *fp; -+ char line[80]; -+ int current_range = 0; -+ -+ fp = fopen(iomem,"r"); -+ if(fp == 0) { -+ fprintf(stderr,"Unable to open %s: %s\n",iomem,strerror(errno)); -+ return -1; -+ } -+ -+ /* Setup the compare string properly. */ -+ while(fgets(line,sizeof(line),fp) != 0) { -+ unsigned long long start, end; -+ int cons; -+ char *str; -+ -+ if (current_range == MAX_MEMORY_RANGES) -+ break; -+ -+ sscanf(line,"%Lx-%Lx : %n", &start, &end, &cons); -+ str = line+cons; -+ if(memcmp(str,sys_ram,strlen(sys_ram)) == 0) { -+ memory_range[current_range].start = start; -+ memory_range[current_range].end = end; -+ memory_range[current_range].type = RANGE_RAM; -+ current_range++; -+ } -+ else { -+ continue; -+ } -+ } -+ fclose(fp); -+ *range = memory_range; -+ *ranges = current_range; -+ -+ return 0; -+} -+ -+/* Supported file types and callbacks */ -+struct file_type file_type[] = { -+ { "image", image_s390_probe, image_s390_load, image_s390_usage}, -+}; -+int file_types = sizeof(file_type) / sizeof(file_type[0]); -+ -+ -+void arch_usage(void) -+{ -+} -+ -+int arch_process_options(int argc, char **argv) -+{ -+ return 0; -+} -+ -+int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+{ -+ return 0; -+} -+ -+void arch_update_purgatory(struct kexec_info *info) -+{ -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/s390/kexec-s390.h kexec-tools-1.101-kdump/kexec/arch/s390/kexec-s390.h ---- kexec-tools-1.101/kexec/arch/s390/kexec-s390.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/s390/kexec-s390.h 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,25 @@ -+/* -+ * kexec/arch/s390/kexec-s390.h -+ * -+ * (C) Copyright IBM Corp. 2005 -+ * -+ * Author(s): Rolf Adelsberger -+ * -+ */ -+ -+#ifndef KEXEC_S390_H -+#define KEXEC_S390_H -+ -+#define IMAGE_READ_OFFSET 0x10000 -+ -+#define RAMDISK_ORIGIN_ADDR 0x800000 -+#define INITRD_START_OFFS 0x408 -+#define INITRD_SIZE_OFFS 0x410 -+#define COMMAND_LINE_OFFS 0x480 -+#define COMMAND_LINESIZE 896 -+ -+extern int image_s390_load(int, char **, const char *, off_t, struct kexec_info *); -+extern int image_s390_probe(const char *, off_t); -+extern void image_s390_usage(void); -+ -+#endif /* KEXEC_IA64_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/s390/Makefile kexec-tools-1.101-kdump/kexec/arch/s390/Makefile ---- kexec-tools-1.101/kexec/arch/s390/Makefile 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/s390/Makefile 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,6 @@ -+# -+# kexec s390 (linux booting linux) -+# -+KEXEC_C_SRCS+= kexec/arch/s390/kexec-s390.c -+KEXEC_C_SRCS+= kexec/arch/s390/kexec-image.c -+KEXEC_C_SRCS+= kexec/arch/s390/kexec-elf-rel-s390.c -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c kexec-tools-1.101-kdump/kexec/arch/x86_64/crashdump-x86_64.c ---- kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/x86_64/crashdump-x86_64.c 2006-02-19 11:13:06.000000000 +0530 -@@ -0,0 +1,655 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: Murali M Chakravarthy (muralim@in.ibm.com) -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * Heavily borrowed from kexec/arch/i386/crashdump-x86.c -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "../../kexec.h" -+#include "../../kexec-elf.h" -+#include "../../kexec-syscall.h" -+#include "../../crashdump.h" -+#include "kexec-x86_64.h" -+#include "crashdump-x86_64.h" -+#include -+ -+extern struct arch_options_t arch_options; -+ -+/* Forward Declaration. */ -+static int exclude_crash_reserve_region(int *nr_ranges); -+ -+/* Stores a sorted list of RAM memory ranges for which to create elf headers. -+ * A separate program header is created for backup region */ -+static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; -+ -+/* Memory region reserved for storing panic kernel and other data. */ -+static struct memory_range crash_reserved_mem; -+ -+/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to -+ * create Elf headers. Keeping it separate from get_memory_ranges() as -+ * requirements are different in the case of normal kexec and crashdumps. -+ * -+ * Normal kexec needs to look at all of available physical memory irrespective -+ * of the fact how much of it is being used by currently running kernel. -+ * Crashdumps need to have access to memory regions actually being used by -+ * running kernel. Expecting a different file/data structure than /proc/iomem -+ * 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) -+{ -+ const char iomem[]= "/proc/iomem"; -+ int memory_ranges = 0; -+ char line[MAX_LINE]; -+ FILE *fp; -+ unsigned long long start, end; -+ -+ fp = fopen(iomem, "r"); -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", -+ iomem, strerror(errno)); -+ return -1; -+ } -+ -+ /* 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++; -+ -+ while(fgets(line, sizeof(line), fp) != 0) { -+ char *str; -+ int type, consumed, count; -+ if (memory_ranges >= CRASH_MAX_MEMORY_RANGES) -+ break; -+ count = sscanf(line, "%Lx-%Lx : %n", -+ &start, &end, &consumed); -+ if (count != 2) -+ continue; -+ str = line + consumed; -+#if 0 -+ printf("%016Lx-%016Lx : %s", -+ start, end, str); -+#endif -+ /* Only Dumping memory of type System RAM. */ -+ if (memcmp(str, "System RAM\n", 11) == 0) { -+ type = RANGE_RAM; -+ } else if (memcmp(str, "Crash kernel\n", 13) == 0) { -+ /* Reserved memory region. New kernel can -+ * use this region to boot into. */ -+ crash_reserved_mem.start = start; -+ crash_reserved_mem.end = end; -+ crash_reserved_mem.type = RANGE_RAM; -+ continue; -+ } else if (memcmp(str, "ACPI Tables\n", 12) == 0) { -+ /* -+ * ACPI Tables area need to be passed to new -+ * kernel with appropriate memmap= option. This -+ * is needed so that x86_64 kernel creates linear -+ * mapping for this region which is required for -+ * initializing acpi tables in second kernel. -+ */ -+ type = RANGE_ACPI; -+ } else { -+ continue; -+ } -+ -+ /* First 640K already registered */ -+ if (start >= 0x00000000 && end <= 0x0009ffff) -+ continue; -+ -+ crash_memory_range[memory_ranges].start = start; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = type; -+ memory_ranges++; -+ -+ /* Segregate linearly mapped region. */ -+ if ((MAXMEM - 1) >= start && (MAXMEM - 1) <= end) { -+ crash_memory_range[memory_ranges-1].end = MAXMEM -1; -+ -+ /* Add segregated region. */ -+ crash_memory_range[memory_ranges].start = MAXMEM; -+ crash_memory_range[memory_ranges].end = end; -+ crash_memory_range[memory_ranges].type = type; -+ memory_ranges++; -+ } -+ } -+ fclose(fp); -+ if (exclude_crash_reserve_region(&memory_ranges) < 0) -+ return -1; -+ *range = crash_memory_range; -+ *ranges = memory_ranges; -+#if 0 -+ int i; -+ printf("CRASH MEMORY RANGES\n"); -+ for(i = 0; i < memory_ranges; i++) { -+ start = crash_memory_range[i].start; -+ end = crash_memory_range[i].end; -+ printf("%016Lx-%016Lx\n", start, end); -+ } -+#endif -+ return 0; -+} -+ -+/* Removes crash reserve region from list of memory chunks for whom elf program -+ * headers have to be created. Assuming crash reserve region to be a single -+ * continuous area fully contained inside one of the memory chunks */ -+static int exclude_crash_reserve_region(int *nr_ranges) -+{ -+ int i, j, tidx = -1; -+ unsigned long long cstart, cend; -+ struct memory_range temp_region; -+ -+ /* Crash reserved region. */ -+ cstart = crash_reserved_mem.start; -+ cend = crash_reserved_mem.end; -+ -+ for (i = 0; i < (*nr_ranges); i++) { -+ unsigned long long mstart, mend; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (cstart < mend && cend > mstart) { -+ if (cstart != mstart && cend != mend) { -+ /* Split memory region */ -+ crash_memory_range[i].end = cstart - 1; -+ temp_region.start = cend + 1; -+ temp_region.end = mend; -+ temp_region.type = RANGE_RAM; -+ tidx = i+1; -+ } else if (cstart != mstart) -+ crash_memory_range[i].end = cstart - 1; -+ else -+ crash_memory_range[i].start = cend + 1; -+ } -+ } -+ /* Insert split memory region, if any. */ -+ if (tidx >= 0) { -+ if (*nr_ranges == CRASH_MAX_MEMORY_RANGES) { -+ /* No space to insert another element. */ -+ fprintf(stderr, "Error: Number of crash memory ranges" -+ " excedeed the max limit\n"); -+ return -1; -+ } -+ for (j = (*nr_ranges - 1); j >= tidx; j--) -+ crash_memory_range[j+1] = crash_memory_range[j]; -+ crash_memory_range[tidx].start = temp_region.start; -+ crash_memory_range[tidx].end = temp_region.end; -+ crash_memory_range[tidx].type = temp_region.type; -+ (*nr_ranges)++; -+ } -+ return 0; -+} -+ -+/* Adds a segment from list of memory regions which new kernel can use to -+ * boot. Segment start and end should be aligned to 1K boundary. */ -+static int add_memmap(struct memory_range *memmap_p, unsigned long long addr, -+ size_t size) -+{ -+ int i, j, nr_entries = 0, tidx = 0, align = 1024; -+ unsigned long long mstart, mend; -+ -+ /* Do alignment check. */ -+ if ((addr%align) || (size%align)) -+ return -1; -+ -+ /* Make sure at least one entry in list is free. */ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (!mstart && !mend) -+ break; -+ else -+ nr_entries++; -+ } -+ if (nr_entries == CRASH_MAX_MEMMAP_NR) -+ return -1; -+ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) -+ break; -+ if (mstart <= (addr+size-1) && mend >=addr) -+ /* Overlapping region. */ -+ return -1; -+ else if (addr > mend) -+ tidx = i+1; -+ } -+ /* Insert the memory region. */ -+ for (j = nr_entries-1; j >= tidx; j--) -+ memmap_p[j+1] = memmap_p[j]; -+ memmap_p[tidx].start = addr; -+ memmap_p[tidx].end = addr + size - 1; -+#if 0 -+ printf("Memmap after adding segment\n"); -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) -+ break; -+ printf("%016llx - %016llx\n", -+ mstart, mend); -+ } -+#endif -+ return 0; -+} -+ -+/* Removes a segment from list of memory regions which new kernel can use to -+ * boot. Segment start and end should be aligned to 1K boundary. */ -+static int delete_memmap(struct memory_range *memmap_p, unsigned long long addr, -+ size_t size) -+{ -+ int i, j, nr_entries = 0, tidx = -1, operation = 0, align = 1024; -+ unsigned long long mstart, mend; -+ struct memory_range temp_region; -+ -+ /* Do alignment check. */ -+ if ((addr%align) || (size%align)) -+ return -1; -+ -+ /* Make sure at least one entry in list is free. */ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (!mstart && !mend) -+ break; -+ else -+ nr_entries++; -+ } -+ if (nr_entries == CRASH_MAX_MEMMAP_NR) -+ /* List if full */ -+ return -1; -+ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) -+ /* Did not find the segment in the list. */ -+ return -1; -+ if (mstart <= addr && mend >= (addr + size - 1)) { -+ if (mstart == addr && mend == (addr + size - 1)) { -+ /* Exact match. Delete region */ -+ operation = -1; -+ tidx = i; -+ break; -+ } -+ if (mstart != addr && mend != (addr + size - 1)) { -+ /* Split in two */ -+ memmap_p[i].end = addr - 1; -+ temp_region.start = addr + size; -+ temp_region.end = mend; -+ operation = 1; -+ tidx = i; -+ break; -+ } -+ -+ /* No addition/deletion required. Adjust the existing.*/ -+ if (mstart != addr) { -+ memmap_p[i].end = addr - 1; -+ break; -+ } else { -+ memmap_p[i].start = addr + size; -+ break; -+ } -+ } -+ } -+ if ((operation == 1) && tidx >=0) { -+ /* Insert the split memory region. */ -+ for (j = nr_entries-1; j > tidx; j--) -+ memmap_p[j+1] = memmap_p[j]; -+ memmap_p[tidx+1] = temp_region; -+ } -+ if ((operation == -1) && tidx >=0) { -+ /* Delete the exact match memory region. */ -+ for (j = i+1; j < CRASH_MAX_MEMMAP_NR; j++) -+ memmap_p[j-1] = memmap_p[j]; -+ memmap_p[j-1].start = memmap_p[j-1].end = 0; -+ } -+#if 0 -+ printf("Memmap after deleting segment\n"); -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ mstart = memmap_p[i].start; -+ mend = memmap_p[i].end; -+ if (mstart == 0 && mend == 0) { -+ break; -+ } -+ printf("%016llx - %016llx\n", -+ mstart, mend); -+ } -+#endif -+ return 0; -+} -+ -+/* Converts unsigned long to ascii string. */ -+static void ultoa(unsigned long i, char *str) -+{ -+ int j = 0, k; -+ char tmp; -+ -+ do { -+ str[j++] = i % 10 + '0'; -+ } while ((i /=10) > 0); -+ str[j] = '\0'; -+ -+ /* Reverse the string. */ -+ for (j = 0, k = strlen(str) - 1; j < k; j++, k--) { -+ tmp = str[k]; -+ str[k] = str[j]; -+ str[j] = tmp; -+ } -+} -+ -+/* Adds the appropriate memmap= options to command line, indicating the -+ * memory regions the new kernel can use to boot into. */ -+static int cmdline_add_memmap(char *cmdline, struct memory_range *memmap_p) -+{ -+ int i, cmdlen, len, min_sizek = 100; -+ char str_mmap[256], str_tmp[20]; -+ -+ /* Exact map */ -+ strcpy(str_mmap, " memmap=exactmap"); -+ len = strlen(str_mmap); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str_mmap); -+ -+ for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { -+ unsigned long startk, endk; -+ startk = (memmap_p[i].start/1024); -+ endk = ((memmap_p[i].end + 1)/1024); -+ if (!startk && !endk) -+ /* All regions traversed. */ -+ break; -+ -+ /* A region is not worth adding if region size < 100K. It eats -+ * up precious command line length. */ -+ if ((endk - startk) < min_sizek) -+ continue; -+ strcpy (str_mmap, " memmap="); -+ ultoa((endk-startk), str_tmp); -+ strcat (str_mmap, str_tmp); -+ strcat (str_mmap, "K@"); -+ ultoa(startk, str_tmp); -+ strcat (str_mmap, str_tmp); -+ strcat (str_mmap, "K"); -+ len = strlen(str_mmap); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str_mmap); -+ } -+#if 0 -+ printf("Command line after adding memmap\n"); -+ printf("%s\n", cmdline); -+#endif -+ return 0; -+} -+ -+/* Adds the elfcorehdr= command line parameter to command line. */ -+static int cmdline_add_elfcorehdr(char *cmdline, unsigned long addr) -+{ -+ int cmdlen, len, align = 1024; -+ char str[30], *ptr; -+ -+ /* Passing in elfcorehdr=xxxK format. Saves space required in cmdline. -+ * Ensure 1K alignment*/ -+ if (addr%align) -+ return -1; -+ addr = addr/align; -+ ptr = str; -+ strcpy(str, " elfcorehdr="); -+ ptr += strlen(str); -+ ultoa(addr, ptr); -+ strcat(str, "K"); -+ len = strlen(str); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str); -+#if 0 -+ printf("Command line after adding elfcorehdr\n"); -+ printf("%s\n", cmdline); -+#endif -+ return 0; -+} -+ -+/* Appends memmap=X#Y commandline for ACPI to command line*/ -+static int cmdline_add_memmap_acpi(char *cmdline, unsigned long start, -+ unsigned long end) -+{ -+ int cmdlen, len, align = 1024; -+ unsigned long startk, endk; -+ char str_mmap[256], str_tmp[20]; -+ -+ if (!(end - start)) -+ return 0; -+ -+ startk = start/1024; -+ endk = (end + align - 1)/1024; -+ strcpy (str_mmap, " memmap="); -+ ultoa((endk - startk), str_tmp); -+ strcat (str_mmap, str_tmp); -+ strcat (str_mmap, "K#"); -+ ultoa(startk, str_tmp); -+ strcat (str_mmap, str_tmp); -+ strcat (str_mmap, "K"); -+ len = strlen(str_mmap); -+ cmdlen = strlen(cmdline) + len; -+ if (cmdlen > (COMMAND_LINE_SIZE - 1)) -+ die("Command line overflow\n"); -+ strcat(cmdline, str_mmap); -+ -+#if 0 -+ printf("Command line after adding acpi memmap\n"); -+ printf("%s\n", cmdline); -+#endif -+ return 0; -+} -+ -+/* Prepares the crash memory elf64 headers and stores in supplied buffer. */ -+static int prepare_crash_memory_elf64_headers(struct kexec_info *info, -+ void *buf, unsigned long size) -+{ -+ Elf64_Ehdr *elf; -+ Elf64_Phdr *phdr; -+ int i; -+ char *bufp; -+ long int nr_cpus = 0; -+ uint64_t notes_addr; -+ -+ bufp = (char*) buf; -+ -+ /* Setup ELF Header*/ -+ elf = (Elf64_Ehdr *) bufp; -+ bufp += sizeof(Elf64_Ehdr); -+ memcpy(elf->e_ident, ELFMAG, SELFMAG); -+ elf->e_ident[EI_CLASS] = ELFCLASS64; -+ elf->e_ident[EI_DATA] = ELFDATA2LSB; -+ elf->e_ident[EI_VERSION]= EV_CURRENT; -+ elf->e_ident[EI_OSABI] = ELFOSABI_NONE; -+ memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); -+ elf->e_type = ET_CORE; -+ elf->e_machine = EM_X86_64; -+ elf->e_version = EV_CURRENT; -+ elf->e_entry = 0; -+ elf->e_phoff = sizeof(Elf64_Ehdr); -+ elf->e_shoff = 0; -+ elf->e_flags = 0; -+ elf->e_ehsize = sizeof(Elf64_Ehdr); -+ elf->e_phentsize= sizeof(Elf64_Phdr); -+ elf->e_phnum = 0; -+ elf->e_shentsize= 0; -+ elf->e_shnum = 0; -+ elf->e_shstrndx = 0; -+ -+ /* PT_NOTE program headers. One per cpu*/ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ return -1; -+ } -+ -+ /* Need to find a better way to determine per cpu notes section size. */ -+#define MAX_NOTE_BYTES 1024 -+ for (i = 0; i < nr_cpus; i++) { -+ if (get_crash_notes_per_cpu(i, ¬es_addr) < 0) { -+ /* This cpu is not present. Skip it. */ -+ continue; -+ } -+ -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_NOTE; -+ phdr->p_flags = 0; -+ phdr->p_offset = phdr->p_paddr = notes_addr; -+ phdr->p_vaddr = 0; -+ phdr->p_filesz = phdr->p_memsz = MAX_NOTE_BYTES; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ -+ /* Setup PT_LOAD type program header for every system RAM chunk. -+ * A seprate program header for Backup Region*/ -+ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -+ unsigned long long mstart, mend; -+ if (crash_memory_range[i].type != RANGE_RAM) -+ continue; -+ mstart = crash_memory_range[i].start; -+ mend = crash_memory_range[i].end; -+ if (!mstart && !mend) -+ continue; -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ if (mstart == BACKUP_START && mend == BACKUP_END) -+ phdr->p_offset = info->backup_start; -+ else -+ phdr->p_offset = mstart; -+ -+ /* Handle linearly mapped region.*/ -+ -+ /* Filling the vaddr conditionally as we have two linearly -+ * mapped regions here. One is __START_KERNEL_map 0 to 40 MB -+ * other one is PAGE_OFFSET */ -+ -+ if ((mend <= (MAXMEM - 1)) && mstart < KERNEL_TEXT_SIZE) -+ phdr->p_vaddr = mstart + __START_KERNEL_map; -+ else { -+ if (mend <= (MAXMEM - 1)) -+ phdr->p_vaddr = mstart + PAGE_OFFSET; -+ else -+ phdr->p_vaddr = -1ULL; -+ } -+ phdr->p_paddr = mstart; -+ phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; -+ /* Do we need any alignment of segments? */ -+ phdr->p_align = 0; -+ -+ /* Increment number of program headers. */ -+ (elf->e_phnum)++; -+ } -+ return 0; -+} -+ -+/* Loads additional segments in case of a panic kernel is being loaded. -+ * One segment for backup region, another segment for storing elf headers -+ * for crash memory image. -+ */ -+int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline, -+ unsigned long max_addr, unsigned long min_base) -+{ -+ void *tmp; -+ unsigned long sz, elfcorehdr; -+ int nr_ranges, align = 1024, i; -+ long int nr_cpus = 0; -+ struct memory_range *mem_range, *memmap_p; -+ -+ if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) -+ return -1; -+ -+ /* Memory regions which panic kernel can safely use to boot into */ -+ sz = (sizeof(struct memory_range) * (KEXEC_MAX_SEGMENTS + 1)); -+ memmap_p = xmalloc(sz); -+ memset(memmap_p, 0, sz); -+ add_memmap(memmap_p, BACKUP_START, BACKUP_SIZE); -+ sz = crash_reserved_mem.end - crash_reserved_mem.start +1; -+ add_memmap(memmap_p, crash_reserved_mem.start, sz); -+ -+ /* Create a backup region segment to store backup data*/ -+ sz = (BACKUP_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. */ -+ nr_cpus = sysconf(_SC_NPROCESSORS_CONF); -+ if (nr_cpus < 0) { -+ fprintf(stderr,"kexec_load (elf header segment)" -+ " failed: %s\n", strerror(errno)); -+ return -1; -+ } -+ sz = sizeof(Elf64_Ehdr) + nr_cpus * sizeof(Elf64_Phdr) + -+ nr_ranges * sizeof(Elf64_Phdr); -+ sz = (sz + align - 1) & ~(align -1); -+ tmp = xmalloc(sz); -+ memset(tmp, 0, sz); -+ -+ /* Prepare ELF64 core heaers. */ -+ if (prepare_crash_memory_elf64_headers(info, tmp, sz) < 0) -+ return -1; -+ -+ /* Hack: With some ld versions (GNU ld version 2.14.90.0.4 20030523), -+ * vmlinux program headers show a gap of two pages between bss segment -+ * and data segment but effectively kernel considers it as bss segment -+ * and overwrites the any data placed there. Hence bloat the memsz of -+ * elf core header segment to 16K to avoid being placed in such gaps. -+ * This is a makeshift solution until it is fixed in kernel. -+ */ -+ elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, -+ max_addr, 1); -+ if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) -+ return -1; -+ cmdline_add_memmap(mod_cmdline, memmap_p); -+ cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr); -+ -+ /* Inform second kernel about the presence of ACPI tables. */ -+ for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -+ unsigned long start, end; -+ if (mem_range[i].type != RANGE_ACPI) -+ continue; -+ start = mem_range[i].start; -+ end = mem_range[i].end; -+ cmdline_add_memmap_acpi(mod_cmdline, start, end); -+ } -+ return 0; -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.h kexec-tools-1.101-kdump/kexec/arch/x86_64/crashdump-x86_64.h ---- kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/x86_64/crashdump-x86_64.h 2006-01-19 11:41:40.000000000 +0530 -@@ -0,0 +1,24 @@ -+#ifndef CRASHDUMP_X86_64_H -+#define CRASHDUMP_X86_64_H -+ -+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline, -+ unsigned long max_addr, unsigned long min_base); -+ -+#define __START_KERNEL_map 0xffffffff80000000UL -+#define PAGE_OFFSET 0xffff810000000000UL -+#define __pa(x) (((unsigned long)(x)>=__START_KERNEL_map)?(unsigned long)(x) - (unsigned long)__START_KERNEL_map:(unsigned long)(x) - PAGE_OFFSET) -+ -+#define MAXMEM 0x3fffffffffffUL -+ -+/* Kernel text size */ -+#define KERNEL_TEXT_SIZE (40UL*1024*1024) -+ -+#define CRASH_MAX_MEMMAP_NR (KEXEC_MAX_SEGMENTS + 1) -+#define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 2) -+ -+/* Backup Region, First 640K of System RAM. */ -+#define BACKUP_START 0x00000000 -+#define BACKUP_END 0x0009ffff -+#define BACKUP_SIZE (BACKUP_END - BACKUP_START + 1) -+ -+#endif /* CRASHDUMP_X86_64_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c kexec-tools-1.101-kdump/kexec/arch/x86_64/kexec-elf-x86_64.c ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c 2005-01-13 18:40:54.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/x86_64/kexec-elf-x86_64.c 2006-01-19 11:41:42.000000000 +0530 -@@ -32,10 +32,12 @@ - #include - #include - #include "../../kexec.h" -+#include "../../kexec-syscall.h" - #include "../../kexec-elf.h" - #include "../../kexec-elf-boot.h" - #include "../i386/x86-linux-setup.h" - #include "kexec-x86_64.h" -+#include "crashdump-x86_64.h" - #include - - static const int probe_debug = 0; -@@ -85,7 +87,9 @@ int elf_x86_64_load(int argc, char **arg - { - struct mem_ehdr ehdr; - const char *command_line; -+ char *modified_cmdline; - int command_line_len; -+ int modified_cmdline_len; - const char *ramdisk; - unsigned long entry, max_addr; - int arg_style; -@@ -118,6 +122,8 @@ int elf_x86_64_load(int argc, char **arg - */ - arg_style = ARG_STYLE_ELF; - command_line = 0; -+ modified_cmdline = 0; -+ modified_cmdline_len = 0; - ramdisk = 0; - while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { - switch(opt) { -@@ -156,6 +162,20 @@ int elf_x86_64_load(int argc, char **arg - command_line_len = strlen(command_line) +1; - } - -+ /* Need to append some command line parameters internally in case of -+ * taking crash dumps. -+ */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ modified_cmdline = xmalloc(COMMAND_LINE_SIZE); -+ memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); -+ if (command_line) { -+ strncpy(modified_cmdline, command_line, -+ COMMAND_LINE_SIZE); -+ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; -+ } -+ modified_cmdline_len = strlen(modified_cmdline); -+ } -+ - /* Load the ELF executable */ - elf_exec_build_load(info, &ehdr, buf, len); - -@@ -197,6 +217,7 @@ int elf_x86_64_load(int argc, char **arg - const unsigned char *ramdisk_buf; - off_t ramdisk_length; - struct entry64_regs regs; -+ int rc=0; - - /* Get the linux parameter header */ - hdr = xmalloc(sizeof(*hdr)); -@@ -210,9 +231,19 @@ int elf_x86_64_load(int argc, char **arg - /* Add a ramdisk to the current image */ - ramdisk_buf = 0; - ramdisk_length = 0; -- if (ramdisk) { -- unsigned char *ramdisk_buf; -+ if (ramdisk) - ramdisk_buf = slurp_file(ramdisk, &ramdisk_length); -+ -+ /* If panic kernel is being loaded, additional segments need -+ * to be created. */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ rc = load_crashdump_segments(info, modified_cmdline, -+ max_addr, 0); -+ if (rc < 0) -+ return -1; -+ /* Use new command line. */ -+ command_line = modified_cmdline; -+ command_line_len = strlen(modified_cmdline) + 1; - } - - /* Tell the kernel what is going on */ -@@ -222,7 +253,7 @@ int elf_x86_64_load(int argc, char **arg - ramdisk_buf, ramdisk_length); - - /* Fill in the information bios calls would usually provide */ -- setup_linux_system_parameters(&hdr->hdr); -+ setup_linux_system_parameters(&hdr->hdr, info->kexec_flags); - - /* Initialize the registers */ - elf_rel_get_symbol(&info->rhdr, "entry64_regs", ®s, sizeof(regs)); -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c kexec-tools-1.101-kdump/kexec/arch/x86_64/kexec-x86_64.c ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c 2005-02-06 04:55:01.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/x86_64/kexec-x86_64.c 2006-02-19 11:11:37.000000000 +0530 -@@ -30,14 +30,15 @@ - #include "../../kexec-elf.h" - #include "../../kexec-syscall.h" - #include "kexec-x86_64.h" -+#include "crashdump-x86_64.h" - #include - - #define MAX_MEMORY_RANGES 64 --#define MAX_LINE 160 - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - - /* Return a sorted list of memory ranges. */ --int get_memory_ranges(struct memory_range **range, int *ranges) -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags) - { - const char iomem[]= "/proc/iomem"; - int memory_ranges = 0; -@@ -79,6 +80,20 @@ int get_memory_ranges(struct memory_rang - else if (memcmp(str, "ACPI Non-volatile Storage\n", 26) == 0) { - type = RANGE_ACPI_NVS; - } -+ else if (memcmp(str, "Crash kernel\n", 13) == 0) { -+ /* Redefine the memory region boundaries if kernel -+ * exports the limits and if it is panic kernel. -+ * Override user values only if kernel exported -+ * values are subset of user defined values. -+ */ -+ if (kexec_flags & KEXEC_ON_CRASH) { -+ if (start > mem_min) -+ mem_min = start; -+ if (end < mem_max) -+ mem_max = end; -+ } -+ continue; -+ } - else { - continue; - } -@@ -124,18 +139,20 @@ void arch_usage(void) - ); - } - --static struct { -+struct { - uint8_t reset_vga; - uint16_t serial_base; - uint32_t serial_baud; - uint8_t console_vga; - uint8_t console_serial; -+ int core_header_type; - } arch_options = { - .reset_vga = 0, - .serial_base = 0x3f8, - .serial_baud = 0, - .console_vga = 0, - .console_serial = 0, -+ .core_header_type = CORE_TYPE_ELF64, - }; - - int arch_process_options(int argc, char **argv) -@@ -207,7 +224,7 @@ int arch_process_options(int argc, char - return 0; - } - --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+int arch_compat_trampoline(struct kexec_info *info) - { - int result; - struct utsname utsname; -@@ -222,7 +239,7 @@ int arch_compat_trampoline(struct kexec_ - /* For compatibility with older patches - * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_X86_64 here. - */ -- *flags |= KEXEC_ARCH_DEFAULT; -+ info->kexec_flags |= KEXEC_ARCH_DEFAULT; - } - else { - fprintf(stderr, "Unsupported machine type: %s\n", -@@ -234,6 +251,8 @@ int arch_compat_trampoline(struct kexec_ - - void arch_update_purgatory(struct kexec_info *info) - { -+ uint8_t panic_kernel = 0; -+ - elf_rel_set_symbol(&info->rhdr, "reset_vga", - &arch_options.reset_vga, sizeof(arch_options.reset_vga)); - elf_rel_set_symbol(&info->rhdr, "serial_base", -@@ -244,4 +263,12 @@ void arch_update_purgatory(struct kexec_ - &arch_options.console_vga, sizeof(arch_options.console_vga)); - elf_rel_set_symbol(&info->rhdr, "console_serial", - &arch_options.console_serial, sizeof(arch_options.console_serial)); -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ panic_kernel = 1; -+ elf_rel_set_symbol(&info->rhdr, "backup_start", -+ &info->backup_start, sizeof(info->backup_start)); -+ } -+ elf_rel_set_symbol(&info->rhdr, "panic_kernel", -+ &panic_kernel, sizeof(panic_kernel)); - } -diff -urNp -X dontdiff kexec-tools-1.101/kexec/arch/x86_64/Makefile kexec-tools-1.101-kdump/kexec/arch/x86_64/Makefile ---- kexec-tools-1.101/kexec/arch/x86_64/Makefile 2005-02-06 04:55:19.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/arch/x86_64/Makefile 2006-01-19 11:41:40.000000000 +0530 -@@ -7,6 +7,7 @@ KEXEC_C_SRCS+= kexec/arch/i386/kexec-mul - KEXEC_C_SRCS+= kexec/arch/i386/kexec-beoboot-x86.c - KEXEC_C_SRCS+= kexec/arch/i386/kexec-nbi.c - KEXEC_C_SRCS+= kexec/arch/i386/x86-linux-setup.c -+KEXEC_C_SRCS+= kexec/arch/x86_64/crashdump-x86_64.c - KEXEC_C_SRCS+= kexec/arch/x86_64/kexec-x86_64.c - KEXEC_C_SRCS+= kexec/arch/x86_64/kexec-elf-x86_64.c - KEXEC_C_SRCS+= kexec/arch/x86_64/kexec-elf-rel-x86_64.c -diff -urNp -X dontdiff kexec-tools-1.101/kexec/crashdump.c kexec-tools-1.101-kdump/kexec/crashdump.c ---- kexec-tools-1.101/kexec/crashdump.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/crashdump.c 2006-01-19 18:19:07.000000000 +0530 -@@ -0,0 +1,65 @@ -+/* -+ * crashdump.c: Architecture independent code for crashdump support. -+ * -+ * Created by: Vivek Goyal (vgoyal@in.ibm.com) -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "kexec.h" -+#include "crashdump.h" -+ -+/* Returns the physical address of start of crash notes buffer for a cpu. */ -+int get_crash_notes_per_cpu(int cpu, uint64_t *addr) -+{ -+ char crash_notes[PATH_MAX]; -+ char line[MAX_LINE]; -+ FILE *fp; -+ struct stat cpu_stat; -+ int count; -+ unsigned long long temp; -+ -+ sprintf(crash_notes, "/sys/devices/system/cpu/cpu%d/crash_notes", cpu); -+ fp = fopen(crash_notes, "r"); -+ if (!fp) { -+ /* Either sysfs is not mounted or CPU is not present*/ -+ if (stat("/sys/devices", &cpu_stat)) -+ die("Sysfs is not mounted. Try mounting sysfs\n"); -+ -+ /* CPU is not physically present.*/ -+ *addr = 0; -+ return errno; -+ } -+ if (fgets(line, sizeof(line), fp) != 0) { -+ count = sscanf(line, "%Lx", &temp); -+ if (count != 1) -+ die("Cannot parse %s: %s\n", crash_notes, -+ strerror(errno)); -+ *addr = (uint64_t) temp; -+ } -+#if 0 -+ printf("crash_notes addr = %Lx\n", *addr); -+#endif -+ return 0; -+} -diff -urNp -X dontdiff kexec-tools-1.101/kexec/crashdump.h kexec-tools-1.101-kdump/kexec/crashdump.h ---- kexec-tools-1.101/kexec/crashdump.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/crashdump.h 2006-01-19 18:19:07.000000000 +0530 -@@ -0,0 +1,9 @@ -+#ifndef CRASHDUMP_H -+#define CRASHDUMP_H -+ -+extern int get_crash_notes_per_cpu(int cpu, uint64_t *addr); -+ -+/* Need to find a better way to determine per cpu notes section size. */ -+#define MAX_NOTE_BYTES 1024 -+ -+#endif /* CRASHDUMP_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/kexec.c kexec-tools-1.101-kdump/kexec/kexec.c ---- kexec-tools-1.101/kexec/kexec.c 2005-01-13 18:54:29.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/kexec.c 2006-02-01 14:41:52.000000000 +0530 -@@ -38,8 +38,8 @@ - #include "kexec-elf.h" - #include "kexec-sha256.h" - --static unsigned long long mem_min = 0; --static unsigned long long mem_max = ULONG_MAX; -+unsigned long long mem_min = 0; -+unsigned long long mem_max = ULONG_MAX; - - void die(char *fmt, ...) - { -@@ -187,7 +187,7 @@ unsigned long locate_hole(struct kexec_i - } - - /* Compute the free memory ranges */ -- max_mem_ranges = memory_ranges + (info->nr_segments -1); -+ max_mem_ranges = memory_ranges + info->nr_segments; - mem_range = malloc(max_mem_ranges *sizeof(struct memory_range)); - mem_ranges = 0; - -@@ -323,12 +323,17 @@ unsigned long add_buffer(struct kexec_in - { - unsigned long base; - int result; -+ int pagesize; - - result = sort_segments(info); - if (result < 0) { - die("sort_segments failed\n"); - } - -+ /* Round memsz up to a multiple of pagesize */ -+ pagesize = getpagesize(); -+ memsz = (memsz + (pagesize - 1)) & ~(pagesize - 1); -+ - base = locate_hole(info, memsz, buf_align, buf_min, buf_max, buf_end); - if (base == ULONG_MAX) { - die("locate_hole failed\n"); -@@ -507,6 +512,8 @@ static int my_load(const char *type, int - info.segment = NULL; - info.nr_segments = 0; - info.entry = NULL; -+ info.backup_start = 0; -+ info.kexec_flags = kexec_flags; - - result = 0; - if (argc - fileind <= 0) { -@@ -522,7 +529,8 @@ static int my_load(const char *type, int - kernel_buf, kernel_size); - #endif - -- if (get_memory_ranges(&memory_range, &memory_ranges) < 0) { -+ if (get_memory_ranges(&memory_range, &memory_ranges, -+ info.kexec_flags) < 0) { - fprintf(stderr, "Could not get memory layout\n"); - return -1; - } -@@ -564,7 +572,7 @@ static int my_load(const char *type, int - return -1; - } - /* If we are not in native mode setup an appropriate trampoline */ -- if (arch_compat_trampoline(&info, &kexec_flags) < 0) { -+ if (arch_compat_trampoline(&info) < 0) { - return -1; - } - /* Verify all of the segments load to a valid location in memory */ -@@ -585,17 +593,17 @@ static int my_load(const char *type, int - update_purgatory(&info); - #if 0 - fprintf(stderr, "kexec_load: entry = %p flags = %lx\n", -- info.entry, kexec_flags); -+ info.entry, info.kexec_flags); - print_segments(stderr, &info); - #endif - result = kexec_load( -- info.entry, info.nr_segments, info.segment, kexec_flags); -+ info.entry, info.nr_segments, info.segment, info.kexec_flags); - if (result != 0) { - /* The load failed, print some debugging information */ - fprintf(stderr, "kexec_load failed: %s\n", - strerror(errno)); - fprintf(stderr, "entry = %p flags = %lx\n", -- info.entry, kexec_flags); -+ info.entry, info.kexec_flags); - print_segments(stderr, &info); - } - return result; -diff -urNp -X dontdiff kexec-tools-1.101/kexec/kexec-elf.c kexec-tools-1.101-kdump/kexec/kexec-elf.c ---- kexec-tools-1.101/kexec/kexec-elf.c 2004-12-20 14:58:30.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/kexec-elf.c 2006-02-22 11:30:11.084107504 +0530 -@@ -113,21 +113,21 @@ static int build_mem_elf32_ehdr(const ch - } - return -1; - } -- if (elf32_to_cpu(ehdr, lehdr.e_entry) > ULONG_MAX) { -+ if (elf32_to_cpu(ehdr, lehdr.e_entry) > UINT32_MAX) { - /* entry is to large */ - if (probe_debug) { - fprintf(stderr, "ELF e_entry to large\n"); - } - return -1; - } -- if (elf32_to_cpu(ehdr, lehdr.e_phoff) > ULONG_MAX) { -+ if (elf32_to_cpu(ehdr, lehdr.e_phoff) > UINT32_MAX) { - /* phoff is to large */ - if (probe_debug) { - fprintf(stderr, "ELF e_phoff to large\n"); - } - return -1; - } -- if (elf32_to_cpu(ehdr, lehdr.e_shoff) > ULONG_MAX) { -+ if (elf32_to_cpu(ehdr, lehdr.e_shoff) > UINT32_MAX) { - /* shoff is to large */ - if (probe_debug) { - fprintf(stderr, "ELF e_shoff to large\n"); -@@ -146,7 +146,7 @@ static int build_mem_elf32_ehdr(const ch - ehdr->e_shstrndx = elf16_to_cpu(ehdr, lehdr.e_shstrndx); - - if ((ehdr->e_phnum > 0) && -- (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf32_Phdr))) -+ (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf32_Phdr))) - { - /* Invalid program header size */ - if (probe_debug) { -@@ -185,21 +185,21 @@ static int build_mem_elf64_ehdr(const ch - } - return -1; - } -- if (elf32_to_cpu(ehdr, lehdr.e_entry) > ULONG_MAX) { -+ if (elf32_to_cpu(ehdr, lehdr.e_entry) > UINT32_MAX) { - /* entry is to large */ - if (probe_debug) { - fprintf(stderr, "ELF e_entry to large\n"); - } - return -1; - } -- if (elf32_to_cpu(ehdr, lehdr.e_phoff) > ULONG_MAX) { -+ if (elf32_to_cpu(ehdr, lehdr.e_phoff) > UINT32_MAX) { - /* phoff is to large */ - if (probe_debug) { - fprintf(stderr, "ELF e_phoff to large\n"); - } - return -1; - } -- if (elf32_to_cpu(ehdr, lehdr.e_shoff) > ULONG_MAX) { -+ if (elf32_to_cpu(ehdr, lehdr.e_shoff) > UINT32_MAX) { - /* shoff is to large */ - if (probe_debug) { - fprintf(stderr, "ELF e_shoff to large\n"); -@@ -218,7 +218,7 @@ static int build_mem_elf64_ehdr(const ch - ehdr->e_shstrndx = elf16_to_cpu(ehdr, lehdr.e_shstrndx); - - if ((ehdr->e_phnum > 0) && -- (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf64_Phdr))) -+ (elf16_to_cpu(ehdr, lehdr.e_phentsize) != sizeof(Elf64_Phdr))) - { - /* Invalid program header size */ - if (probe_debug) { -@@ -302,7 +302,7 @@ static int build_mem_ehdr(const char *bu - return 0; - } - --static int build_mem_elf32_phdr(const char *buf, off_t len, -+static int build_mem_elf32_phdr(const char *buf, off_t len, - struct mem_ehdr *ehdr, int idx) - { - struct mem_phdr *phdr; -@@ -312,12 +312,12 @@ static int build_mem_elf32_phdr(const ch - phdr = &ehdr->e_phdr[idx]; - memcpy(&lphdr, pbuf, sizeof(lphdr)); - -- if ( (elf32_to_cpu(ehdr, lphdr.p_filesz) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lphdr.p_memsz) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lphdr.p_offset) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lphdr.p_paddr) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lphdr.p_vaddr) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lphdr.p_align) > ULONG_MAX)) -+ if ( (elf32_to_cpu(ehdr, lphdr.p_filesz) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lphdr.p_memsz) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lphdr.p_offset) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lphdr.p_paddr) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lphdr.p_vaddr) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lphdr.p_align) > UINT32_MAX)) - { - fprintf(stderr, "Program segment size out of range\n"); - return -1; -@@ -345,12 +345,12 @@ static int build_mem_elf64_phdr(const ch - phdr = &ehdr->e_phdr[idx]; - memcpy(&lphdr, pbuf, sizeof(lphdr)); - -- if ( (elf64_to_cpu(ehdr, lphdr.p_filesz) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lphdr.p_memsz) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lphdr.p_offset) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lphdr.p_paddr) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lphdr.p_vaddr) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lphdr.p_align) > ULONG_MAX)) -+ if ( (elf64_to_cpu(ehdr, lphdr.p_filesz) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lphdr.p_memsz) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lphdr.p_offset) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lphdr.p_paddr) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lphdr.p_vaddr) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lphdr.p_align) > UINT64_MAX)) - { - fprintf(stderr, "Program segment size out of range\n"); - return -1; -@@ -388,7 +388,7 @@ static int build_mem_phdrs(const char *b - fprintf(stderr, "Invalid ei_class?\n"); - return -1; - } -- phdr_size *= ehdr->e_phnum; -+ phdr_size *= ehdr->e_phnum; - if (ehdr->e_phoff + phdr_size > len) { - /* The program header did not fit in the file buffer */ - if (probe_debug) { -@@ -396,7 +396,7 @@ static int build_mem_phdrs(const char *b - } - return -1; - } -- -+ - /* Allocate the e_phdr array */ - mem_phdr_size = sizeof(ehdr->e_phdr[0]) * ehdr->e_phnum; - ehdr->e_phdr = xmalloc(mem_phdr_size); -@@ -440,7 +440,7 @@ static int build_mem_phdrs(const char *b - return 0; - } - --static int build_mem_elf32_shdr(const char *buf, off_t len, -+static int build_mem_elf32_shdr(const char *buf, off_t len, - struct mem_ehdr *ehdr, int idx) - { - struct mem_shdr *shdr; -@@ -451,12 +451,12 @@ static int build_mem_elf32_shdr(const ch - shdr = &ehdr->e_shdr[idx]; - memcpy(&lshdr, sbuf, sizeof(lshdr)); - -- if ( (elf32_to_cpu(ehdr, lshdr.sh_flags) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lshdr.sh_addr) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lshdr.sh_offset) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lshdr.sh_size) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lshdr.sh_addralign) > ULONG_MAX) || -- (elf32_to_cpu(ehdr, lshdr.sh_entsize) > ULONG_MAX)) -+ if ( (elf32_to_cpu(ehdr, lshdr.sh_flags) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lshdr.sh_addr) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lshdr.sh_offset) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lshdr.sh_size) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lshdr.sh_addralign) > UINT32_MAX) || -+ (elf32_to_cpu(ehdr, lshdr.sh_entsize) > UINT32_MAX)) - { - fprintf(stderr, "Program section size out of range\n"); - return -1; -@@ -510,7 +510,7 @@ static int build_mem_elf32_shdr(const ch - return 0; - } - --static int build_mem_elf64_shdr(const char *buf, off_t len, -+static int build_mem_elf64_shdr(const char *buf, off_t len, - struct mem_ehdr *ehdr, int idx) - { - struct mem_shdr *shdr; -@@ -521,12 +521,12 @@ static int build_mem_elf64_shdr(const ch - shdr = &ehdr->e_shdr[idx]; - memcpy(&lshdr, sbuf, sizeof(lshdr)); - -- if ( (elf64_to_cpu(ehdr, lshdr.sh_flags) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lshdr.sh_addr) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lshdr.sh_offset) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lshdr.sh_size) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lshdr.sh_addralign) > ULONG_MAX) || -- (elf64_to_cpu(ehdr, lshdr.sh_entsize) > ULONG_MAX)) -+ if ( (elf64_to_cpu(ehdr, lshdr.sh_flags) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lshdr.sh_addr) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lshdr.sh_offset) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lshdr.sh_size) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lshdr.sh_addralign) > UINT64_MAX) || -+ (elf64_to_cpu(ehdr, lshdr.sh_entsize) > UINT64_MAX)) - { - fprintf(stderr, "Program section size out of range\n"); - return -1; -@@ -608,7 +608,7 @@ static int build_mem_shdrs(const char *b - } - return -1; - } -- -+ - /* Allocate the e_shdr array */ - mem_shdr_size = sizeof(ehdr->e_shdr[0]) * ehdr->e_shnum; - ehdr->e_shdr = xmalloc(mem_shdr_size); -@@ -635,7 +635,7 @@ static int build_mem_shdrs(const char *b - { - /* The section does not fit in the buffer */ - if (probe_debug) { -- fprintf(stderr, "ELF section %d not in file\n", -+ fprintf(stderr, "ELF section %d not in file\n", - i); - } - return -1; -@@ -648,19 +648,19 @@ static int build_mem_shdrs(const char *b - return -1; - } - /* Remember where the section lives in the buffer */ -- shdr->sh_data = buf + shdr->sh_offset; -+ shdr->sh_data = (unsigned char *)(buf + shdr->sh_offset); - } - return 0; - } - --static void read_nhdr(const struct mem_ehdr *ehdr, -+static void read_nhdr(const struct mem_ehdr *ehdr, - ElfNN_Nhdr *hdr, const unsigned char *note) - { - memcpy(hdr, note, sizeof(*hdr)); - hdr->n_namesz = elf32_to_cpu(ehdr, hdr->n_namesz); - hdr->n_descsz = elf32_to_cpu(ehdr, hdr->n_descsz); - hdr->n_type = elf32_to_cpu(ehdr, hdr->n_type); -- -+ - } - static int build_mem_notes(const char *buf, off_t len, struct mem_ehdr *ehdr) - { -@@ -672,7 +672,7 @@ static int build_mem_notes(const char *b - for(i = 0; !note_start && (i < ehdr->e_phnum); i++) { - struct mem_phdr *phdr = &ehdr->e_phdr[i]; - if (phdr->p_type == PT_NOTE) { -- note_start = phdr->p_data; -+ note_start = (unsigned char *)phdr->p_data; - note_end = note_start + phdr->p_filesz; - } - } -@@ -686,7 +686,7 @@ static int build_mem_notes(const char *b - if (!note_start) { - return 0; - } -- -+ - /* Walk through and count the notes */ - ehdr->e_notenum = 0; - for(note = note_start; note < note_end; note+= note_size) { -@@ -708,15 +708,15 @@ static int build_mem_notes(const char *b - note_size += (hdr.n_namesz + 3) & ~3; - desc = note + note_size; - note_size += (hdr.n_descsz + 3) & ~3; -- -+ - if ((hdr.n_namesz != 0) && (name[hdr.n_namesz -1] != '\0')) { - die("Note name is not null termiated"); - } - ehdr->e_note[i].n_type = hdr.n_type; -- ehdr->e_note[i].n_name = name; -+ ehdr->e_note[i].n_name = (char *)name; - ehdr->e_note[i].n_desc = desc; - ehdr->e_note[i].n_descsz = hdr.n_descsz; -- -+ - } - return 0; - } -diff -urNp -X dontdiff kexec-tools-1.101/kexec/kexec-elf-rel.c kexec-tools-1.101-kdump/kexec/kexec-elf-rel.c ---- kexec-tools-1.101/kexec/kexec-elf-rel.c 2005-01-13 18:34:21.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/kexec-elf-rel.c 2006-02-22 11:30:11.085107352 +0530 -@@ -155,7 +155,7 @@ int build_elf_rel_info(const char *buf, - if (probe_debug) { - fprintf(stderr, "No ELF section headers\n"); - } -- return -1; -+ return -1; - } - if (!machine_verify_elf_rel(ehdr)) { - /* It does not meant the native architecture constraints */ -@@ -251,7 +251,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, - - /* Allocate where we will put the relocated object */ - buf = xmalloc(bufsz); -- buf_addr = add_buffer(info, buf, bufsz, bufsz + bss_pad + bsssz, -+ buf_addr = add_buffer(info, buf, bufsz, bufsz + bss_pad + bsssz, - buf_align, min, max, end); - ehdr->rel_addr = buf_addr; - ehdr->rel_size = bufsz + bss_pad + bsssz; -@@ -269,7 +269,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, - unsigned long off; - /* Adjust the address */ - data_addr = (data_addr + (align - 1)) & ~(align -1); -- -+ - /* Update the section */ - off = data_addr - buf_addr; - memcpy(buf + off, shdr->sh_data, shdr->sh_size); -@@ -306,7 +306,7 @@ int elf_rel_load(struct mem_ehdr *ehdr, - continue; - } - if ((shdr->sh_info > ehdr->e_shnum) || -- (shdr->sh_link > ehdr->e_shnum)) -+ (shdr->sh_link > ehdr->e_shnum)) - { - die("Invalid section number\n"); - } -@@ -350,12 +350,12 @@ int elf_rel_load(struct mem_ehdr *ehdr, - - /* The final address of that location */ - address = section->sh_addr + rel.r_offset; -- -+ - /* The relevant symbol */ - sym = elf_sym(ehdr, symtab->sh_data + (rel.r_sym * elf_sym_size(ehdr))); --#if 0 -+#ifdef DEBUG - fprintf(stderr, "sym: %10s info: %02x other: %02x shndx: %lx value: %lx size: %lx\n", -- strtab + sym.st_name, -+ strtab + sym.st_name, - sym.st_info, - sym.st_other, - sym.st_shndx, -@@ -364,8 +364,19 @@ int elf_rel_load(struct mem_ehdr *ehdr, - - #endif - if (sym.st_shndx == STN_UNDEF) { -- die("Undefined symbol: %s\n", -+ /* -+ * NOTE: ppc64 elf .ro shows up a UNDEF section. -+ * From Elf 1.2 Spec: -+ * Relocation Entries: If the index is STN_UNDEF, -+ * the undefined symbol index, the relocation uses 0 -+ * as the "symbol value". -+ * So, is this really an error condition to flag die? -+ */ -+ /* -+ die("Undefined symbol: %s\n", - strtab + sym.st_name); -+ */ -+ continue; - } - sec_base = 0; - if (sym.st_shndx == SHN_COMMON) { -@@ -383,14 +394,14 @@ int elf_rel_load(struct mem_ehdr *ehdr, - else { - sec_base = ehdr->e_shdr[sym.st_shndx].sh_addr; - } --#if 0 -+#ifdef DEBUG - fprintf(stderr, "sym: %s value: %lx addr: %lx\n", - strtab + sym.st_name, value, address); - #endif - value = sym.st_value; - value += sec_base; - value += rel.r_addend; -- machine_apply_elf_rel(ehdr, rel.r_type, -+ machine_apply_elf_rel(ehdr, rel.r_type, - (void *)location, address, value); - } - } -@@ -399,14 +410,14 @@ int elf_rel_load(struct mem_ehdr *ehdr, - return result; - } - --void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, -+void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, - const char *buf, off_t len, unsigned long min, unsigned long max, - int end) - { - int result; - - /* Parse the Elf file */ -- result = build_elf_rel_info(purgatory, purgatory_size, ehdr); -+ result = build_elf_rel_info((char *)purgatory, purgatory_size, ehdr); - if (result < 0) { - die("ELF rel parse failed\n"); - } -@@ -439,7 +450,7 @@ int elf_rel_find_symbol(struct mem_ehdr - /* Invalid strtab section number? */ - continue; - } -- strtab = ehdr->e_shdr[shdr->sh_link].sh_data; -+ strtab = (char *)ehdr->e_shdr[shdr->sh_link].sh_data; - /* Walk through the symbol table and find the symbol */ - sym_size = elf_sym_size(ehdr); - sym_end = shdr->sh_data + shdr->sh_size; -@@ -452,8 +463,8 @@ int elf_rel_find_symbol(struct mem_ehdr - if (strcmp(strtab + sym.st_name, name) != 0) { - continue; - } -- if ((sym.st_shndx == STN_UNDEF) || -- (sym.st_shndx > ehdr->e_shnum)) -+ if ((sym.st_shndx == STN_UNDEF) || -+ (sym.st_shndx > ehdr->e_shnum)) - { - die("Symbol: %s has Bad section index %d\n", - name, sym.st_shndx); -@@ -491,7 +502,7 @@ void elf_rel_set_symbol(struct mem_ehdr - - result = elf_rel_find_symbol(ehdr, name, &sym); - if (result < 0) { -- die("Symbol: %s not found cannot set\n", -+ die("Symbol: %s not found cannot set\n", - name); - } - if (sym.st_size != size) { -diff -urNp -X dontdiff kexec-tools-1.101/kexec/kexec.h kexec-tools-1.101-kdump/kexec/kexec.h ---- kexec-tools-1.101/kexec/kexec.h 2005-01-13 18:33:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/kexec.h 2006-01-19 18:19:07.000000000 +0530 -@@ -91,6 +91,8 @@ do { \ - } while(0) - #endif - -+extern unsigned long long mem_min, mem_max; -+ - struct kexec_segment { - const void *buf; - size_t bufsz; -@@ -112,10 +114,13 @@ struct kexec_info { - int nr_segments; - void *entry; - struct mem_ehdr rhdr; -+ unsigned long backup_start; -+ unsigned long kexec_flags; - }; - - void usage(void); --int get_memory_ranges(struct memory_range **range, int *ranges); -+int get_memory_ranges(struct memory_range **range, int *ranges, -+ unsigned long kexec_flags); - int valid_memory_range(unsigned long sstart, unsigned long send); - int valid_memory_segment(struct kexec_segment *segment); - void print_segments(FILE *file, struct kexec_info *info); -@@ -188,7 +193,8 @@ extern size_t purgatory_size; - - void arch_usage(void); - int arch_process_options(int argc, char **argv); --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags); -+int arch_compat_trampoline(struct kexec_info *info); - void arch_update_purgatory(struct kexec_info *info); - -+#define MAX_LINE 160 - #endif /* KEXEC_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/kexec-syscall.h kexec-tools-1.101-kdump/kexec/kexec-syscall.h ---- kexec-tools-1.101/kexec/kexec-syscall.h 2005-01-06 12:29:50.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/kexec-syscall.h 2006-01-19 11:41:43.000000000 +0530 -@@ -37,6 +37,12 @@ - #ifdef __x86_64__ - #define __NR_kexec_load 246 - #endif -+#ifdef __s390x__ -+#define __NR_kexec_load 277 -+#endif -+#ifdef __s390__ -+#define __NR_kexec_load 277 -+#endif - #ifndef __NR_kexec_load - #error Unknown processor architecture. Needs a kexec_load syscall number. - #endif -@@ -67,7 +73,8 @@ static inline long kexec_reboot(void) - #define KEXEC_ARCH_PPC (20 << 16) - #define KEXEC_ARCH_PPC64 (21 << 16) - #define KEXEC_ARCH_IA_64 (50 << 16) -+#define KEXEC_ARCH_S390 (22 << 16) - --#define KEXEC_MAX_SEGMENTS 8 -+#define KEXEC_MAX_SEGMENTS 16 - - #endif /* KEXEC_SYSCALL_H */ -diff -urNp -X dontdiff kexec-tools-1.101/kexec/Makefile kexec-tools-1.101-kdump/kexec/Makefile ---- kexec-tools-1.101/kexec/Makefile 2004-12-22 01:06:39.000000000 +0530 -+++ kexec-tools-1.101-kdump/kexec/Makefile 2006-01-19 18:19:07.000000000 +0530 -@@ -15,6 +15,7 @@ KEXEC_C_SRCS+= kexec/kexec-elf.c - KEXEC_C_SRCS+= kexec/kexec-elf-exec.c - KEXEC_C_SRCS+= kexec/kexec-elf-rel.c - KEXEC_C_SRCS+= kexec/kexec-elf-boot.c -+KEXEC_C_SRCS+= kexec/crashdump.c - KEXEC_C_SRCS+= $(PURGATORY_HEX_C) - KEXEC_S_SRCS:= - include kexec/arch/$(ARCH)/Makefile -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/i386/crashdump_backup.c kexec-tools-1.101-kdump/purgatory/arch/i386/crashdump_backup.c ---- kexec-tools-1.101/purgatory/arch/i386/crashdump_backup.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/i386/crashdump_backup.c 2006-01-19 11:41:41.000000000 +0530 -@@ -0,0 +1,46 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: Vivek goyal (vgoyal@in.ibm.com) -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+ -+#define BACKUP_REGION_SOURCE 0x00000000 -+#define BACKUP_REGION_SIZE 0xa0000 -+ -+/* Backup region start gets set after /proc/iomem has been parsed. */ -+/* We reuse the same code for x86_64 also so changing backup_start to -+ unsigned long */ -+unsigned long backup_start = 0; -+ -+/* Backup first 640K of memory to backup region as reserved by kexec. -+ * Assuming first 640K has to be present on i386 machines and no address -+ * validity checks have to be performed. */ -+ -+void crashdump_backup_memory(void) -+{ -+ void *dest, *src; -+ -+ src = (void *) BACKUP_REGION_SOURCE; -+ -+ if (backup_start) { -+ dest = (void *)(backup_start); -+ memcpy(dest, src, BACKUP_REGION_SIZE); -+ } -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/i386/Makefile kexec-tools-1.101-kdump/purgatory/arch/i386/Makefile ---- kexec-tools-1.101/purgatory/arch/i386/Makefile 2005-01-11 06:37:58.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/i386/Makefile 2006-01-19 11:41:27.000000000 +0530 -@@ -12,3 +12,4 @@ PURGATORY_C_SRCS+= purgatory/arch/i386/p - PURGATORY_C_SRCS+= purgatory/arch/i386/console-x86.c - PURGATORY_C_SRCS+= purgatory/arch/i386/vga.c - PURGATORY_C_SRCS+= purgatory/arch/i386/pic.c -+PURGATORY_C_SRCS+= purgatory/arch/i386/crashdump_backup.c -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/i386/purgatory-x86.c kexec-tools-1.101-kdump/purgatory/arch/i386/purgatory-x86.c ---- kexec-tools-1.101/purgatory/arch/i386/purgatory-x86.c 2004-12-21 21:59:48.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/i386/purgatory-x86.c 2006-01-19 11:41:27.000000000 +0530 -@@ -30,6 +30,7 @@ void x86_setup_cpu(void) - uint8_t reset_vga = 0; - uint8_t legacy_timer = 0; - uint8_t legacy_pic = 0; -+uint8_t panic_kernel = 0; - - void setup_arch(void) - { -@@ -38,3 +39,9 @@ void setup_arch(void) - if (legacy_pic) x86_setup_legacy_pic(); - /* if (legacy_timer) x86_setup_legacy_timer(); */ - } -+ -+/* This function can be used to execute after the SHA256 verification. */ -+void post_verification_setup_arch(void) -+{ -+ if (panic_kernel) crashdump_backup_memory(); -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/i386/purgatory-x86.h kexec-tools-1.101-kdump/purgatory/arch/i386/purgatory-x86.h ---- kexec-tools-1.101/purgatory/arch/i386/purgatory-x86.h 2004-12-20 17:52:26.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/i386/purgatory-x86.h 2006-01-19 11:41:27.000000000 +0530 -@@ -4,5 +4,6 @@ - void x86_reset_vga(void); - void x86_setup_legacy_pic(void); - void x86_setup_legacy_timer(void); -+void crashdump_backup_memory(void); - - #endif /* PURGATORY_X86_H */ -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c kexec-tools-1.101-kdump/purgatory/arch/ia64/purgatory-ia64.c ---- kexec-tools-1.101/purgatory/arch/ia64/purgatory-ia64.c 2004-12-21 04:15:21.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ia64/purgatory-ia64.c 2006-01-19 11:41:27.000000000 +0530 -@@ -5,3 +5,9 @@ void setup_arch(void) - { - /* Nothing for now */ - } -+ -+/* This function can be used to execute after the SHA256 verification. */ -+void post_verification_setup_arch(void) -+{ -+ /* Nothing for now */ -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc/purgatory-ppc.c kexec-tools-1.101-kdump/purgatory/arch/ppc/purgatory-ppc.c ---- kexec-tools-1.101/purgatory/arch/ppc/purgatory-ppc.c 2004-12-21 04:17:43.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc/purgatory-ppc.c 2006-01-19 11:41:27.000000000 +0530 -@@ -5,3 +5,9 @@ void setup_arch(void) - { - /* Nothing for now */ - } -+ -+/* This function can be used to execute after the SHA256 verification. */ -+void post_verification_setup_arch(void) -+{ -+ /* Nothing for now */ -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc64/console-ppc64.c kexec-tools-1.101-kdump/purgatory/arch/ppc64/console-ppc64.c ---- kexec-tools-1.101/purgatory/arch/ppc64/console-ppc64.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc64/console-ppc64.c 2006-01-19 18:20:08.000000000 +0530 -@@ -0,0 +1,27 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: Mohan Kumar M (mohan@in.ibm.com) -+ * -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+ -+void putchar(int c) -+{ -+ return; -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc64/crashdump_backup.c kexec-tools-1.101-kdump/purgatory/arch/ppc64/crashdump_backup.c ---- kexec-tools-1.101/purgatory/arch/ppc64/crashdump_backup.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc64/crashdump_backup.c 2006-01-19 18:20:08.000000000 +0530 -@@ -0,0 +1,41 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: Mohan Kumar M (mohan@in.ibm.com) -+ * -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include -+ -+#define BACKUP_REGION_SOURCE 0x0 -+#define BACKUP_REGION_SIZE 32*1024 -+ -+extern unsigned long backup_start; -+ -+/* Backup first 32KB of memory to backup region reserved by kexec */ -+void crashdump_backup_memory(void) -+{ -+ void *dest, *src; -+ -+ src = (void *)BACKUP_REGION_SOURCE; -+ -+ if (backup_start) { -+ dest = (void *)(backup_start); -+ memcpy(dest, src, BACKUP_REGION_SIZE); -+ } -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc64/Makefile kexec-tools-1.101-kdump/purgatory/arch/ppc64/Makefile ---- kexec-tools-1.101/purgatory/arch/ppc64/Makefile 2004-12-17 11:00:20.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc64/Makefile 2006-01-19 18:20:08.000000000 +0530 -@@ -2,6 +2,7 @@ - # Purgatory ppc - # - --PURGATORY_C_SRCS+= --PURGATORY_S_SRCS+= -- -+PURGATORY_S_SRCS+= purgatory/arch/ppc64/v2wrap.S -+PURGATORY_C_SRCS += purgatory/arch/ppc64/purgatory-ppc64.c -+PURGATORY_C_SRCS += purgatory/arch/ppc64/console-ppc64.c -+PURGATORY_C_SRCS += purgatory/arch/ppc64/crashdump_backup.c -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc64/purgatory-ppc64.c kexec-tools-1.101-kdump/purgatory/arch/ppc64/purgatory-ppc64.c ---- kexec-tools-1.101/purgatory/arch/ppc64/purgatory-ppc64.c 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc64/purgatory-ppc64.c 2006-01-19 18:20:08.000000000 +0530 -@@ -0,0 +1,41 @@ -+/* -+ * kexec: Linux boots Linux -+ * -+ * Created by: Mohan Kumar M (mohan@in.ibm.com) -+ * -+ * Copyright (C) IBM Corporation, 2005. All rights reserved -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation (version 2 of the License). -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include -+#include "purgatory-ppc64.h" -+ -+unsigned int panic_kernel = 0; -+unsigned long backup_start = 0; -+unsigned long stack = 0; -+unsigned long dt_offset = 0; -+unsigned long my_toc = 0; -+unsigned long kernel = 0; -+ -+void setup_arch(void) -+{ -+ return; -+} -+ -+void post_verification_setup_arch(void) -+{ -+ if (panic_kernel) -+ crashdump_backup_memory(); -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc64/purgatory-ppc64.h kexec-tools-1.101-kdump/purgatory/arch/ppc64/purgatory-ppc64.h ---- kexec-tools-1.101/purgatory/arch/ppc64/purgatory-ppc64.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc64/purgatory-ppc64.h 2006-01-19 18:20:08.000000000 +0530 -@@ -0,0 +1,6 @@ -+#ifndef PURGATORY_PPC64_H -+#define PURGATORY_PPC64_H -+ -+void crashdump_backup_memory(void); -+ -+#endif /* PURGATORY_PPC64_H */ -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/ppc64/v2wrap.S kexec-tools-1.101-kdump/purgatory/arch/ppc64/v2wrap.S ---- kexec-tools-1.101/purgatory/arch/ppc64/v2wrap.S 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/ppc64/v2wrap.S 2006-01-19 18:20:08.000000000 +0530 -@@ -0,0 +1,128 @@ -+# -+# kexec: Linux boots Linux -+# -+# Copyright (C) 2004 - 2005, Milton D Miller II, IBM Corporation -+# Copyright (C) 2006, Mohan Kumar M (mohan@in.ibm.com), IBM Corporation -+# -+# This program is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation (version 2 of the License). -+# -+# This program is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this program; if not, write to the Free Software -+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+# -+ -+# v2wrap.S -+# a wrapper to call purgatory code to backup first -+# 32kB of first kernel into the backup region -+# reserved by kexec-tools. -+# Invokes ppc64 kernel with the expected arguments -+# of kernel(device-tree, phys-offset, 0) -+ -+# -+# calling convention: -+# r3 = physical number of this cpu (all cpus) -+# r4 = address of this chunk (master only) -+# master enters at purgatory_start (aka first byte of this chunk) -+# slaves (additional cpus), if any, enter a copy of the -+# first 0x100 bytes of this code relocated to 0x0 -+# -+# in other words, -+# a copy of the first 0x100 bytes of this code is copied to 0 -+# and the slaves are sent to address 0x60 -+# with r3 = their physical cpu number. -+ -+#define LOADADDR(rn,name) \ -+ lis rn,name##@highest; \ -+ ori rn,rn,name##@higher; \ -+ rldicr rn,rn,32,31; \ -+ oris rn,rn,name##@h; \ -+ ori rn,rn,name##@l -+ -+# look a bit like a Linux kernel here ... -+ .machine ppc64 -+ .globl purgatory_start -+purgatory_start: b master -+ tweq 0,0 -+master: -+ or 1,1,1 # low priority to let other thread catchup -+ isync -+ mr 17,3 # save cpu id to r17 -+ mr 15,4 # save physical address in reg15 -+ -+ LOADADDR(6,my_toc) -+ ld 2,0(6) #setup toc -+ -+ LOADADDR(6,stack) -+ ld 1,0(6) #setup stack -+ -+ subi 1,1,112 -+ bl .purgatory -+ nop -+ -+ b 81f -+ .org purgatory_start + 0x60 # ABI: slaves start at 60 with r3=phys -+slave: -+ # load slave spin code address and branch into that -+ LOADADDR(6,slave_spin) -+ ld 4,0(6) -+ mtctr 4 -+ bctr -+ -+spin: .long 1 -+slave_spin_code: -+ lis 5,spin@ha -+ lwz 5,spin@l(5) -+ cmpwi 0,5,0 -+ bne slave_spin_code -+ ba 0x60 -+ -+81: # master continues here -+ or 3,3,3 # ok back to high, lets boot -+ lis 6,0x1 -+ mtctr 6 # delay a bit for slaves to catch up -+83: bdnz 83b # before we overwrite 0-100 again -+ -+ LOADADDR(16, dt_offset) -+ ld 3,0(16) # load device-tree address -+ mr 16,3 # save dt address in reg16 -+ lwz 6,20(3) # fetch version number -+ cmpwi 0,6,2 # v2 ? -+ blt 80f -+ stw 17,28(3) # save my cpu number as boot_cpu_phys -+80: -+ LOADADDR(6,kernel) -+ ld 4,0(6) # load the kernel address -+ -+ addi 5,4,-8 # prepare copy with update form instructions -+ li 6,0x100/8 -+ mtctr 6 -+ li 6,-8 -+85: ldu 7,8(5) -+ stdu 7,8(6) -+ bdnz 85b -+ -+ li 5,0 # r5 will be 0 for kernel -+ dcbst 0,5 # store dcache, flush icache -+ dcbst 0,6 # 0 and 0xf8 covers us with 128 byte lines -+ mtctr 4 # prepare branch too -+ sync -+ icbi 0,5 -+ icbi 0,6 -+ sync -+ isync -+ lis 6,spin@ha -+ li 0,0 -+ stw 0,spin@l(6) -+ mr 3,16 # restore dt address -+ -+ bctr # start kernel -+ -+slave_spin: .llong slave_spin_code -+ -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/s390/include/limits.h kexec-tools-1.101-kdump/purgatory/arch/s390/include/limits.h ---- kexec-tools-1.101/purgatory/arch/s390/include/limits.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/s390/include/limits.h 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,54 @@ -+#ifndef _LIMITS_H_ -+#define _LIMITS_H_ -+ -+/* Number of bits in a `char'. */ -+# define CHAR_BIT 8 -+ -+/* Minimum and maximum values a `signed char' can hold. */ -+# define SCHAR_MIN (-128) -+# define SCHAR_MAX 127 -+ -+/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ -+# define UCHAR_MAX 255 -+ -+# define CHAR_MIN SCHAR_MIN -+# define CHAR_MAX SCHAR_MAX -+ -+/* Minimum and maximum values a `signed short int' can hold. */ -+# define SHRT_MIN (-32768) -+# define SHRT_MAX 32767 -+ -+/* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ -+# define USHRT_MAX 65535 -+ -+/* Minimum and maximum values a `signed int' can hold. */ -+# define INT_MIN (-INT_MAX - 1) -+# define INT_MAX 2147483647 -+ -+/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ -+# define UINT_MAX 4294967295U -+ -+/* Minimum and maximum values a `signed long int' can hold. */ -+#ifdef __s390x__ -+# define LONG_MAX 9223372036854775807L -+#else -+# define LONG_MAX 2147483647L -+#endif -+ -+# define LONG_MIN (-LONG_MAX - 1L) -+ -+/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */ -+#ifdef __s390x__ -+# define ULONG_MAX 18446744073709551615UL -+#else -+# define ULONG_MAX 4294967295UL -+#endif -+ -+/* Minimum and maximum values a `signed long long int' can hold. */ -+# define LLONG_MAX 9223372036854775807LL -+# define LLONG_MIN (-LLONG_MAX - 1LL) -+ -+/* Maximum value an `unsigned long long int' can hold. (Minimum is 0.) */ -+# define ULLONG_MAX 18446744073709551615ULL -+ -+#endif /* !_LIMITS_H_ */ -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/s390/include/stdint.h kexec-tools-1.101-kdump/purgatory/arch/s390/include/stdint.h ---- kexec-tools-1.101/purgatory/arch/s390/include/stdint.h 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/s390/include/stdint.h 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,24 @@ -+#ifndef _STDINT_H -+#define _STDINT_H -+ -+typedef unsigned long size_t; -+ -+typedef unsigned char uint8_t; -+typedef unsigned short uint16_t; -+typedef unsigned int uint32_t; -+#ifdef __s390x__ -+typedef unsigned long uint64_t; -+#else -+typedef unsigned long long uint64_t; -+#endif -+ -+typedef signed char int8_t; -+typedef short int16_t; -+typedef int int32_t; -+#ifdef __s390x__ -+typedef long int64_t; -+#else -+typedef long long int64_t; -+#endif -+ -+#endif -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/s390/Makefile kexec-tools-1.101-kdump/purgatory/arch/s390/Makefile ---- kexec-tools-1.101/purgatory/arch/s390/Makefile 1970-01-01 05:30:00.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/s390/Makefile 2006-01-19 11:41:37.000000000 +0530 -@@ -0,0 +1,7 @@ -+# -+# Purgatory s390 -+# -+ -+PURGATORY_C_SRCS+= -+PURGATORY_S_SRCS+= -+ -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/x86_64/Makefile kexec-tools-1.101-kdump/purgatory/arch/x86_64/Makefile ---- kexec-tools-1.101/purgatory/arch/x86_64/Makefile 2004-12-21 12:43:53.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/x86_64/Makefile 2006-01-19 11:41:41.000000000 +0530 -@@ -9,6 +9,7 @@ PURGATORY_S_SRCS+= purgatory/arch/x86_64 - PURGATORY_S_SRCS+= purgatory/arch/x86_64/setup-x86_64.S - PURGATORY_S_SRCS+= purgatory/arch/x86_64/stack.S - PURGATORY_C_SRCS+= purgatory/arch/x86_64/purgatory-x86_64.c -+PURGATORY_C_SRCS+= purgatory/arch/i386/crashdump_backup.c - PURGATORY_C_SRCS+= purgatory/arch/i386/console-x86.c - PURGATORY_C_SRCS+= purgatory/arch/i386/vga.c - PURGATORY_C_SRCS+= purgatory/arch/i386/pic.c -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/arch/x86_64/purgatory-x86_64.c kexec-tools-1.101-kdump/purgatory/arch/x86_64/purgatory-x86_64.c ---- kexec-tools-1.101/purgatory/arch/x86_64/purgatory-x86_64.c 2004-12-21 22:07:41.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/arch/x86_64/purgatory-x86_64.c 2006-01-19 11:41:41.000000000 +0530 -@@ -4,9 +4,16 @@ - - uint8_t reset_vga = 0; - uint8_t legacy_pic = 0; -+uint8_t panic_kernel = 0; - - void setup_arch(void) - { - if (reset_vga) x86_reset_vga(); - if (legacy_pic) x86_setup_legacy_pic(); - } -+ -+/* This function can be used to execute after the SHA256 verification. */ -+void post_verification_setup_arch(void) -+{ -+ if (panic_kernel) crashdump_backup_memory(); -+} -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/include/purgatory.h kexec-tools-1.101-kdump/purgatory/include/purgatory.h ---- kexec-tools-1.101/purgatory/include/purgatory.h 2004-12-18 18:42:15.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/include/purgatory.h 2006-01-19 11:41:27.000000000 +0530 -@@ -4,5 +4,6 @@ - void putchar(int ch); - void printf(const char *fmt, ...); - void setup_arch(void); -+void post_verification_setup_arch(void); - - #endif /* PURGATORY_H */ -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/Makefile kexec-tools-1.101-kdump/purgatory/Makefile ---- kexec-tools-1.101/purgatory/Makefile 2005-01-09 04:06:32.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/Makefile 2006-01-19 18:20:08.000000000 +0530 -@@ -6,6 +6,11 @@ - # There is probably a cleaner way to do this but for now this - # should keep us from accidentially include unsafe library functions - # or headers. -+ -+ifeq ($(ARCH),ppc64) -+LDFLAGS = -melf64ppc -+endif -+ - PCFLAGS:=-Wall -Os \ - -I$(shell $(CC) -print-file-name=include) \ - -Ipurgatory/include -Ipurgatory/arch/$(ARCH)/include \ -@@ -16,11 +21,11 @@ PCFLAGS += $(call cc-option, -fnobuiltin - PCFLAGS += $(call cc-option, -fnostdinc) - PCFLAGS += $(call cc-option, -fno-zero-initialized-in-bss) - --PURGATORY_C_SRCS:= -+PURGATORY_C_SRCS:= - PURGATORY_C_SRCS += purgatory/purgatory.c - PURGATORY_C_SRCS += purgatory/printf.c - PURGATORY_C_SRCS += purgatory/string.c --PURGATORY_S_OBJS:= -+PURGATORY_S_OBJS:= - - include purgatory/arch/$(ARCH)/Makefile - -diff -urNp -X dontdiff kexec-tools-1.101/purgatory/purgatory.c kexec-tools-1.101-kdump/purgatory/purgatory.c ---- kexec-tools-1.101/purgatory/purgatory.c 2004-12-22 00:21:03.000000000 +0530 -+++ kexec-tools-1.101-kdump/purgatory/purgatory.c 2006-01-19 11:41:27.000000000 +0530 -@@ -44,4 +44,5 @@ void purgatory(void) - printf("I'm in purgatory\n"); - setup_arch(); - verify_sha256_digest(); -+ post_verification_setup_arch(); - } diff --git a/kexec-tools-1.101-makedumpfile-xen-syms.patch b/kexec-tools-1.101-makedumpfile-xen-syms.patch deleted file mode 100644 index 207a43f..0000000 --- a/kexec-tools-1.101-makedumpfile-xen-syms.patch +++ /dev/null @@ -1,81 +0,0 @@ ---- kexec-tools-1.101/makedumpfile/makedumpfile.c.orig 2007-07-27 13:16:28.000000000 -0400 -+++ kexec-tools-1.101/makedumpfile/makedumpfile.c 2007-08-22 13:20:04.000000000 -0400 -@@ -5195,6 +5195,9 @@ - int i; - struct pt_load_segment *pls; - int ret = FALSE; -+ unsigned long long paddr; -+ off_t offset_page; -+ unsigned char *buf = NULL; - - /* - * NOTE: the first half of bitmap is not used for Xen extraction -@@ -5211,6 +5214,11 @@ - strerror(errno)); - goto out; - } -+ if ((buf = malloc(info->page_size)) == NULL) { -+ ERRMSG("Can't allocate memory for the page. %s\n", -+ strerror(errno)); -+ goto out; -+ } - - pfn = 0; - for (i = 0; i < info->num_load_memory; i++) { -@@ -5255,11 +5263,35 @@ - * - xen heap area, or - * - selected domain page - */ -- if (_domain == 0 || -+ if (!(_domain == 0 || - (info->xen_heap_start <= pfn && pfn < info->xen_heap_end) || -- ((count_info & 0xffff) && is_select_domain(info, _domain))) { -- set_bitmap(bm2.buf, pfn%PFN_BUFBITMAP, 1); -+ ((count_info & 0xffff) && is_select_domain(info, _domain)))) { -+ continue; -+ } -+ if (info->dump_level & DL_EXCLUDE_ZERO) { -+ paddr = (unsigned long long)pfn * info->page_size; -+ offset_page = paddr_to_offset(info, paddr); -+ if (!offset_page) { -+ ERRMSG("Can't convert physaddr(%llx) to a offset.\n", -+ paddr); -+ goto out; -+ } -+ if (lseek(info->fd_memory, offset_page, -+ SEEK_SET) == (off_t)-1) { -+ ERRMSG("Can't seek the dump memory(%s). %s\n", -+ info->name_memory, strerror(errno)); -+ goto out; -+ } -+ if (read(info->fd_memory, buf, info->page_size) -+ != info->page_size) { -+ ERRMSG("Can't read the dump memory(%s). %s\n", -+ info->name_memory, strerror(errno)); -+ goto out; -+ } -+ if (is_zero_page(buf, info->page_size)) -+ continue; - } -+ set_bitmap(bm2.buf, pfn%PFN_BUFBITMAP, 1); - } - } - -@@ -5275,6 +5307,8 @@ - out: - if (bm2.buf != NULL) - free(bm2.buf); -+ if (buf != NULL) -+ free(buf); - - return ret; - } -@@ -5546,7 +5580,7 @@ - MSG("-E must be specified with --xen-syms or --xen-vmcoreinfo.\n"); - goto out; - } -- info->dump_level = DL_EXCLUDE_XEN; -+ info->dump_level |= DL_EXCLUDE_XEN; - return handle_xen(info); - - } else if (info->flag_rearrange) { diff --git a/kexec-tools-1.101-page_h.patch b/kexec-tools-1.101-page_h.patch deleted file mode 100644 index a07a579..0000000 --- a/kexec-tools-1.101-page_h.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c.orig 2006-08-28 14:32:50.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c 2006-08-28 14:34:29.000000000 -0400 -@@ -47,7 +47,6 @@ - #include - #include - #include --#include - #include - #include "../../kexec.h" - #include "../../kexec-elf.h" -@@ -342,7 +341,7 @@ - /* Pick the next aligned spot to load it in */ - freespace = add_buffer(info, - buf, mod_size, mod_size, -- PAGE_SIZE, 0, 0xffffffffUL, 1); -+ getpagesize(), 0, 0xffffffffUL, 1); - - /* Add the module command line */ - sprintf(mod_clp, "%s", mod_command_line); diff --git a/kexec-tools-1.101-ppc-boots-ppc64.patch b/kexec-tools-1.101-ppc-boots-ppc64.patch deleted file mode 100644 index 45eb7a7..0000000 --- a/kexec-tools-1.101-ppc-boots-ppc64.patch +++ /dev/null @@ -1,292 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-rel-ppc64.c.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-rel-ppc64.c 2007-04-10 15:34:06.000000000 -0400 -@@ -101,10 +101,10 @@ - break; - - case R_PPC64_ADDR16_HIGHEST: -- *(uint16_t *)location = ((value>>48) & 0xffff); -+ *(uint16_t *)location = (((uint64_t)value>>48) & 0xffff); - break; - case R_PPC64_ADDR16_HIGHER: -- *(uint16_t *)location = ((value>>32) & 0xffff); -+ *(uint16_t *)location = (((uint64_t)value>>32) & 0xffff); - break; - - default: ---- kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.h.orig 2007-04-10 15:34:59.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.h 2007-04-10 15:35:16.000000000 -0400 -@@ -25,7 +25,7 @@ - #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) - #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) - --extern unsigned long long crash_base; --extern unsigned long long crash_size; -+extern uint64_t crash_base; -+extern uint64_t crash_size; - - #endif /* CRASHDUMP_PPC64_H */ ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c.orig 2007-04-10 15:33:47.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c 2007-04-10 15:34:06.000000000 -0400 -@@ -42,7 +42,7 @@ - #define BOOTLOADER "kexec" - #define BOOTLOADER_VERSION VERSION - --unsigned long initrd_base, initrd_size; -+uint64_t initrd_base, initrd_size; - - int create_flatten_tree(struct kexec_info *, unsigned char **, unsigned long *, - char *); -@@ -76,19 +76,19 @@ - char *cmdline, *modified_cmdline; - const char *ramdisk, *devicetreeblob; - int cmdline_len, modified_cmdline_len; -- unsigned long long max_addr, hole_addr; -+ uint64_t max_addr, hole_addr; - unsigned char *seg_buf = NULL; - off_t seg_size = 0; - struct mem_phdr *phdr; - size_t size; -- unsigned long long *rsvmap_ptr; -+ uint64_t *rsvmap_ptr; - struct bootblock *bb_ptr; - unsigned int nr_segments, i; - int result, opt; -- unsigned long my_kernel, my_dt_offset; -+ uint64_t my_kernel, my_dt_offset; - unsigned int my_panic_kernel; -- unsigned long my_stack, my_backup_start; -- unsigned long toc_addr; -+ uint64_t my_stack, my_backup_start; -+ uint64_t toc_addr; - - #define OPT_APPEND (OPT_ARCH_MAX+0) - #define OPT_RAMDISK (OPT_ARCH_MAX+1) -@@ -226,10 +226,10 @@ - } - seg_buf = (unsigned char *)slurp_file(ramdisk, &seg_size); - add_buffer(info, seg_buf, seg_size, seg_size, 0, 0, max_addr, 1); -- hole_addr = (unsigned long long) -+ hole_addr = (uint64_t) - info->segment[info->nr_segments-1].mem; - initrd_base = hole_addr; -- initrd_size = (unsigned long long) -+ initrd_size = (uint64_t) - info->segment[info->nr_segments-1].memsz; - } /* ramdisk */ - -@@ -259,25 +259,25 @@ - */ - bb_ptr = (struct bootblock *)( - (unsigned char *)info->segment[(info->nr_segments)-1].buf); -- rsvmap_ptr = (unsigned long long *)( -+ rsvmap_ptr = (uint64_t *)( - (unsigned char *)info->segment[(info->nr_segments)-1].buf + - bb_ptr->off_mem_rsvmap); - while (*rsvmap_ptr || *(rsvmap_ptr+1)) - rsvmap_ptr += 2; - rsvmap_ptr -= 2; -- *rsvmap_ptr = (unsigned long long)( -+ *rsvmap_ptr = (uint64_t)( - info->segment[(info->nr_segments)-1].mem); - rsvmap_ptr++; -- *rsvmap_ptr = (unsigned long long)bb_ptr->totalsize; -+ *rsvmap_ptr = (uint64_t)bb_ptr->totalsize; - - nr_segments = info->nr_segments; - - /* Set kernel */ -- my_kernel = (unsigned long )info->segment[0].mem; -+ my_kernel = (uint64_t)info->segment[0].mem; - elf_rel_set_symbol(&info->rhdr, "kernel", &my_kernel, sizeof(my_kernel)); - - /* Set dt_offset */ -- my_dt_offset = (unsigned long )info->segment[nr_segments-1].mem; -+ my_dt_offset = (uint64_t)info->segment[nr_segments-1].mem; - elf_rel_set_symbol(&info->rhdr, "dt_offset", &my_dt_offset, - sizeof(my_dt_offset)); - ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.h.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.h 2007-04-10 15:34:06.000000000 -0400 -@@ -15,7 +15,7 @@ - void elf_ppc64_usage(void); - void reserve(unsigned long long where, unsigned long long length); - --extern unsigned long initrd_base, initrd_size; -+extern uint64_t initrd_base, initrd_size; - /* boot block version 2 as defined by the linux kernel */ - struct bootblock { - unsigned magic, ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c 2007-04-10 15:34:06.000000000 -0400 -@@ -35,12 +35,12 @@ - #include - - static struct exclude_range exclude_range[MAX_MEMORY_RANGES]; --static unsigned long long rmo_top; -+static uint64_t rmo_top; - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - static struct memory_range base_memory_range[MAX_MEMORY_RANGES]; --unsigned long long memory_max = 0; -+uint64_t memory_max = 0; - static int nr_memory_ranges, nr_exclude_ranges; --unsigned long long crash_base, crash_size; -+uint64_t crash_base, crash_size; - - static int sort_base_ranges(); - -@@ -90,10 +90,10 @@ - if (local_memory_ranges >= MAX_MEMORY_RANGES) - break; - base_memory_range[local_memory_ranges].start = -- ((unsigned long long *)buf)[0]; -+ ((uint64_t *)buf)[0]; - base_memory_range[local_memory_ranges].end = - base_memory_range[local_memory_ranges].start + -- ((unsigned long long *)buf)[1]; -+ ((uint64_t *)buf)[1]; - base_memory_range[local_memory_ranges].type = RANGE_RAM; - local_memory_ranges++; - #ifdef DEBUG -@@ -120,7 +120,7 @@ - static int sort_base_ranges() - { - int i, j; -- unsigned long long tstart, tend; -+ uint64_t tstart, tend; - - for (i = 0; i < nr_memory_ranges - 1; i++) { - for (j = 0; j < nr_memory_ranges - i - 1; j++) { -@@ -141,7 +141,7 @@ - static int sort_ranges() - { - int i, j; -- unsigned long long tstart, tend; -+ uint64_t tstart, tend; - for (i = 0; i < nr_exclude_ranges - 1; i++) { - for (j = 0; j < nr_exclude_ranges - i - 1; j++) { - if (exclude_range[j].start > exclude_range[j+1].start) { -@@ -162,12 +162,12 @@ - */ - static int get_devtree_details(unsigned long kexec_flags) - { -- unsigned long long rmo_base; -- unsigned long long tce_base; -+ uint64_t rmo_base; -+ uint64_t tce_base; - unsigned int tce_size; - unsigned int rtas_base, rtas_size; -- unsigned long long htab_base, htab_size; -- unsigned long long kernel_end; -+ uint64_t htab_base, htab_size; -+ uint64_t kernel_end; - char buf[MAXBYTES-1]; - char device_tree[256] = "/proc/device-tree/"; - char fname[256]; -@@ -203,7 +203,7 @@ - closedir(dir); - return -1; - } -- if (fread(&kernel_end, sizeof(unsigned long), 1, file) != 1) { -+ if (fread(&kernel_end, sizeof(uint64_t), 1, file) != 1) { - perror(fname); - fclose(file); - closedir(cdir); -@@ -228,7 +228,7 @@ - closedir(dir); - return -1; - } -- if (fread(&crash_base, sizeof(unsigned long), 1, -+ if (fread(&crash_base, sizeof(uint64_t), 1, - file) != 1) { - perror(fname); - fclose(file); -@@ -248,7 +248,7 @@ - closedir(dir); - return -1; - } -- if (fread(&crash_size, sizeof(unsigned long), 1, -+ if (fread(&crash_size, sizeof(uint64_t), 1, - file) != 1) { - perror(fname); - fclose(file); -@@ -281,7 +281,7 @@ - closedir(dir); - return -1; - } -- if (fread(&htab_base, sizeof(unsigned long), 1, file) != 1) { -+ if (fread(&htab_base, sizeof(uint64_t), 1, file) != 1) { - perror(fname); - fclose(file); - closedir(cdir); -@@ -298,7 +298,7 @@ - closedir(dir); - return -1; - } -- if (fread(&htab_size, sizeof(unsigned long), 1, file) != 1) { -+ if (fread(&htab_size, sizeof(uint64_t), 1, file) != 1) { - perror(fname); - fclose(file); - closedir(cdir); -@@ -367,8 +367,8 @@ - closedir(dir); - return -1; - } -- rmo_base = ((unsigned long long *)buf)[0]; -- rmo_top = rmo_base + ((unsigned long long *)buf)[1]; -+ rmo_base = ((uint64_t *)buf)[0]; -+ rmo_top = rmo_base + ((uint64_t *)buf)[1]; - if (rmo_top > 0x07C00000UL) - rmo_top = 0x07C00000UL; - -@@ -389,7 +389,7 @@ - closedir(dir); - return -1; - } -- if (fread(&tce_base, sizeof(unsigned long), 1, file) != 1) { -+ if (fread(&tce_base, sizeof(uint64_t), 1, file) != 1) { - perror(fname); - fclose(file); - closedir(cdir); ---- kexec-tools-1.101/kexec/kexec-sha256.h.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/kexec/kexec-sha256.h 2007-04-10 15:34:06.000000000 -0400 -@@ -2,8 +2,8 @@ - #define KEXEC_SHA256_H - - struct sha256_region { -- const void *start; -- unsigned long len; -+ uint64_t start; -+ uint64_t len; - }; - - #define SHA256_REGIONS 16 ---- kexec-tools-1.101/purgatory/Makefile.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/purgatory/Makefile 2007-04-10 15:34:06.000000000 -0400 -@@ -57,9 +57,9 @@ - $(MKDIR) -p $(@D) - $(CC) $(PCFLAGS) -o $@ -c $< - --$(PURGATORY): $(PURGATORY_OBJS) $(UTIL_LIB) -+$(PURGATORY): $(PURGATORY_OBJS) - $(MKDIR) -p $(@D) -- $(LD) $(LDFLAGS) --no-undefined -e purgatory_start -r -o $@ $(PURGATORY_OBJS) $(UTIL_LIB) -+ $(LD) $(LDFLAGS) --no-undefined -e purgatory_start -r -o $@ $(PURGATORY_OBJS) - - echo:: - @echo "PURGATORY_C_SRCS $(PURGATORY_C_SRCS)" ---- kexec-tools-1.101/purgatory/arch/ppc64/Makefile.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/purgatory/arch/ppc64/Makefile 2007-04-10 15:34:06.000000000 -0400 -@@ -6,3 +6,5 @@ - PURGATORY_C_SRCS += purgatory/arch/ppc64/purgatory-ppc64.c - PURGATORY_C_SRCS += purgatory/arch/ppc64/console-ppc64.c - PURGATORY_C_SRCS += purgatory/arch/ppc64/crashdump_backup.c -+ -+PCFLAGS += -m64 -mcall-aixdesc ---- kexec-tools-1.101/purgatory/purgatory.c.orig 2007-04-10 15:33:46.000000000 -0400 -+++ kexec-tools-1.101/purgatory/purgatory.c 2007-04-10 15:34:06.000000000 -0400 -@@ -46,3 +46,5 @@ - verify_sha256_digest(); - post_verification_setup_arch(); - } -+ -+#include "../util_lib/sha256.c" diff --git a/kexec-tools-1.101-ppc-fixup.patch b/kexec-tools-1.101-ppc-fixup.patch deleted file mode 100644 index e1953dc..0000000 --- a/kexec-tools-1.101-ppc-fixup.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc/kexec-ppc.c.orig 2006-07-05 16:21:50.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc/kexec-ppc.c 2006-07-05 16:22:01.000000000 -0400 -@@ -33,7 +33,6 @@ int get_memory_ranges(struct memory_rang - memory_range[memory_ranges].type = RANGE_RAM; - memory_ranges++; - #else --#error Please, fix this for your platform - const char iomem[] = "/proc/iomem"; - char line[MAX_LINE]; - FILE *fp; diff --git a/kexec-tools-1.101-ppc64-64k-pages.patch b/kexec-tools-1.101-ppc64-64k-pages.patch deleted file mode 100644 index 2ffe7ac..0000000 --- a/kexec-tools-1.101-ppc64-64k-pages.patch +++ /dev/null @@ -1,111 +0,0 @@ -Signed-off-by: Sachin Sant ---- - -diff -Naurp kexec-tools-rh/kexec/arch/ppc64/crashdump-ppc64.c kexec-tools-rh-fix/kexec/arch/ppc64/crashdump-ppc64.c ---- kexec-tools-rh/kexec/arch/ppc64/crashdump-ppc64.c 2006-09-08 07:29:52.000000000 +0530 -+++ kexec-tools-rh-fix/kexec/arch/ppc64/crashdump-ppc64.c 2006-09-08 07:32:19.000000000 +0530 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -85,8 +86,8 @@ static int get_crash_memory_ranges(struc - unsigned long long start, end, cstart, cend; - - /* create a separate program header for the backup region */ -- crash_memory_range[0].start = 0x0000000000000000; -- crash_memory_range[0].end = 0x0000000000008000; -+ crash_memory_range[0].start = BACKUP_START; -+ crash_memory_range[0].end = BACKUP_END; - crash_memory_range[0].type = RANGE_RAM; - memory_ranges++; - -@@ -125,8 +126,8 @@ static int get_crash_memory_ranges(struc - break; - start = ((unsigned long long *)buf)[0]; - end = start + ((unsigned long long *)buf)[1]; -- if (start == 0 && end >= 0x8000) -- start = 0x8000; -+ if (start == 0 && end >= BACKUP_END) -+ start = BACKUP_END; - match = 0; - sort_regions(&exclude_rgns); - -@@ -420,8 +421,8 @@ void add_usable_mem_rgns(unsigned long l - unsigned long long end = base + size; - unsigned long long ustart, uend; - -- base = _ALIGN_DOWN(base, PAGE_SIZE); -- end = _ALIGN_UP(end, PAGE_SIZE); -+ base = _ALIGN_DOWN(base, getpagesize()); -+ end = _ALIGN_UP(end, getpagesize()); - - for (i=0; i < usablemem_rgns.size; i++) { - ustart = usablemem_rgns.ranges[i].start; -diff -Naurp kexec-tools-rh/kexec/arch/ppc64/crashdump-ppc64.h kexec-tools-rh-fix/kexec/arch/ppc64/crashdump-ppc64.h ---- kexec-tools-rh/kexec/arch/ppc64/crashdump-ppc64.h 2006-09-08 07:29:52.000000000 +0530 -+++ kexec-tools-rh-fix/kexec/arch/ppc64/crashdump-ppc64.h 2006-09-08 07:33:38.000000000 +0530 -@@ -6,28 +6,24 @@ int load_crashdump_segments(struct kexec - void add_usable_mem_rgns(unsigned long long base, unsigned long long size); - void add_exclude_rgns(unsigned long long base, unsigned long long size); - --#define PAGE_OFFSET 0xC000000000000000 -+#define PAGE_OFFSET 0xC000000000000000 - #define KERNELBASE PAGE_OFFSET - #define VMALLOCBASE 0xD000000000000000 - - #define __pa(x) ((unsigned long)(x)-PAGE_OFFSET) -- --#define MAXMEM (-KERNELBASE-VMALLOCBASE) -+#define MAXMEM (-KERNELBASE-VMALLOCBASE) - - #define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 6) - - #define COMMAND_LINE_SIZE 512 /* from kernel */ --/* Backup Region, First 32K of System RAM. */ -+/* Backup Region, First 64K of System RAM. */ - #define BACKUP_START 0x0000 --#define BACKUP_END 0x8000 -+#define BACKUP_END 0x10000 - #define BACKUP_SIZE (BACKUP_END - BACKUP_START + 1) - --#define KDUMP_BACKUP_LIMIT 0x8000 -+#define KDUMP_BACKUP_LIMIT BACKUP_END - #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) - #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1))) --#ifndef PAGE_SIZE --#define PAGE_SIZE 4096 --#endif - - extern unsigned long long crash_base; - extern unsigned long long crash_size; -diff -Naurp kexec-tools-rh/purgatory/arch/ppc64/crashdump_backup.c kexec-tools-rh-fix/purgatory/arch/ppc64/crashdump_backup.c ---- kexec-tools-rh/purgatory/arch/ppc64/crashdump_backup.c 2006-09-08 07:29:52.000000000 +0530 -+++ kexec-tools-rh-fix/purgatory/arch/ppc64/crashdump_backup.c 2006-09-08 08:42:27.000000000 +0530 -@@ -21,9 +21,7 @@ - - #include - #include -- --#define BACKUP_REGION_SOURCE 0x0 --#define BACKUP_REGION_SIZE 32*1024 -+#include "../../../kexec/arch/ppc64/crashdump-ppc64.h" - - extern unsigned long backup_start; - -@@ -32,10 +30,10 @@ void crashdump_backup_memory(void) - { - void *dest, *src; - -- src = (void *)BACKUP_REGION_SOURCE; -+ src = (void *)BACKUP_START; - - if (backup_start) { - dest = (void *)(backup_start); -- memcpy(dest, src, BACKUP_REGION_SIZE); -+ memcpy(dest, src, BACKUP_SIZE); - } - } diff --git a/kexec-tools-1.101-ppc64-align-dtstruct.patch b/kexec-tools-1.101-ppc64-align-dtstruct.patch deleted file mode 100644 index 2de263f..0000000 --- a/kexec-tools-1.101-ppc64-align-dtstruct.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c~ 2006-04-27 15:01:55.000000000 +0900 -+++ kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c 2006-05-08 14:15:50.571330714 +0900 -@@ -61,7 +61,8 @@ - struct stat statbuf[1]; - char pathname[MAXPATH], *pathstart; - char propnames[NAMESPACE]; --dvt dtstruct[TREEWORDS], *dt; -+dvt dtstruct[TREEWORDS] __attribute((aligned(8))); -+dvt *dt; - unsigned long long mem_rsrv[2*MEMRESERVE]; - - static int initrd_found = 0; diff --git a/kexec-tools-1.101-ppc64-bootargs-align.patch b/kexec-tools-1.101-ppc64-bootargs-align.patch deleted file mode 100644 index 03da127..0000000 --- a/kexec-tools-1.101-ppc64-bootargs-align.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c.org 2006-04-26 13:12:55.515946645 +0900 -+++ kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c 2006-04-26 13:50:00.665270758 +0900 -@@ -275,6 +275,8 @@ - strcat(local_cmdline, " "); - cmd_len = strlen(local_cmdline); - cmd_len = cmd_len + 1; -+ if ((cmd_len >= 8) && ((unsigned long)dt & 0x4)) -+ dt++; - memcpy(dt,local_cmdline,cmd_len); - len = cmd_len; - *dt_len = cmd_len; diff --git a/kexec-tools-1.101-ppc64-cliargs.patch b/kexec-tools-1.101-ppc64-cliargs.patch deleted file mode 100644 index 8f78d25..0000000 --- a/kexec-tools-1.101-ppc64-cliargs.patch +++ /dev/null @@ -1,21 +0,0 @@ -Index: kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c -=================================================================== ---- kexec-tools-1.101.orig/kexec/arch/ppc64/fs2dt.c -+++ kexec-tools-1.101/kexec/arch/ppc64/fs2dt.c -@@ -267,10 +267,12 @@ void putprops(char *fn, struct dirent ** - char *old_param; - memcpy(temp_cmdline, dt, len); - param = strstr(temp_cmdline, "root="); -- old_param = strtok(param, " "); -- if (cmd_len != 0) -- strcat(local_cmdline, " "); -- strcat(local_cmdline, old_param); -+ if (param) { -+ old_param = strtok(param, " "); -+ if (cmd_len != 0) -+ strcat(local_cmdline, " "); -+ strcat(local_cmdline, old_param); -+ } - } - strcat(local_cmdline, " "); - cmd_len = strlen(local_cmdline); diff --git a/kexec-tools-1.101-ppc64-ignore-args.patch b/kexec-tools-1.101-ppc64-ignore-args.patch deleted file mode 100644 index 2894b55..0000000 --- a/kexec-tools-1.101-ppc64-ignore-args.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/kexec/arch/ppc64/kexec-elf-ppc64.c -+++ b/kexec/arch/ppc64/kexec-elf-ppc64.c -@@ -93,6 +93,7 @@ int elf_ppc64_load(int argc, char **argv - #define OPT_APPEND (OPT_ARCH_MAX+0) - #define OPT_RAMDISK (OPT_ARCH_MAX+1) - #define OPT_DEVICETREEBLOB (OPT_ARCH_MAX+2) -+#define OPT_ARGS_IGNORE (OPT_ARCH_MAX+3) - - static const struct option options[] = { - KEXEC_ARCH_OPTIONS -@@ -101,6 +102,7 @@ int elf_ppc64_load(int argc, char **argv - { "ramdisk", 1, NULL, OPT_RAMDISK }, - { "initrd", 1, NULL, OPT_RAMDISK }, - { "devicetreeblob", 1, NULL, OPT_DEVICETREEBLOB }, -+ { "args-linux", 0, NULL, OPT_ARGS_IGNORE }, - { 0, 0, NULL, 0 }, - }; - -@@ -134,6 +136,8 @@ int elf_ppc64_load(int argc, char **argv - case OPT_DEVICETREEBLOB: - devicetreeblob = optarg; - break; -+ case OPT_ARGS_IGNORE: -+ break; - } - } - diff --git a/kexec-tools-1.101-ppc64-memory_regions.patch b/kexec-tools-1.101-ppc64-memory_regions.patch deleted file mode 100644 index 4928112..0000000 --- a/kexec-tools-1.101-ppc64-memory_regions.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.c.orig 2007-03-21 13:08:54.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/crashdump-ppc64.c 2007-03-21 13:14:06.000000000 -0400 -@@ -143,10 +143,10 @@ - if (start < cstart && end > cend) { - match = 1; - crash_memory_range[memory_ranges].start = start; -- crash_memory_range[memory_ranges].end = cstart - 1; -+ crash_memory_range[memory_ranges].end = cstart; - crash_memory_range[memory_ranges].type = RANGE_RAM; - memory_ranges++; -- crash_memory_range[memory_ranges].start = cend + 1; -+ crash_memory_range[memory_ranges].start = cend; - crash_memory_range[memory_ranges].end = end; - crash_memory_range[memory_ranges].type = RANGE_RAM; - memory_ranges++; -@@ -154,18 +154,18 @@ - } else if (start < cstart) { - match = 1; - crash_memory_range[memory_ranges].start = start; -- crash_memory_range[memory_ranges].end = cstart - 1; -+ crash_memory_range[memory_ranges].end = cstart; - crash_memory_range[memory_ranges].type = RANGE_RAM; - memory_ranges++; -- end = cstart - 1; -+ end = cstart; - continue; - } else if (end > cend){ - match = 1; -- crash_memory_range[memory_ranges].start = cend + 1; -+ crash_memory_range[memory_ranges].start = cend; - crash_memory_range[memory_ranges].end = end; - crash_memory_range[memory_ranges].type = RANGE_RAM; - memory_ranges++; -- start = cend + 1; -+ start = cend; - continue; - } - } diff --git a/kexec-tools-1.101-ppc64-platform-fix.patch b/kexec-tools-1.101-ppc64-platform-fix.patch deleted file mode 100644 index 6152642..0000000 --- a/kexec-tools-1.101-ppc64-platform-fix.patch +++ /dev/null @@ -1,116 +0,0 @@ - -In recent kernels, the plaform property is removed from the /proc/device-tree. -This property is used to determine whether the platform is LPAR or non-lpar, -and reads htab-* and tce-* properties based on the platform. Fixed this issue -such that read these properties if exists, otherwise continue instead of -exiting with an error message. - -Signed-off-by: David Wilder -Signed-off-by: Haren Myneni ---- - kexec/arch/ppc64/kexec-ppc64.c | 55 +++++++++++------------------------------ - 1 file changed, 15 insertions(+), 40 deletions(-) - -Index: kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c -=================================================================== ---- kexec-tools-1.101.orig/kexec/arch/ppc64/kexec-ppc64.c -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c -@@ -34,13 +34,8 @@ - #include "crashdump-ppc64.h" - #include - --/* Platforms supported by kexec on PPC64 */ --#define PLATFORM_PSERIES 0x0100 --#define PLATFORM_PSERIES_LPAR 0x0101 -- - static struct exclude_range exclude_range[MAX_MEMORY_RANGES]; - static unsigned long long rmo_top; --static unsigned int platform; - static struct memory_range memory_range[MAX_MEMORY_RANGES]; - static struct memory_range base_memory_range[MAX_MEMORY_RANGES]; - unsigned long long memory_max = 0; -@@ -201,26 +196,6 @@ static int get_devtree_details(unsigned - } - - if (strncmp(dentry->d_name, "chosen", 6) == 0) { -- /* get platform details from /chosen node */ -- strcat(fname, "/linux,platform"); -- if ((file = fopen(fname, "r")) == NULL) { -- perror(fname); -- closedir(cdir); -- closedir(dir); -- return -1; -- } -- if (fread(&platform, sizeof(int), 1, file) != 1) { -- perror(fname); -- fclose(file); -- closedir(cdir); -- closedir(dir); -- return -1; -- } -- fclose(file); -- -- memset(fname, 0, sizeof(fname)); -- strcpy(fname, device_tree); -- strcat(fname, dentry->d_name); - strcat(fname, "/linux,kernel-end"); - if ((file = fopen(fname, "r")) == NULL) { - perror(fname); -@@ -291,18 +266,18 @@ static int get_devtree_details(unsigned - reserve(KDUMP_BACKUP_LIMIT, crash_base-KDUMP_BACKUP_LIMIT); - } - -- /* if LPAR, no need to read any more from /chosen */ -- if (platform != PLATFORM_PSERIES) { -- closedir(cdir); -- continue; -- } - memset(fname, 0, sizeof(fname)); - strcpy(fname, device_tree); - strcat(fname, dentry->d_name); - strcat(fname, "/linux,htab-base"); - if ((file = fopen(fname, "r")) == NULL) { -- perror(fname); - closedir(cdir); -+ if (errno == ENOENT) { -+ /* Non LPAR */ -+ errno = 0; -+ continue; -+ } -+ perror(fname); - closedir(dir); - return -1; - } -@@ -394,23 +369,23 @@ static int get_devtree_details(unsigned - } - rmo_base = ((unsigned long long *)buf)[0]; - rmo_top = rmo_base + ((unsigned long long *)buf)[1]; -- if (platform == PLATFORM_PSERIES) { -- if (rmo_top > 0x30000000UL) -- rmo_top = 0x30000000UL; -- } -+ if (rmo_top > 0x30000000UL) -+ rmo_top = 0x30000000UL; -+ - fclose(file); - closedir(cdir); - } /* memory */ - - if (strncmp(dentry->d_name, "pci@", 4) == 0) { -- if (platform != PLATFORM_PSERIES) { -- closedir(cdir); -- continue; -- } - strcat(fname, "/linux,tce-base"); - if ((file = fopen(fname, "r")) == NULL) { -- perror(fname); - closedir(cdir); -+ if (errno == ENOENT) { -+ /* Non LPAR */ -+ errno = 0; -+ continue; -+ } -+ perror(fname); - closedir(dir); - return -1; - } diff --git a/kexec-tools-1.101-ppc64-usage.patch b/kexec-tools-1.101-ppc64-usage.patch deleted file mode 100644 index 57467d1..0000000 --- a/kexec-tools-1.101-ppc64-usage.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c.orig 2006-10-20 11:10:39.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c 2006-10-20 11:11:22.000000000 -0400 -@@ -577,6 +577,10 @@ - - void arch_usage(void) - { -+ fprintf(stderr, " --command-line= command line to append.\n"); -+ fprintf(stderr, " --append= same as --command-line.\n"); -+ fprintf(stderr, " --ramdisk= Initial RAM disk.\n"); -+ fprintf(stderr, " --initrd= same as --ramdisk.\n"); - fprintf(stderr, " --devicetreeblob= Specify device tree blob file.\n"); - fprintf(stderr, " --elf64-core-headers Prepare core headers in ELF64 format\n"); - } diff --git a/kexec-tools-1.101-ppc64_rmo_top.patch b/kexec-tools-1.101-ppc64_rmo_top.patch deleted file mode 100644 index 8f062b0..0000000 --- a/kexec-tools-1.101-ppc64_rmo_top.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c.orig 2007-04-10 10:53:44.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-ppc64.c 2007-04-10 10:53:58.000000000 -0400 -@@ -369,8 +369,8 @@ - } - rmo_base = ((unsigned long long *)buf)[0]; - rmo_top = rmo_base + ((unsigned long long *)buf)[1]; -- if (rmo_top > 0x30000000UL) -- rmo_top = 0x30000000UL; -+ if (rmo_top > 0x07C00000UL) -+ rmo_top = 0x07C00000UL; - - fclose(file); - closedir(cdir); diff --git a/kexec-tools-1.101-reloc-update.patch b/kexec-tools-1.101-reloc-update.patch deleted file mode 100644 index fa2e7cd..0000000 --- a/kexec-tools-1.101-reloc-update.patch +++ /dev/null @@ -1,1040 +0,0 @@ ---- kexec-tools-1.101/purgatory/arch/x86_64/include/arch/debug.h.orig 2004-12-20 18:05:40.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/x86_64/include/arch/debug.h 2007-01-05 13:32:24.000000000 -0500 -@@ -311,7 +311,7 @@ - TTYS0_TX_AL - - --#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') -+#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - ---- kexec-tools-1.101/purgatory/arch/i386/linux-entry16.S.orig 2004-12-20 05:48:45.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/i386/linux-entry16.S 2007-01-05 13:32:24.000000000 -0500 -@@ -127,10 +127,10 @@ - TTYS0_TX_AL - - --#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') -+#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #else --#define DEBUG(x) -+#define DEBUG_CHAR(x) - #define DEBUG_TX_HEX32(x) - #endif - -@@ -142,15 +142,15 @@ - entry16: - .code32 - --DEBUG('a') -+DEBUG_CHAR('a') - /* Setup the classic BIOS interrupt table at 0x0 */ - lidt idtptr - --DEBUG('b') -+DEBUG_CHAR('b') - /* Provide us with 16bit segments that we can use */ - lgdt gdt - --DEBUG('c') -+DEBUG_CHAR('c') - /* Note we don't disable the a20 line, (this shouldn't be required) - * The code to do it is in kexec_test and it is a real pain. - * I will worry about that when I need it. -@@ -164,26 +164,26 @@ DEBUG('c') - movl %eax, %fs - movl %eax, %gs - --DEBUG('d') -+DEBUG_CHAR('d') - - /* switch to 16bit mode */ - ljmp $0x08, $1f - entry16 - 1: - .code16 --DEBUG('e') -+DEBUG_CHAR('e') - /* Disable Paging and protected mode */ - /* clear the PG & PE bits of CR0 */ - movl %cr0,%eax - andl $~((1 << 31)|(1<<0)),%eax - movl %eax,%cr0 - --DEBUG('f') -+DEBUG_CHAR('f') - /* make intersegment jmp to flush the processor pipeline - * and reload %cs:%eip (to clear upper 16 bits of %eip). - */ - ljmp *(realptr - entry16) - 3: --DEBUG('g') -+DEBUG_CHAR('g') - /* we are in real mode now - * set up the real mode segment registers : %ds, $ss, %es - */ -@@ -191,7 +191,7 @@ DEBUG('g') - movw %cs, %ax - movw %ax, %ds - --DEBUG('h') -+DEBUG_CHAR('h') - /* Load the registers */ - movl eax - entry16, %eax - movl ebx - entry16, %ebx -@@ -386,10 +386,10 @@ gdt_end: - TTYS0_TX_AL - - --#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') -+#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #else --#define DEBUG(x) -+#define DEBUG_CHAR(x) - #define DEBUG_TX_HEX32(x) - #endif - -@@ -403,7 +403,7 @@ setup16_debug_start: - _reloc = . - .balign 16 - .code32 --DEBUG('a') -+DEBUG_CHAR('a') - /* Compute where I am running at */ - call 1f - 1: popl %ebx -@@ -412,13 +412,13 @@ DEBUG('a') - /* Remember where I am running at */ - movl %ebx, location - _reloc(%ebx) - --DEBUG('b') -+DEBUG_CHAR('b') - /* Fixup my real mode segment */ - movl %ebx, %eax - shrl $4, %eax - movw %ax, 2 + realptr - _reloc(%ebx) - --DEBUG('c') -+DEBUG_CHAR('c') - /* Fixup the gdt */ - movl %ebx, %eax - shll $16, %eax -@@ -440,7 +440,7 @@ DEBUG('c') - - - --DEBUG('d') -+DEBUG_CHAR('d') - /* Setup the classic BIOS interrupt table at 0x0 */ - lidt idtptr - _reloc(%ebx) - -@@ -465,20 +465,20 @@ DEBUG('d') - ljmp $0x08, $2f - _reloc - 2: - .code16 --DEBUG('e') -+DEBUG_CHAR('e') - /* Disable Paging and protected mode */ - /* clear the PG & PE bits of CR0 */ - movl %cr0,%eax - andl $~((1 << 31)|(1<<0)),%eax - movl %eax,%cr0 - --DEBUG('f') -+DEBUG_CHAR('f') - /* make intersegment jmp to flush the processor pipeline - * and reload %cs:%eip (to clear upper 16 bits of %eip). - */ - ljmp *(realptr - _reloc) - 3: --DEBUG('g') -+DEBUG_CHAR('g') - /* we are in real mode now - * set up the real mode segment registers : %ds, $ss, %es - */ -@@ -486,7 +486,7 @@ DEBUG('g') - movw %cs, %ax - movw %ax, %ds - --DEBUG('h') -+DEBUG_CHAR('h') - /* Load the registers */ - movl eax - _reloc, %eax - movl ebx - _reloc, %ebx -@@ -600,7 +600,7 @@ debug_gdt_end: - - setup16_debug_kernel_pre_protected: - .code16 -- DEBUG('i') -+ DEBUG_CHAR('i') - cli # no interrupts allowed ! - movb $0x80, %al # disable NMI for bootup - # sequence -@@ -611,7 +611,7 @@ setup16_debug_first_code32: - .byte 0xbf /* movl $0x12345678, %edi */ - location: - .long 0x12345678 -- DEBUG('j') -+ DEBUG_CHAR('j') - .byte 0xb8 /* movl $0x10000, %eax */ - setup16_debug_old_code32: - .long 0x10000 ---- kexec-tools-1.101/purgatory/arch/i386/entry32-16-debug.S.orig 2004-12-20 18:11:43.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/i386/entry32-16-debug.S 2007-01-05 13:32:24.000000000 -0500 -@@ -55,15 +55,15 @@ entry16_debug: - orl %ecx, 0x14 + gdt - - --DEBUG('a') -+DEBUG_CHAR('a') - /* Setup the classic BIOS interrupt table at 0x0 */ - lidt idtptr - --DEBUG('b') -+DEBUG_CHAR('b') - /* Provide us with 16bit segments that we can use */ - lgdt gdt - --DEBUG('c') -+DEBUG_CHAR('c') - /* Note we don't disable the a20 line, (this shouldn't be required) - * The code to do it is in kexec_test and it is a real pain. - * I will worry about that when I need it. -@@ -77,26 +77,26 @@ DEBUG('c') - movl %eax, %fs - movl %eax, %gs - --DEBUG('d') -+DEBUG_CHAR('d') - - /* switch to 16bit mode */ - ljmp $0x08, $1f - entry16_debug - 1: - .code16 --DEBUG('e') -+DEBUG_CHAR('e') - /* Disable Paging and protected mode */ - /* clear the PG & PE bits of CR0 */ - movl %cr0,%eax - andl $~((1 << 31)|(1<<0)),%eax - movl %eax,%cr0 - --DEBUG('f') -+DEBUG_CHAR('f') - /* make intersegment jmp to flush the processor pipeline - * and reload %cs:%eip (to clear upper 16 bits of %eip). - */ - ljmp *(realptr - entry16_debug) - 3: --DEBUG('g') -+DEBUG_CHAR('g') - /* we are in real mode now - * set up the real mode segment registers : %ds, $ss, %es - */ -@@ -104,7 +104,7 @@ DEBUG('g') - movw %cs, %ax - movw %ax, %ds - --DEBUG('h') -+DEBUG_CHAR('h') - /* Load the registers */ - movl eax - entry16_debug, %eax - movl ebx - entry16_debug, %ebx -@@ -176,7 +176,7 @@ gdt_end: - .text - entry16_debug_pre32: - .code16 --DEBUG('i') -+DEBUG_CHAR('i') - cli # no interrupts allowed ! - movb $0x80, %al # disable NMI for bootup - # sequence -@@ -186,7 +186,7 @@ DEBUG('i') - - entry16_debug_first32: - .code32 --DEBUG('j') -+DEBUG_CHAR('j') - .byte 0xb8 /* movl $0x10000, %eax */ - entry16_debug_old_first32: - .long 0x100000 ---- kexec-tools-1.101/purgatory/arch/i386/include/arch/debug.h.orig 2004-12-20 18:03:17.000000000 -0500 -+++ kexec-tools-1.101/purgatory/arch/i386/include/arch/debug.h 2007-01-05 13:32:24.000000000 -0500 -@@ -311,6 +311,6 @@ - TTYS0_TX_AL - - --#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') -+#define DEBUG_CHAR(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') - #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') ---- kexec-tools-1.101/kexec/Makefile.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/Makefile 2007-01-05 13:32:24.000000000 -0500 -@@ -13,6 +13,7 @@ KEXEC_C_SRCS:= kexec/kexec.c - KEXEC_C_SRCS+= kexec/ifdown.c - KEXEC_C_SRCS+= kexec/kexec-elf.c - KEXEC_C_SRCS+= kexec/kexec-elf-exec.c -+KEXEC_C_SRCS+= kexec/kexec-elf-core.c - KEXEC_C_SRCS+= kexec/kexec-elf-rel.c - KEXEC_C_SRCS+= kexec/kexec-elf-boot.c - KEXEC_C_SRCS+= kexec/crashdump.c ---- kexec-tools-1.101/kexec/kexec-elf-rel.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf-rel.c 2007-01-05 13:32:24.000000000 -0500 -@@ -135,10 +135,11 @@ static struct mem_rela elf_rela(struct m - return rela; - } - --int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr) -+int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - int result; -- result = build_elf_info(buf, len, ehdr); -+ result = build_elf_info(buf, len, ehdr, flags); - if (result < 0) { - return result; - } -@@ -412,12 +413,12 @@ int elf_rel_load(struct mem_ehdr *ehdr, - - void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, - const char *buf, off_t len, unsigned long min, unsigned long max, -- int end) -+ int end, uint32_t flags) - { - int result; - - /* Parse the Elf file */ -- result = build_elf_rel_info((char *)purgatory, purgatory_size, ehdr); -+ result = build_elf_rel_info(buf, len, ehdr, flags); - if (result < 0) { - die("ELF rel parse failed\n"); - } ---- kexec-tools-1.101/kexec/kexec-elf.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf.c 2007-01-05 13:32:24.000000000 -0500 -@@ -368,7 +368,8 @@ static int build_mem_elf64_phdr(const ch - return 0; - } - --static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) -+static int build_mem_phdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - size_t phdr_size, mem_phdr_size; - int i; -@@ -418,9 +419,11 @@ static int build_mem_phdrs(const char *b - - /* Check the program headers to be certain - * they are safe to use. -+ * Skip the check if ELF_SKIP_FILESZ_CHECK is set. - */ - phdr = &ehdr->e_phdr[i]; -- if ((phdr->p_offset + phdr->p_filesz) > len) { -+ if (!(flags & ELF_SKIP_FILESZ_CHECK) -+ && (phdr->p_offset + phdr->p_filesz) > len) { - /* The segment does not fit in the buffer */ - if (probe_debug) { - fprintf(stderr, "ELF segment not in file\n"); -@@ -580,7 +583,8 @@ static int build_mem_elf64_shdr(const ch - return 0; - } - --static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr) -+static int build_mem_shdrs(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - size_t shdr_size, mem_shdr_size; - int i; -@@ -628,11 +632,12 @@ static int build_mem_shdrs(const char *b - } - /* Check the section headers to be certain - * they are safe to use. -+ * Skip the check if ELF_SKIP_FILESZ_CHECK is set. - */ - shdr = &ehdr->e_shdr[i]; -- if ((shdr->sh_type != SHT_NOBITS) && -- ((shdr->sh_offset + shdr->sh_size) > len)) -- { -+ if (!(flags & ELF_SKIP_FILESZ_CHECK) -+ && (shdr->sh_type != SHT_NOBITS) -+ && (shdr->sh_offset + shdr->sh_size) > len) { - /* The section does not fit in the buffer */ - if (probe_debug) { - fprintf(stderr, "ELF section %d not in file\n", -@@ -710,7 +715,8 @@ static int build_mem_notes(const char *b - note_size += (hdr.n_descsz + 3) & ~3; - - if ((hdr.n_namesz != 0) && (name[hdr.n_namesz -1] != '\0')) { -- die("Note name is not null termiated"); -+ fprintf(stderr, "Note name is not null termiated\n"); -+ return -1; - } - ehdr->e_note[i].n_type = hdr.n_type; - ehdr->e_note[i].n_name = (char *)name; -@@ -729,7 +735,8 @@ void free_elf_info(struct mem_ehdr *ehdr - memset(ehdr, 0, sizeof(*ehdr)); - } - --int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr) -+int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - int result; - result = build_mem_ehdr(buf, len, ehdr); -@@ -737,14 +744,14 @@ int build_elf_info(const char *buf, off_ - return result; - } - if ((ehdr->e_phoff > 0) && (ehdr->e_phnum > 0)) { -- result = build_mem_phdrs(buf, len, ehdr); -+ result = build_mem_phdrs(buf, len, ehdr, flags); - if (result < 0) { - free_elf_info(ehdr); - return result; - } - } - if ((ehdr->e_shoff > 0) && (ehdr->e_shnum > 0)) { -- result = build_mem_shdrs(buf, len, ehdr); -+ result = build_mem_shdrs(buf, len, ehdr, flags); - if (result < 0) { - free_elf_info(ehdr); - return result; ---- kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ia64/kexec-elf-ia64.c 2007-01-05 13:32:24.000000000 -0500 -@@ -56,7 +56,7 @@ int elf_ia64_probe(const char *buf, off_ - { - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - if (probe_debug) { - fprintf(stderr, "Not an ELF executable\n"); -@@ -163,7 +163,7 @@ int elf_ia64_load(int argc, char **argv, - } - - /* Parse the Elf file */ -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - fprintf(stderr, "ELF parse failed\n"); - free_elf_info(&ehdr); -@@ -198,7 +198,7 @@ int elf_ia64_load(int argc, char **argv, - - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0x0, ULONG_MAX, -1); -+ 0x0, ULONG_MAX, -1, 0); - - - if (load_crashdump_segments(info, &ehdr, max_addr, 0, ---- kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/crashdump-x86_64.c 2007-01-05 13:32:24.000000000 -0500 -@@ -24,8 +24,10 @@ - #include - #include - #include -+#include - #include - #include -+#include - #include - #include "../../kexec.h" - #include "../../kexec-elf.h" -@@ -40,6 +42,137 @@ extern struct arch_options_t arch_option - /* Forward Declaration. */ - static int exclude_crash_reserve_region(int *nr_ranges); - -+#define KERN_VADDR_ALIGN 0x200000 /* 2MB */ -+ -+/* Read kernel physical load addr from /proc/iomem (Kernel Code) and -+ * store in kexec_info */ -+static int get_kernel_paddr(struct kexec_info *info) -+{ -+ const char iomem[]= "/proc/iomem"; -+ char line[MAX_LINE]; -+ FILE *fp; -+ unsigned long long start, end; -+ -+ fp = fopen(iomem, "r"); -+ if (!fp) { -+ fprintf(stderr, "Cannot open %s: %s\n", iomem, strerror(errno)); -+ return -1; -+ } -+ while(fgets(line, sizeof(line), fp) != 0) { -+ char *str; -+ int consumed, count; -+ count = sscanf(line, "%Lx-%Lx : %n", -+ &start, &end, &consumed); -+ if (count != 2) -+ continue; -+ str = line + consumed; -+#ifdef DEBUG -+ printf("%016Lx-%016Lx : %s", -+ start, end, str); -+#endif -+ if (memcmp(str, "Kernel code\n", 12) == 0) { -+ info->kern_paddr_start = start; -+ -+#ifdef DEBUG -+ printf("kernel load physical addr start = 0x%016Lx\n", -+ start); -+#endif -+ fclose(fp); -+ return 0; -+ } -+ } -+ fprintf(stderr, "Cannot determine kernel physical load addr\n"); -+ fclose(fp); -+ return -1; -+} -+ -+/* Hardcoding kernel virtual address and size. While writting -+ * this patch vanilla kernel is compiled for addr 2MB. Anybody -+ * using kernel older than that which was compiled for 1MB -+ * physical addr, use older version of kexec-tools. This function -+ * is there just for backward compatibility reasons and we should -+ * get rid of it at some point of time. -+ */ -+ -+static int hardcode_kernel_vaddr_size(struct kexec_info *info) -+{ -+ fprintf(stderr, "Warning: Hardcoding kernel virtual addr and size\n"); -+ info->kern_vaddr_start = __START_KERNEL_map + 0x200000; -+ info->kern_size = KERNEL_TEXT_SIZE - 0x200000; -+ fprintf(stderr, "Warning: virtual addr = 0x%lx size = 0x%lx\n", -+ info->kern_vaddr_start, info->kern_size); -+ return 0; -+} -+ -+/* Retrieve info regarding virtual address kernel has been compiled for and -+ * size of the kernel from /proc/kcore. Current /proc/kcore parsing from -+ * from kexec-tools fails because of malformed elf notes. A kernel patch has -+ * been submitted. For the folks using older kernels, this function -+ * hard codes the values to remain backward compatible. Once things stablize -+ * we should get rid of backward compatible code. */ -+ -+static int get_kernel_vaddr_and_size(struct kexec_info *info) -+{ -+ int result; -+ const char kcore[] = "/proc/kcore"; -+ char *buf; -+ struct mem_ehdr ehdr; -+ struct mem_phdr *phdr, *end_phdr; -+ int align; -+ unsigned long size; -+ uint32_t elf_flags = 0; -+ -+ align = getpagesize(); -+ size = KCORE_ELF_HEADERS_SIZE; -+ buf = slurp_file_len(kcore, size); -+ if (!buf) { -+ fprintf(stderr, "Cannot read %s: %s\n", kcore, strerror(errno)); -+ return -1; -+ } -+ -+ /* Don't perform checks to make sure stated phdrs and shdrs are -+ * actually present in the core file. It is not practical -+ * to read the GB size file into a user space buffer, Given the -+ * fact that we don't use any info from that. -+ */ -+ elf_flags |= ELF_SKIP_FILESZ_CHECK; -+ result = build_elf_core_info(buf, size, &ehdr, elf_flags); -+ if (result < 0) { -+ fprintf(stderr, "ELF core (kcore) parse failed\n"); -+ hardcode_kernel_vaddr_size(info); -+ return 0; -+ } -+ -+ /* Traverse through the Elf headers and find the region where -+ * kernel is mapped. */ -+ end_phdr = &ehdr.e_phdr[ehdr.e_phnum]; -+ for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) { -+ if (phdr->p_type == PT_LOAD) { -+ unsigned long saddr = phdr->p_vaddr; -+ unsigned long eaddr = phdr->p_vaddr + phdr->p_memsz; -+ unsigned long size; -+ -+ /* Look for kernel text mapping header. */ -+ if ((saddr >= __START_KERNEL_map) && -+ (eaddr <= __START_KERNEL_map + KERNEL_TEXT_SIZE)) { -+ saddr = (saddr) & (~(KERN_VADDR_ALIGN - 1)); -+ info->kern_vaddr_start = saddr; -+ size = eaddr - saddr; -+ /* Align size to page size boundary. */ -+ size = (size + align - 1) & (~(align - 1)); -+ info->kern_size = size; -+#ifdef DEBUG -+ printf("kernel vaddr = 0x%lx size = 0x%lx\n", -+ saddr, size); -+#endif -+ return 0; -+ } -+ } -+ } -+ fprintf(stderr, "Can't find kernel text map area from kcore\n"); -+ return -1; -+} -+ - /* Stores a sorted list of RAM memory ranges for which to create elf headers. - * A separate program header is created for backup region */ - static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES]; -@@ -245,7 +378,7 @@ static int add_memmap(struct memory_rang - memmap_p[j+1] = memmap_p[j]; - memmap_p[tidx].start = addr; - memmap_p[tidx].end = addr + size - 1; --#if 0 -+#ifdef DEBUG - printf("Memmap after adding segment\n"); - for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { - mstart = memmap_p[i].start; -@@ -330,7 +463,7 @@ static int delete_memmap(struct memory_r - memmap_p[j-1] = memmap_p[j]; - memmap_p[j-1].start = memmap_p[j-1].end = 0; - } --#if 0 -+#ifdef DEBUG - printf("Memmap after deleting segment\n"); - for (i = 0; i < CRASH_MAX_MEMMAP_NR; i++) { - mstart = memmap_p[i].start; -@@ -404,7 +537,7 @@ static int cmdline_add_memmap(char *cmdl - die("Command line overflow\n"); - strcat(cmdline, str_mmap); - } --#if 0 -+#ifdef DEBUG - printf("Command line after adding memmap\n"); - printf("%s\n", cmdline); - #endif -@@ -432,7 +565,7 @@ static int cmdline_add_elfcorehdr(char * - if (cmdlen > (COMMAND_LINE_SIZE - 1)) - die("Command line overflow\n"); - strcat(cmdline, str); --#if 0 -+#ifdef DEBUG - printf("Command line after adding elfcorehdr\n"); - printf("%s\n", cmdline); - #endif -@@ -465,7 +598,7 @@ static int cmdline_add_memmap_acpi(char - die("Command line overflow\n"); - strcat(cmdline, str_mmap); - --#if 0 -+#ifdef DEBUG - printf("Command line after adding acpi memmap\n"); - printf("%s\n", cmdline); - #endif -@@ -536,6 +669,27 @@ static int prepare_crash_memory_elf64_he - (elf->e_phnum)++; - } - -+ /* Setup an PT_LOAD type program header for the region where -+ * Kernel is mapped. -+ */ -+ phdr = (Elf64_Phdr *) bufp; -+ bufp += sizeof(Elf64_Phdr); -+ phdr->p_type = PT_LOAD; -+ phdr->p_flags = PF_R|PF_W|PF_X; -+ phdr->p_offset = phdr->p_paddr = info->kern_paddr_start; -+ phdr->p_vaddr = info->kern_vaddr_start; -+ phdr->p_filesz = phdr->p_memsz = info->kern_size; -+ phdr->p_align = 0; -+ (elf->e_phnum)++; -+#ifdef DEBUG -+ printf("Kernel text Elf header: p_type = %d, p_offset = 0x%lx " -+ "p_paddr = 0x%lx p_vaddr = 0x%lx " -+ "p_filesz = 0x%lx p_memsz = 0x%lx\n", -+ phdr->p_type, phdr->p_offset, phdr->p_paddr, -+ phdr->p_vaddr, phdr->p_filesz, phdr->p_memsz); -+#endif -+ -+ - /* Setup PT_LOAD type program header for every system RAM chunk. - * A seprate program header for Backup Region*/ - for (i = 0; i < CRASH_MAX_MEMORY_RANGES; i++) { -@@ -555,21 +709,13 @@ static int prepare_crash_memory_elf64_he - else - phdr->p_offset = mstart; - -- /* Handle linearly mapped region.*/ -+ /* We already prepared the header for kernel text. Map -+ * rest of the memory segments to kernel linearly mapped -+ * memory region. -+ */ - -- /* Filling the vaddr conditionally as we have two linearly -- * mapped regions here. One is __START_KERNEL_map 0 to 40 MB -- * other one is PAGE_OFFSET */ -- -- if ((mend <= (MAXMEM - 1)) && mstart < KERNEL_TEXT_SIZE) -- phdr->p_vaddr = mstart + __START_KERNEL_map; -- else { -- if (mend <= (MAXMEM - 1)) -- phdr->p_vaddr = mstart + PAGE_OFFSET; -- else -- phdr->p_vaddr = -1ULL; -- } - phdr->p_paddr = mstart; -+ phdr->p_vaddr = mstart + PAGE_OFFSET; - phdr->p_filesz = phdr->p_memsz = mend - mstart + 1; - /* Do we need any alignment of segments? */ - phdr->p_align = 0; -@@ -593,6 +739,12 @@ int load_crashdump_segments(struct kexec - long int nr_cpus = 0; - struct memory_range *mem_range, *memmap_p; - -+ if (get_kernel_paddr(info)) -+ return -1; -+ -+ if (get_kernel_vaddr_and_size(info)) -+ return -1; -+ - if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) - return -1; - -@@ -638,7 +790,7 @@ int load_crashdump_segments(struct kexec - * This is a makeshift solution until it is fixed in kernel. - */ - elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, -- max_addr, 1); -+ max_addr, -1); - if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) - return -1; - cmdline_add_memmap(mod_cmdline, memmap_p); ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-rel-x86_64.c.orig 2004-12-21 12:51:24.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-rel-x86_64.c 2007-01-05 13:32:24.000000000 -0500 -@@ -60,7 +60,7 @@ static const char *reloc_name(unsigned l - void machine_apply_elf_rel(struct mem_ehdr *ehdr, unsigned long r_type, - void *location, unsigned long address, unsigned long value) - { --#if 0 -+#ifdef DEBUG - fprintf(stderr, "%s\n", reloc_name(r_type)); - #endif - switch(r_type) { ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-elf-x86_64.c 2007-01-05 13:32:24.000000000 -0500 -@@ -47,7 +47,7 @@ int elf_x86_64_probe(const char *buf, of - - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - if (probe_debug) { - fprintf(stderr, "Not an ELF executable\n"); -@@ -177,7 +177,7 @@ int elf_x86_64_load(int argc, char **arg - } - - /* Load the ELF executable */ -- elf_exec_build_load(info, &ehdr, buf, len); -+ elf_exec_build_load(info, &ehdr, buf, len, 0); - - entry = ehdr.e_entry; - max_addr = elf_max_addr(&ehdr); -@@ -186,7 +186,7 @@ int elf_x86_64_load(int argc, char **arg - if (arg_style != ARG_STYLE_NONE) { - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0, ULONG_MAX, 1); -+ 0, ULONG_MAX, 1, 0); - } - if (arg_style == ARG_STYLE_NONE) { - info->entry = (void *)entry; ---- kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/x86_64/kexec-x86_64.c 2007-01-05 13:32:24.000000000 -0500 -@@ -64,7 +64,7 @@ int get_memory_ranges(struct memory_rang - continue; - str = line + consumed; - end = end + 1; --#if 0 -+#ifdef DEBUG - printf("%016Lx-%016Lx : %s", - start, end, str); - #endif -@@ -104,7 +104,7 @@ int get_memory_ranges(struct memory_rang - memory_range[memory_ranges].start = start; - memory_range[memory_ranges].end = end; - memory_range[memory_ranges].type = type; --#if 0 -+#ifdef DEBUG - printf("%016Lx-%016Lx : %x\n", - start, end, type); - #endif ---- kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-elf-x86.c 2007-01-05 13:32:24.000000000 -0500 -@@ -47,7 +47,7 @@ int elf_x86_probe(const char *buf, off_t - - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - if (probe_debug) { - fprintf(stderr, "Not an ELF executable\n"); -@@ -177,7 +177,7 @@ int elf_x86_load(int argc, char **argv, - } - - /* Load the ELF executable */ -- elf_exec_build_load(info, &ehdr, buf, len); -+ elf_exec_build_load(info, &ehdr, buf, len, 0); - - entry = ehdr.e_entry; - max_addr = elf_max_addr(&ehdr); -@@ -186,7 +186,7 @@ int elf_x86_load(int argc, char **argv, - if (arg_style != ARG_STYLE_NONE) { - /* Load the setup code */ - elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0, ULONG_MAX, 1); -+ 0, ULONG_MAX, 1, 0); - } - if (arg_style == ARG_STYLE_NONE) { - info->entry = (void *)entry; ---- kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-multiboot-x86.c 2007-01-05 13:32:24.000000000 -0500 -@@ -209,10 +209,11 @@ int multiboot_x86_load(int argc, char ** - - - /* Load the ELF executable */ -- elf_exec_build_load(info, &ehdr, buf, len); -+ elf_exec_build_load(info, &ehdr, buf, len, 0); - - /* Load the setup code */ -- elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, ULONG_MAX, 1); -+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, 0, -+ ULONG_MAX, 1, 0); - - /* The first segment will contain the multiboot headers: - * ============= ---- kexec-tools-1.101/kexec/arch/ppc/kexec-elf-ppc.c.orig 2005-01-20 14:10:56.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ppc/kexec-elf-ppc.c 2007-01-05 13:32:24.000000000 -0500 -@@ -72,7 +72,7 @@ int elf_ppc_probe(const char *buf, off_t - - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - goto out; - } -@@ -180,7 +180,7 @@ int elf_ppc_load(int argc, char **argv, - } - - /* Parse the Elf file */ -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - free_elf_info(&ehdr); - return result; ---- kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/ppc64/kexec-elf-ppc64.c 2007-01-05 13:32:24.000000000 -0500 -@@ -52,7 +52,7 @@ int elf_ppc64_probe(const char *buf, off - { - struct mem_ehdr ehdr; - int result; -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - goto out; - } -@@ -163,7 +163,7 @@ int elf_ppc64_load(int argc, char **argv - } - - /* Parse the Elf file */ -- result = build_elf_exec_info(buf, len, &ehdr); -+ result = build_elf_exec_info(buf, len, &ehdr, 0); - if (result < 0) { - free_elf_info(&ehdr); - return result; -@@ -213,7 +213,7 @@ int elf_ppc64_load(int argc, char **argv - memcpy(seg_buf, purgatory, purgatory_size); - seg_size = purgatory_size; - elf_rel_build_load(info, &info->rhdr, (const char *)purgatory, -- purgatory_size, 0, max_addr, 1); -+ purgatory_size, 0, max_addr, 1, 0); - - /* Add a ram-disk to the current image - * Note: Add the ramdisk after elf_rel_build_load ---- /dev/null 2006-12-27 08:05:56.458406418 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf-core.c 2007-01-05 13:32:24.000000000 -0500 -@@ -0,0 +1,29 @@ -+#include -+#include -+#include -+#include -+#include "elf.h" -+#include "kexec-elf.h" -+ -+ -+int build_elf_core_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) -+{ -+ int result; -+ result = build_elf_info(buf, len, ehdr, flags); -+ if (result < 0) { -+ return result; -+ } -+ if ((ehdr->e_type != ET_CORE)) { -+ /* not an ELF Core */ -+ fprintf(stderr, "Not ELF type ET_CORE\n"); -+ return -1; -+ } -+ if (!ehdr->e_phdr) { -+ /* No program header */ -+ fprintf(stderr, "No ELF program header\n"); -+ return -1; -+ } -+ -+ return 0; -+} ---- kexec-tools-1.101/kexec/kexec-elf.h.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf.h 2007-01-05 13:32:24.000000000 -0500 -@@ -82,22 +82,29 @@ typedef struct - uint32_t n_type; /* Type of the note. */ - } ElfNN_Nhdr; - -+/* Misc flags */ - -+#define ELF_SKIP_FILESZ_CHECK 0x00000001 - - extern void free_elf_info(struct mem_ehdr *ehdr); --extern int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr); --extern int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr); --extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr); -+extern int build_elf_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags); -+extern int build_elf_exec_info(const char *buf, off_t len, -+ struct mem_ehdr *ehdr, uint32_t flags); -+extern int build_elf_rel_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags); - -+extern int build_elf_core_info(const char *buf, off_t len, -+ struct mem_ehdr *ehdr, uint32_t flags); - extern int elf_exec_load(struct mem_ehdr *ehdr, struct kexec_info *info); - extern int elf_rel_load(struct mem_ehdr *ehdr, struct kexec_info *info, - unsigned long min, unsigned long max, int end); - - extern void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, -- const char *buf, off_t len); -+ const char *buf, off_t len, uint32_t flags); - extern void elf_rel_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, - const char *buf, off_t len, unsigned long min, unsigned long max, -- int end); -+ int end, uint32_t flags); - - extern int elf_rel_find_symbol(struct mem_ehdr *ehdr, - const char *name, struct mem_sym *ret_sym); ---- kexec-tools-1.101/kexec/kexec-elf-exec.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec-elf-exec.c 2007-01-05 13:32:24.000000000 -0500 -@@ -11,11 +11,12 @@ - - static const int probe_debug = 0; - --int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr) -+int build_elf_exec_info(const char *buf, off_t len, struct mem_ehdr *ehdr, -+ uint32_t flags) - { - struct mem_phdr *phdr, *end_phdr; - int result; -- result = build_elf_info(buf, len, ehdr); -+ result = build_elf_info(buf, len, ehdr, flags); - if (result < 0) { - return result; - } -@@ -136,11 +137,11 @@ int elf_exec_load(struct mem_ehdr *ehdr, - } - - void elf_exec_build_load(struct kexec_info *info, struct mem_ehdr *ehdr, -- const char *buf, off_t len) -+ const char *buf, off_t len, uint32_t flags) - { - int result; - /* Parse the Elf file */ -- result = build_elf_exec_info(buf, len, ehdr); -+ result = build_elf_exec_info(buf, len, ehdr, flags); - if (result < 0) { - die("ELF exec parse failed\n"); - } ---- kexec-tools-1.101/kexec/crashdump.h.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/crashdump.h 2007-01-05 13:32:24.000000000 -0500 -@@ -5,5 +5,7 @@ extern int get_crash_notes_per_cpu(int c - - /* Need to find a better way to determine per cpu notes section size. */ - #define MAX_NOTE_BYTES 1024 -+/* Expecting ELF headers to fit in 4K. Increase it if you need more. */ -+#define KCORE_ELF_HEADERS_SIZE 4096 - - #endif /* CRASHDUMP_H */ ---- kexec-tools-1.101/kexec/kexec.h.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec.h 2007-01-05 13:32:24.000000000 -0500 -@@ -116,6 +116,9 @@ struct kexec_info { - struct mem_ehdr rhdr; - unsigned long backup_start; - unsigned long kexec_flags; -+ unsigned long kern_vaddr_start; -+ unsigned long kern_paddr_start; -+ unsigned long kern_size; - }; - - void usage(void); -@@ -177,6 +180,7 @@ extern void die(char *fmt, ...); - extern void *xmalloc(size_t size); - extern void *xrealloc(void *ptr, size_t size); - extern char *slurp_file(const char *filename, off_t *r_size); -+extern char *slurp_file_len(const char *filename, off_t size); - extern char *slurp_decompress_file(const char *filename, off_t *r_size); - extern void add_segment(struct kexec_info *info, - const void *buf, size_t bufsz, unsigned long base, size_t memsz); ---- kexec-tools-1.101/kexec/kexec.c.orig 2007-01-05 13:32:05.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec.c 2007-01-05 13:32:24.000000000 -0500 -@@ -391,6 +391,50 @@ char *slurp_file(const char *filename, o - return buf; - } - -+/* This functions reads either specified number of bytes from the file or -+ lesser if EOF is met. */ -+ -+char *slurp_file_len(const char *filename, off_t size) -+{ -+ int fd; -+ char *buf; -+ off_t progress; -+ ssize_t result; -+ -+ if (!filename) -+ return 0; -+ fd = open(filename, O_RDONLY); -+ if (fd < 0) { -+ fprintf(stderr, "Cannot open %s: %s\n", filename, -+ strerror(errno)); -+ return 0; -+ } -+ buf = xmalloc(size); -+ progress = 0; -+ while(progress < size) { -+ result = read(fd, buf + progress, size - progress); -+ if (result < 0) { -+ if ((errno == EINTR) || (errno == EAGAIN)) -+ continue; -+ fprintf(stderr, "read on %s of %ld bytes failed: %s\n", -+ filename, (size - progress)+ 0UL, -+ strerror(errno)); -+ free(buf); -+ return 0; -+ } -+ if (result == 0) -+ /* EOF */ -+ break; -+ progress += result; -+ } -+ result = close(fd); -+ if (result < 0) { -+ die("Close of %s failed: %s\n", -+ filename, strerror(errno)); -+ } -+ return buf; -+} -+ - #if HAVE_ZLIB_H - char *slurp_decompress_file(const char *filename, off_t *r_size) - { diff --git a/kexec-tools-1.101-relocatable-bzimage.patch b/kexec-tools-1.101-relocatable-bzimage.patch deleted file mode 100644 index ea8410e..0000000 --- a/kexec-tools-1.101-relocatable-bzimage.patch +++ /dev/null @@ -1,252 +0,0 @@ ---- kexec-tools-1.101/include/x86/x86-linux.h.orig 2007-01-05 13:28:08.000000000 -0500 -+++ kexec-tools-1.101/include/x86/x86-linux.h 2007-01-05 13:24:49.000000000 -0500 -@@ -141,7 +141,10 @@ struct x86_linux_param_header { - uint32_t high_filesz; /* 0x254 */ - uint8_t reserved15[0x2d0 - 0x258]; /* 0x258 */ - #else -- uint8_t reserved15[0x2d0 - 0x230]; /* 0x230 */ -+ /* 2.04+ */ -+ uint32_t kernel_alignment; /* 0x230 */ -+ uint8_t relocatable_kernel; /* 0x234 */ -+ uint8_t reserved15[0x2d0 - 0x235]; /* 0x230 */ - #endif - struct e820entry e820_map[E820MAX]; /* 0x2d0 */ - /* 0x550 */ -@@ -201,12 +204,15 @@ struct x86_linux_header { - uint32_t high_filesz; /* 0x254 */ - uint32_t tail[32*1024 - 0x258]; /* 0x258 */ - #else -- uint8_t tail[32*1024 - 0x230]; /* 0x230 */ -+ uint32_t kernel_alignment; /* 0x230 */ -+ uint8_t relocatable_kernel; /* 0x234 */ -+ uint8_t tail[32*1024 - 0x235]; /* 0x230 */ - #endif - } PACKED; - - #endif /* ASSEMBLY */ - - #define DEFAULT_INITRD_ADDR_MAX 0x37FFFFFF -+#define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF - - #endif /* X86_LINUX_H */ ---- kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c.orig 2007-01-05 13:28:08.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c 2007-01-05 13:27:53.000000000 -0500 -@@ -680,7 +680,9 @@ int load_crashdump_segments(struct kexec - tmp = xmalloc(sz); - memset(tmp, 0, sz); - info->backup_start = add_buffer(info, tmp, sz, sz, align, -- 0, max_addr, 1); -+ 0, max_addr, -1); -+ dfprintf(stdout, "Created backup segment at 0x%lx\n", -+ info->backup_start); - if (delete_memmap(memmap_p, info->backup_start, sz) < 0) - return -1; - -@@ -719,7 +721,8 @@ int load_crashdump_segments(struct kexec - * This is a makeshift solution until it is fixed in kernel. - */ - elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, -- max_addr, 1); -+ max_addr, -1); -+ dfprintf(stdout, "Created elf header segment at 0x%lx\n", elfcorehdr); - if (delete_memmap(memmap_p, elfcorehdr, sz) < 0) - return -1; - cmdline_add_memmap(mod_cmdline, memmap_p); ---- kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c.orig 2007-01-05 13:28:08.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/x86-linux-setup.c 2007-01-05 13:24:49.000000000 -0500 -@@ -59,6 +59,7 @@ void setup_linux_bootloader_parameters( - initrd_addr_max = DEFAULT_INITRD_ADDR_MAX; - if (real_mode->protocol_version >= 0x0203) { - initrd_addr_max = real_mode->initrd_addr_max; -+ dfprintf(stdout, "initrd_addr_max is 0x%lx\n", initrd_addr_max); - } - - /* Load the initrd if we have one */ -@@ -66,6 +67,8 @@ void setup_linux_bootloader_parameters( - initrd_base = add_buffer(info, - initrd_buf, initrd_size, initrd_size, - 4096, INITRD_BASE, initrd_addr_max, -1); -+ dfprintf(stdout, "Loaded initrd at 0x%lx size 0x%lx\n", -+ initrd_base, initrd_size); - } else { - initrd_base = 0; - initrd_size = 0; ---- kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c.orig 2007-01-05 13:28:08.000000000 -0500 -+++ kexec-tools-1.101/kexec/arch/i386/kexec-bzImage.c 2007-01-05 13:27:53.000000000 -0500 -@@ -34,8 +34,10 @@ - #include - #include "../../kexec.h" - #include "../../kexec-elf.h" -+#include "../../kexec-syscall.h" - #include "kexec-x86.h" - #include "x86-linux-setup.h" -+#include "crashdump-x86.h" - #include - - static const int probe_debug = 0; -@@ -109,6 +111,9 @@ int do_bzImage_load(struct kexec_info *i - unsigned long setup_base, setup_size; - struct entry32_regs regs32; - struct entry16_regs regs16; -+ unsigned int relocatable_kernel = 0; -+ unsigned long kernel32_load_addr; -+ char *modified_cmdline; - - /* - * Find out about the file I am about to load. -@@ -121,6 +126,7 @@ int do_bzImage_load(struct kexec_info *i - if (setup_sects == 0) { - setup_sects = 4; - } -+ - kern16_size = (setup_sects +1) *512; - kernel_version = ((unsigned char *)&setup_header) + 512 + setup_header.kver_addr; - if (kernel_len < kern16_size) { -@@ -128,25 +134,88 @@ int do_bzImage_load(struct kexec_info *i - return -1; - } - -+ if (setup_header.protocol_version >= 0x0205) { -+ relocatable_kernel = setup_header.relocatable_kernel; -+ dfprintf(stdout, "bzImage is relocatable\n"); -+ } -+ -+ /* Can't use bzImage for crash dump purposes with real mode entry */ -+ if((info->kexec_flags & KEXEC_ON_CRASH) && real_mode_entry) { -+ fprintf(stderr, "Can't use bzImage for crash dump purposes" -+ " with real mode entry\n"); -+ return -1; -+ } -+ -+ if((info->kexec_flags & KEXEC_ON_CRASH) && !relocatable_kernel) { -+ fprintf(stderr, "BzImage is not relocatable. Can't be used" -+ " as capture kernel.\n"); -+ return -1; -+ } -+ -+ /* Need to append some command line parameters internally in case of -+ * taking crash dumps. -+ */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ modified_cmdline = xmalloc(COMMAND_LINE_SIZE); -+ memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE); -+ if (command_line) { -+ strncpy(modified_cmdline, command_line, -+ COMMAND_LINE_SIZE); -+ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0'; -+ } -+ -+ /* If panic kernel is being loaded, additional segments need -+ * to be created. load_crashdump_segments will take care of -+ * loading the segments as high in memory as possible, hence -+ * in turn as away as possible from kernel to avoid being -+ * stomped by the kernel. -+ */ -+ if (load_crashdump_segments(info, modified_cmdline, -1, 0) < 0) -+ return -1; -+ -+ /* Use new command line buffer */ -+ command_line = modified_cmdline; -+ command_line_len = strlen(command_line) +1; -+ } -+ - /* Load the trampoline. This must load at a higher address - * the the argument/parameter segment or the kernel will stomp - * it's gdt. - */ -- elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -- 0x3000, 640*1024, -1); -+ -+ if (!real_mode_entry && relocatable_kernel) -+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -+ 0x3000, -1, -1, 0); -+ else -+ elf_rel_build_load(info, &info->rhdr, purgatory, purgatory_size, -+ 0x3000, 640*1024, -1, 0); -+ dfprintf(stdout, "Loaded purgatory at addr 0x%lx\n", -+ info->rhdr.rel_addr); - - /* The argument/parameter segment */ - setup_size = kern16_size + command_line_len; - real_mode = xmalloc(setup_size); - memcpy(real_mode, kernel, kern16_size); -- if (real_mode->protocol_version >= 0x0200) { -+ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ /* If using bzImage for capture kernel, then we will not be -+ * executing real mode code. setup segment can be loaded -+ * anywhere as we will be just reading command line. -+ */ -+ setup_base = add_buffer(info, real_mode, setup_size, setup_size, -+ 16, 0x3000, -1, 1); -+ } -+ else if (real_mode->protocol_version >= 0x0200) { - /* Careful setup_base must be greater than 8K */ - setup_base = add_buffer(info, real_mode, setup_size, setup_size, -- 16, 0x3000, 640*1024, -1); -+ 16, 0x3000, 640*1024, 1); - } else { - add_segment(info, real_mode, setup_size, SETUP_BASE, setup_size); - setup_base = SETUP_BASE; - } -+ dfprintf(stdout, "Loaded real-mode code and command line at 0x%lx\n", -+ setup_base); -+ - /* Verify purgatory loads higher than the parameters */ - if (info->rhdr.rel_addr < setup_base) { - die("Could not put setup code above the kernel parameters\n"); -@@ -154,9 +223,30 @@ int do_bzImage_load(struct kexec_info *i - - /* The main kernel segment */ - size = kernel_len - kern16_size; -- add_segment(info, kernel + kern16_size, size, KERN32_BASE, size); - -+ if (real_mode->protocol_version >=0x0205 && relocatable_kernel) { -+ /* Relocatable bzImage */ -+ unsigned long kern_align = real_mode->kernel_alignment; -+ unsigned long kernel32_max_addr = DEFAULT_BZIMAGE_ADDR_MAX; -+ -+ if (real_mode->protocol_version >= 0x0203) { -+ if (kernel32_max_addr > real_mode->initrd_addr_max) -+ kernel32_max_addr = real_mode->initrd_addr_max; -+ } -+ -+ kernel32_load_addr = add_buffer(info, kernel + kern16_size, -+ size, size, kern_align, -+ 0x100000, kernel32_max_addr, -+ 1); -+ } -+ else { -+ kernel32_load_addr = KERN32_BASE; -+ add_segment(info, kernel + kern16_size, size, -+ kernel32_load_addr, size); -+ } - -+ dfprintf(stdout, "Loaded 32bit kernel at 0x%lx\n", kernel32_load_addr); -+ - /* Tell the kernel what is going on */ - setup_linux_bootloader_parameters(info, real_mode, setup_base, - kern16_size, command_line, command_line_len, -@@ -177,7 +267,7 @@ int do_bzImage_load(struct kexec_info *i - regs32.edi = 0; /* unused */ - regs32.esp = elf_rel_get_addr(&info->rhdr, "stack_end"); /* stack, unused */ - regs32.ebp = 0; /* unused */ -- regs32.eip = KERN32_BASE; /* kernel entry point */ -+ regs32.eip = kernel32_load_addr; /* kernel entry point */ - - /* - * Initialize the 16bit start information. ---- kexec-tools-1.101/kexec/kexec.h.orig 2007-01-05 13:28:08.000000000 -0500 -+++ kexec-tools-1.101/kexec/kexec.h 2007-01-05 13:24:43.000000000 -0500 -@@ -197,4 +197,11 @@ int arch_compat_trampoline(struct kexec_ - void arch_update_purgatory(struct kexec_info *info); - - #define MAX_LINE 160 -+ -+#ifdef DEBUG -+#define dfprintf(args...) do {fprintf(args);} while(0) -+#else -+#define dfprintf(args...) do { } while(0) -+#endif -+ - #endif /* KEXEC_H */ diff --git a/kexec-tools-1.101-s390-fixup.patch b/kexec-tools-1.101-s390-fixup.patch deleted file mode 100644 index ca4649c..0000000 --- a/kexec-tools-1.101-s390-fixup.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/s390/kexec-s390.c.orig 2006-07-05 16:01:46.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/s390/kexec-s390.c 2006-07-05 16:02:48.000000000 -0400 -@@ -36,7 +36,7 @@ static struct memory_range memory_range[ - * - (-1) if something went wrong. - */ - --int get_memory_ranges(struct memory_range **range, int *ranges) -+int get_memory_ranges(struct memory_range **range, int *ranges, unsigned long kexec_flags) - { - char sys_ram[] = "System RAM\n"; - char iomem[] = "/proc/iomem"; -@@ -94,7 +94,7 @@ int arch_process_options(int argc, char - return 0; - } - --int arch_compat_trampoline(struct kexec_info *info, unsigned long *flags) -+int arch_compat_trampoline(struct kexec_info *info) - { - return 0; - } diff --git a/kexec-tools-1.101-x86-add_buffer_retry.patch b/kexec-tools-1.101-x86-add_buffer_retry.patch deleted file mode 100644 index d4b6361..0000000 --- a/kexec-tools-1.101-x86-add_buffer_retry.patch +++ /dev/null @@ -1,60 +0,0 @@ ---- kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c.orig 2007-07-17 08:33:59.000000000 -0400 -+++ kexec-tools-1.101/kexec/arch/i386/crashdump-x86.c 2007-07-17 08:34:13.000000000 -0400 -@@ -663,6 +663,7 @@ int load_crashdump_segments(struct kexec - int nr_ranges, align = 1024; - long int nr_cpus = 0; - struct memory_range *mem_range, *memmap_p; -+ int i; - - if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0) - return -1; -@@ -720,8 +721,13 @@ int load_crashdump_segments(struct kexec - * elf core header segment to 16K to avoid being placed in such gaps. - * This is a makeshift solution until it is fixed in kernel. - */ -- elfcorehdr = add_buffer(info, tmp, sz, 16*1024, align, min_base, -- max_addr, -1); -+ for (i=0;inr_segments; i++) { -+ if ((base < (info->segment[i].mem + info->segment[i].memsz)) && -+ ((base+memsz) > info->segment[i].mem)) { -+ /* -+ *we have an overlap, bump down buf_max -+ */ -+ buf_max = (unsigned long)info->segment[i].mem; -+ goto retry; -+ } -+ } - - add_segment(info, buf, bufsz, base, memsz); - return base; diff --git a/kexec-tools-1.101-disable-kdump-x8664.patch b/kexec-tools-1.102pre-disable-kdump-x8664.patch similarity index 100% rename from kexec-tools-1.101-disable-kdump-x8664.patch rename to kexec-tools-1.102pre-disable-kdump-x8664.patch diff --git a/kexec-tools-1.102pre-ppc64-buffer-overflow.patch b/kexec-tools-1.102pre-ppc64-buffer-overflow.patch new file mode 100644 index 0000000..db04f39 --- /dev/null +++ b/kexec-tools-1.102pre-ppc64-buffer-overflow.patch @@ -0,0 +1,33 @@ +diff -up kexec-tools-testing-20070330/kexec/arch/ppc64/kexec-ppc64.c.orig kexec-tools-testing-20070330/kexec/arch/ppc64/kexec-ppc64.c +--- kexec-tools-testing-20070330/kexec/arch/ppc64/kexec-ppc64.c.orig 2008-02-20 10:08:36.000000000 -0500 ++++ kexec-tools-testing-20070330/kexec/arch/ppc64/kexec-ppc64.c 2008-02-20 10:10:32.000000000 -0500 +@@ -133,7 +133,7 @@ static int get_base_ranges() + int local_memory_ranges = 0; + char device_tree[256] = "/proc/device-tree/"; + char fname[256]; +- char buf[MAXBYTES-1]; ++ char buf[MAXBYTES]; + DIR *dir, *dmem; + FILE *file; + struct dirent *dentry, *mentry; +@@ -253,7 +253,7 @@ static int get_devtree_details(unsigned + unsigned int tce_size; + unsigned long long htab_base, htab_size; + unsigned long long kernel_end; +- char buf[MAXBYTES-1]; ++ char buf[MAXBYTES]; + char device_tree[256] = "/proc/device-tree/"; + char fname[256]; + DIR *dir, *cdir; +diff -up kexec-tools-testing-20070330/kexec/arch/ppc64/crashdump-ppc64.c.orig kexec-tools-testing-20070330/kexec/arch/ppc64/crashdump-ppc64.c +--- kexec-tools-testing-20070330/kexec/arch/ppc64/crashdump-ppc64.c.orig 2007-03-30 00:34:36.000000000 -0400 ++++ kexec-tools-testing-20070330/kexec/arch/ppc64/crashdump-ppc64.c 2008-02-20 10:09:23.000000000 -0500 +@@ -101,7 +101,7 @@ static int get_crash_memory_ranges(struc + int memory_ranges = 0; + char device_tree[256] = "/proc/device-tree/"; + char fname[256]; +- char buf[MAXBYTES-1]; ++ char buf[MAXBYTES]; + DIR *dir, *dmem; + FILE *file; + struct dirent *dentry, *mentry; diff --git a/kexec-tools-1.102pre-vmcoreinfo.patch b/kexec-tools-1.102pre-vmcoreinfo.patch new file mode 100644 index 0000000..28ac10f --- /dev/null +++ b/kexec-tools-1.102pre-vmcoreinfo.patch @@ -0,0 +1,94 @@ +diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump-elf.c kexec-tools/kexec/crashdump-elf.c +--- backup/kexec-tools-testing-20070330/kexec/crashdump-elf.c 2007-03-30 13:34:36.000000000 +0900 ++++ kexec-tools/kexec/crashdump-elf.c 2007-08-03 14:45:47.000000000 +0900 +@@ -36,6 +36,8 @@ + char *bufp; + long int nr_cpus = 0; + uint64_t notes_addr, notes_len; ++ uint64_t vmcoreinfo_addr, vmcoreinfo_len; ++ int has_vmcoreinfo = 0; + int (*get_note_info)(int cpu, uint64_t *addr, uint64_t *len); + + if (xen_present()) +@@ -47,7 +49,11 @@ + return -1; + } + +- sz = sizeof(EHDR) + nr_cpus * sizeof(PHDR) + ranges * sizeof(PHDR); ++ if (get_kernel_vmcoreinfo(&vmcoreinfo_addr, &vmcoreinfo_len) == 0) { ++ has_vmcoreinfo = 1; ++ } ++ ++ sz = sizeof(EHDR) + (nr_cpus + has_vmcoreinfo) * sizeof(PHDR) + ranges * sizeof(PHDR); + + /* + * Certain architectures such as x86_64 and ia64 require a separate +@@ -148,6 +154,21 @@ + dfprintf_phdr(stdout, "Elf header", phdr); + } + ++ if (has_vmcoreinfo) { ++ phdr = (PHDR *) bufp; ++ bufp += sizeof(PHDR); ++ phdr->p_type = PT_NOTE; ++ phdr->p_flags = 0; ++ phdr->p_offset = phdr->p_paddr = vmcoreinfo_addr; ++ phdr->p_vaddr = 0; ++ phdr->p_filesz = phdr->p_memsz = vmcoreinfo_len; ++ /* Do we need any alignment of segments? */ ++ phdr->p_align = 0; ++ ++ (elf->e_phnum)++; ++ dfprintf_phdr(stdout, "vmcoreinfo header", phdr); ++ } ++ + /* Setup an PT_LOAD type program header for the region where + * Kernel is mapped if info->kern_size is non-zero. + */ +--- backup/kexec-tools-testing-20070330/kexec/crashdump.c 2007-03-30 13:34:36.000000000 +0900 ++++ kexec-tools/kexec/crashdump.c 2007-08-03 14:45:05.000000000 +0900 +@@ -108,3 +108,32 @@ + + return 0; + } ++ ++/* Returns the physical address of start of crash notes buffer for a kernel. */ ++int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len) ++{ ++ char kdump_info[PATH_MAX]; ++ char line[MAX_LINE]; ++ int count; ++ FILE *fp; ++ unsigned long long temp, temp2; ++ ++ *addr = 0; ++ *len = 0; ++ ++ sprintf(kdump_info, "/sys/kernel/vmcoreinfo"); ++ fp = fopen(kdump_info, "r"); ++ if (!fp) ++ return -1; ++ ++ if (!fgets(line, sizeof(line), fp)) ++ die("Cannot parse %s: %s\n", kdump_info, strerror(errno)); ++ count = sscanf(line, "%Lx %Lx", &temp, &temp2); ++ if (count != 2) ++ die("Cannot parse %s: %s\n", kdump_info, strerror(errno)); ++ ++ *addr = (uint64_t) temp; ++ *len = (uint64_t) temp2; ++ ++ return 0; ++} +diff -rpuN backup/kexec-tools-testing-20070330/kexec/crashdump.h kexec-tools/kexec/crashdump.h +--- backup/kexec-tools-testing-20070330/kexec/crashdump.h 2007-03-30 13:34:36.000000000 +0900 ++++ kexec-tools/kexec/crashdump.h 2007-08-03 14:45:05.000000000 +0900 +@@ -2,6 +2,7 @@ + #define CRASHDUMP_H + + extern int get_crash_notes_per_cpu(int cpu, uint64_t *addr, uint64_t *len); ++extern int get_kernel_vmcoreinfo(uint64_t *addr, uint64_t *len); + + /* Need to find a better way to determine per cpu notes section size. */ + #define MAX_NOTE_BYTES 1024 +_ diff --git a/kexec-tools-1.101-x86_64-exactmap.patch b/kexec-tools-1.102pre-x86_64-exactmap.patch similarity index 100% rename from kexec-tools-1.101-x86_64-exactmap.patch rename to kexec-tools-1.102pre-x86_64-exactmap.patch diff --git a/kexec-tools.spec b/kexec-tools.spec index 537900d..e81f4a3 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 1.102pre -Release: 5%{?dist} +Release: 6%{?dist} License: GPL Group: Applications/System Summary: The kexec/kdump userspace component. @@ -36,8 +36,8 @@ Patch2: kexec-tools-1.102pre-bzimage-options.patch # # Patches 101 through 200 are meant for x86_64 kexec-tools enablement # -Patch101: kexec-tools-1.101-disable-kdump-x8664.patch -Patch102: kexec-tools-1.101-x86_64-exactmap.patch +Patch101: kexec-tools-1.102pre-disable-kdump-x8664.patch +Patch102: kexec-tools-1.102pre-x86_64-exactmap.patch # # Patches 201 through 300 are meant for ia64 kexec-tools enablement @@ -47,6 +47,7 @@ Patch102: kexec-tools-1.101-x86_64-exactmap.patch # Patches 301 through 400 are meant for ppc64 kexec-tools enablement # Patch301: kexec-tools-1.102pre-ppc64_rmo_top.patch +Patch302: kexec-tools-1.102pre-ppc64-buffer-overflow.patch # # Patches 401 through 500 are meant for s390 kexec-tools enablement @@ -64,7 +65,8 @@ Patch601: kexec-tools-1.102pre-elf-format.patch Patch602: kexec-tools-1.102pre-x86-add_buffer_retry.patch Patch603: kexec-tools-1.102pre-makedumpfile-xen-syms.patch Patch604: kexec-tools-1.102pre-disable-kexec-test.patch -Patch605: kexec-tools-1.102pre-makedumpfile-makefile.patch +Patch605: kexec-tools-1.102pre-vmcoreinfo.patch +Patch606: kexec-tools-1.102pre-makedumpfile-makefile.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -92,6 +94,7 @@ tar -z -x -v -f %{SOURCE9} %patch603 -p1 %patch604 -p1 %patch605 -p1 +%patch606 -p1 tar -z -x -v -f %{SOURCE13} @@ -220,6 +223,10 @@ done %doc kexec-kdump-howto.txt %changelog +* Fri Feb 22 2008 Neil Horman - 1.102pre-6 +- Bringing rawhide up to date with bugfixes from RHEL5 +- Adding patch to prevent kexec buffer overflow on ppc (bz 428684) + * Tue Feb 19 2008 Neil Horman - 1.102pre-5 - Modifying mkdumprd to include dynamic executibles (bz 433350) diff --git a/mkdumprd b/mkdumprd index 4fe4495..8f03a20 100644 --- a/mkdumprd +++ b/mkdumprd @@ -25,6 +25,7 @@ # Guillaume Cottenceau # Peter Jones # Neil Horman +# Jarod Wilson cmdname=`basename $0` umask 0022 @@ -68,6 +69,9 @@ vg_list="" net_list="" USING_METHOD="" SAVE_PATH=/var/crash +bin="" +KDUMP_POST="" +extra_kdump_mods="" vecho() { @@ -97,9 +101,7 @@ usage () { fi $cmd "usage: $cmdname [--version] [--help] [-v] [-d] [-f] [--preload ]" - $cmd " [--force-ide-probe] [--force-scsi-probe | --omit-scsi-modules]" - $cmd " [--image-version] [--force-scsi-probe | --omit-raid-modules]" - $cmd " [--with=] [--force-lvm-probe | --omit-lvm-modules]" + $cmd " [--image-version] [--with-module]" $cmd " [--builtin=] [--omit-dmraid]" $cmd " [--fstab=] [--nocompress] " $cmd "" @@ -191,18 +193,26 @@ findmodule() { done fi - for modExt in o.gz o ko ; do - for modDir in /lib/modules/$kernel/updates /lib/modules/$kernel ; do - if [ -d $modDir ]; then - fmPath=$(findone $modDir -name $modName.$modExt) - if [ -f "$fmPath" ]; then - break 2 - fi - fi - done - done + fmPath=$(modprobe --set-version $kernel -l $modName 2>/dev/null) - if [ ! -f $fmPath ]; then + if [ ! -f "$fmPath" ]; then + for modExt in o.gz o ko + do + for modDir in /lib/modules/$kernel/updates /lib/modules/$kernel + do + if [ -d $modDir ] + then + fmPath=$(findone $modDir -name $modName.$modExt) + if [ -f "$fmPath" ] + then + break 2 + fi + fi + done + done + fi + + if [ ! -f "$fmPath" ]; then if [ -n "$skiperrors" ]; then return fi @@ -275,12 +285,13 @@ findstoragedriver () { continue ;; *) handleddevices="$handleddevices $device" ;; esac - if [[ "$device" =~ "md[0-9]+" ]]; then + if [[ "$device" == "md[0-9]+" ]]; then vecho "Found RAID component $device" handleraid "$device" continue fi vecho "Looking for driver for device $device" + device=`echo $device | sed 's/\//\!/g'` sysfs=$(findone -type d /sys/block -name $device) [ -z "$sysfs" ] && return pushd $sysfs >/dev/null 2>&1 @@ -716,7 +727,7 @@ if [ "x$PROBE" == "xyes" ]; then if [ "$rootfs" == "nfs" ]; then remote=$(echo $rootdev | cut -d : -f 1) # FIXME: this doesn't handle ips properly - remoteip=$(host $remote | cut -d ' ' -f 4) + remoteip=$(getent hosts $remote | cut -d ' ' -f 1) netdev=`/sbin/ip route get to $remoteip |sed 's|.*dev \(.*\).*|\1|g' |awk {'print $1;'} |head -n 1` net_list="$net_list $netdev" # check if it's root by label @@ -777,7 +788,7 @@ if [ -n "$testdm" ]; then done fi fi - + for n in $basicmodules; do findmodule $n done @@ -840,104 +851,6 @@ if [ -z "$MNTIMAGE" -o -z "$IMAGE" ]; then error "Error creating temporaries. Try again" exit 1 fi -if [ -n "$KDUMP_CONFIG_FILE" ]; then - while read type location; do - - case "$type" in - net) - #grab remote host and xlate into numbers - rhost=`echo $location | sed 's/.*@//' | cut -d':' -f1` - USE_SSH=`echo $location | grep @` - if [ -n "$USE_SSH" ]; then - USING_METHOD="ssh" - else - USING_METHOD="nfs" - fi - need_dns=`echo $rhost|grep [a-zA-Z]` - [ -n "$need_dns" ] && rhost=`host $rhost|cut -d' ' -f4` - - #find ethernet device used to route to remote host, ie eth0 - netdev=`/sbin/ip route get to $rhost 2>&1` - [ $? != 0 ] && echo "Bad kdump location: $location" && exit 1 - #the field in the ip output changes if we go to another subnet - OFF_SUBNET=`echo $netdev | grep via` - if [ -n "$OFF_SUBNET" ] - then - # we are going to a different subnet - netdev=`echo $netdev|awk '{print $5;}'|head -n 1` - else - # we are on the same subnet - netdev=`echo $netdev|awk '{print $3}'|head -n 1` - fi - - #add the ethernet device to the list of modules - mkdir -p $MNTIMAGE/etc/network/ - handlenetdev $netdev - echo $netdev >> $MNTIMAGE/etc/iface_to_activate - - #load nfs modules, if needed - echo $location | grep -v "@" > /dev/null && findmodule nfs - ;; - raw) - USING_METHOD="raw" - if (echo $location | egrep -q "^(LABEL|UUID)="); then - location=$(findfs $location) - fi - handlelvordev $location - ;; - core_collector) - if [ -x /sbin/makedumpfile ]; then - CORE_COLLECTOR=$location - CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/makedumpfile/makedumpfile -i \/etc\/makedumpfile.config --message-level 1/'` - else - echo "Cannot use the core_collector option on this arch" - rm -rf $MNTIMAGE - rm -rf $IMAGE - exit 1 - fi - ;; - path) - SAVE_PATH=$location - ;; - link_delay) - LINK_DELAY=$location - ;; - default) - DEFAULT_ACTION=$location - ;; - *) - IS_COMMENT=`echo $type | grep ^#.*$` - if [ -n "$IS_COMMENT" -o -z "$location" ] - then - #don't process comments or blank line - continue - fi - USING_METHOD="filesystem" - if (echo $location | egrep -q "^(LABEL|UUID)="); then - location=$(findfs $location) - fi - handlelvordev $location - ;; - esac - - done < $KDUMP_CONFIG_FILE -fi - -if [ -n "$CORE_COLLECTOR" ]; then - if [ "$USING_METHOD" == "ssh" ] || [ "$USING_METHOD" == "raw" ]; then - echo "You may only use alternate core collectors with the NFS and Local Filesystem targets" - rm -rf $MNTIMAGE - rm -rf $IMAGE - exit 1 - fi - - if [ -z "$USING_METHOD" ] - then - echo "Warning! Lack of dump target specification means core_collector option is ignored!" - CORE_COLLECTOR="" - fi - -fi #START BUILDING INITRD HERE @@ -960,26 +873,199 @@ mkdir -p $MNTIMAGE/etc/network/if-down.d mkdir -p $MNTIMAGE/etc/network/if-post-down.d ln -s bin $MNTIMAGE/sbin +if [ -n "$KDUMP_CONFIG_FILE" ]; then + while read config_opt config_val; do + + case "$config_opt" in + net) + #grab remote host and xlate into numbers + rhost=`echo $config_val | sed 's/.*@//' | cut -d':' -f1` + USE_SSH=`echo $config_val | grep @` + if [ -n "$USE_SSH" ]; then + USING_METHOD="ssh" + else + USING_METHOD="nfs" + fi + need_dns=`echo $rhost|grep [a-zA-Z]` + [ -n "$need_dns" ] && rhost=`getent hosts $rhost|cut -d' ' -f1` + + #find ethernet device used to route to remote host, ie eth0 + netdev=`/sbin/ip route get to $rhost 2>&1` + [ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1 + #the field in the ip output changes if we go to another subnet + OFF_SUBNET=`echo $netdev | grep via` + if [ -n "$OFF_SUBNET" ] + then + # we are going to a different subnet + netdev=`echo $netdev|awk '{print $5;}'|head -n 1` + else + # we are on the same subnet + netdev=`echo $netdev|awk '{print $3}'|head -n 1` + fi + + #add the ethernet device to the list of modules + mkdir -p $MNTIMAGE/etc/network/ + handlenetdev $netdev + echo $netdev >> $MNTIMAGE/etc/iface_to_activate + + #load nfs modules, if needed + echo $config_val | grep -v "@" > /dev/null && findmodule nfs + ;; + raw) + USING_METHOD="raw" + if (echo $config_val | egrep -q "^(LABEL|UUID)="); then + config_val=$(findfs $config_val) + fi + handlelvordev $config_val + ;; + core_collector) + if [ -x /sbin/makedumpfile ]; then + CORE_COLLECTOR=$config_val + grep -q control_d /proc/xen/capabilities 2>/dev/null + if [ $? -eq 0 ] + then + if [ -e /sys/kernel/vmcoreinfo ] + then + CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/makedumpfile/makedumpfile --message-level 1/'` + else + CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/makedumpfile/makedumpfile --xen-vmcoreinfo \/etc\/makedumpfile.config --message-level 1/'` + fi + else + if [ -e /sys/kernel/vmcoreinfo ] + then + CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/makedumpfile/makedumpfile --message-level 1/'` + else + CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/makedumpfile/makedumpfile -i \/etc\/makedumpfile.config --message-level 1/'` + fi + fi + else + echo "Cannot use the core_collector option on this arch" + rm -rf $MNTIMAGE + rm -rf $IMAGE + exit 1 + fi + ;; + path) + SAVE_PATH=$config_val + ;; + link_delay) + LINK_DELAY=$config_val + ;; + kdump_post) + KDUMP_POST=$config_val + if [ ! -x "$KDUMP_POST" ]; then + echo "$KDUMP_POST not executable or not found" + exit 1 + fi + bin="$bin $KDUMP_POST" + KDUMP_POST_INTERNAL=`echo $KDUMP_POST | sed -e's/\(^.*\/\)\(.*$\)/\/bin\/\2/'` + ;; + kdump_pre) + KDUMP_PRE=$config_val + if [ ! -x "$KDUMP_PRE" ]; then + echo "$KDUMP_PRE not executable or not found" + exit 1 + fi + bin="$bin $KDUMP_PRE" + KDUMP_PRE_INTERNAL=`echo $KDUMP_PRE | sed -e's/\(^.*\/\)\(.*$\)/\/bin\/\2/'` + ;; + extra_bins) + bin="$bin $config_val" + ;; + extra_modules) + extra_kdump_mods="$extra_kdump_mods $config_val" + ;; + default) + DEFAULT_ACTION=$config_val + case $DEFAULT_ACTION in + reboot|shell) + FINAL_ACTION="reboot -f" + ;; + halt) + FINAL_ACTION="halt -f" + ;; + esac + ;; + *) + IS_COMMENT=`echo $config_opt | grep ^#.*$` + if [ -n "$IS_COMMENT" -o -z "$config_val" ] + then + #don't process comments or blank line + continue + fi + USING_METHOD="filesystem" + if (echo $config_val | egrep -q "^(LABEL|UUID)="); then + config_val=$(findfs $config_val) + fi + handlelvordev $config_val + ;; + esac + + done < $KDUMP_CONFIG_FILE +fi + #if we are using makedumpfile here, then generate the config file -if [ -n "$CORE_COLLECTOR" ]; then - RUN_KERN_VER=`uname -r` - if [ ! -f /usr/lib/debug/lib/modules/$RUN_KERN_VER/vmlinux ] +#also only build this config if we don't have vmcoreinfo on this kernel +if [ -n "$CORE_COLLECTOR" -a ! -e /sys/kernel/vmcoreinfo ]; then + if [ -z "$USING_METHOD" ] then - echo "kernel-debuginfo-$RUN_KERN_VER is not installed. You need this to use makedumpfile!" - echo "please install it and restart the kdump service" - rm -rf $MNTIMAGE - rm -rf $IMAGE - exit 1 - fi - /sbin/makedumpfile -g $MNTIMAGE/etc/makedumpfile.config -x -/usr/lib/debug/lib/modules/$RUN_KERN_VER/vmlinux > /dev/null 2>&1 - if [ $? != 0 ]; then - echo "could not generate makedumpfile configuration. aborting" - rm -rf $MNTIMAGE - rm -rf $IMAGE - exit 1; + echo "Warning! Lack of dump target specification means core_collector option is ignored!" + CORE_COLLECTOR="" + else + RUN_KERN_VER=`uname -r` + if [ ! -f /usr/lib/debug/lib/modules/$RUN_KERN_VER/vmlinux ] + then + echo "kernel-debuginfo-$RUN_KERN_VER is not installed. You need this to use makedumpfile!" + echo "please install it and restart the kdump service" + rm -rf $MNTIMAGE + rm -rf $IMAGE + exit 1 + fi + XEN_OPTS="" + grep -q control_d /proc/xen/capabilities 2>/dev/null + if [ $? -eq 0 ] + then + # This is a dom0 xen kernel so we need to add xen-syms to the + # makedumpefile config + RUN_XEN_VER=${RUN_KERN_VER%xen} + if [ ! -f /usr/lib/debug/boot/xen-syms-$RUN_XEN_VER.debug ] + then + echo "xen-syms.debug not found and is needed on this kernel to use makedumpfile!" + echo "please install it and restart the kdump service" + rm -rf $MNTIMAGE + rm -rf $IMAGE + exit 1 + fi + + XEN_OPTS="--xen-syms /usr/lib/debug/boot/xen-syms-$RUN_XEN_VER.debug" + /sbin/makedumpfile -g $MNTIMAGE/etc/makedumpfile.config $XEN_OPTS > /dev/null 2>&1 + else + /sbin/makedumpfile -g $MNTIMAGE/etc/makedumpfile.config -x /usr/lib/debug/lib/modules/$RUN_KERN_VER/vmlinux > /dev/null 2>&1 + fi + if [ $? != 0 ]; then + echo "could not generate makedumpfile configuration. aborting" + rm -rf $MNTIMAGE + rm -rf $IMAGE + exit 1; + fi fi fi + +#include extra user-specified modules for kdump initrd +for n in $extra_kdump_mods; do + findmodule $n +done + +if [ -z "$FINAL_ACTION" ]; then + FINAL_ACTION="reboot -f" +else + if [ -z "$USING_METHOD" ]; then + echo "Warning! Lack of dump target specification means default option is ignored!" + DEFAULT_ACTION="" + FINAL_ACTION="reboot -f" + fi +fi + #copy in busybox and make symlinks to its supported utilities cp /sbin/busybox $MNTIMAGE/sbin/busybox cd $MNTIMAGE/sbin @@ -991,6 +1077,16 @@ do done cd - > /dev/null 2>&1 +if [ -f /etc/mdadm.conf ] +then + cp /etc/mdadm.conf $MNTIMAGE/etc + bin="$bin /sbin/mdadm" + for i in `cat /etc/mdadm.conf | grep ARRAY | sed -e's/\(^.*level=\)\(.*$\)/\2/' | cut -d" " -f1` + do + findmodule $i + done +fi + #THIS IS WHERE WE GENERATE OUR ADDITINONAL UTILITIES #Busybox doesn't have a /bin/sh applet, #so we build a reasonable faximilie here @@ -1356,10 +1452,19 @@ done # this will make sure that we have all of our devices before trying # things like RAID or LVM emit "echo Creating Block Devices" +emit "mkdir /dev/cciss" +emit "mkdir /dev/ida" emit "for i in \`ls /sys/block\`; do" emit " MAJOR_NUM=\`cat /sys/block/\$i/dev | cut -d":" -f1\`" emit " MINOR_NUM=\`cat /sys/block/\$i/dev | cut -d":" -f2\`" emit " MINOR_RANGE=\`cat /sys/block/\$i/range | cut -d":" -f2\`" +emit " PART_SEP=''" +emit " i=\`echo \$i | sed 's/\!/\//g'\`" +emit " if echo \$i | grep -q '^cciss'; then" +emit " PART_SEP='p'" +emit " elif echo \$i | grep -q '^ida'; then" +emit " PART_SEP='p'" +emit " fi" emit " echo Creating block device \$i" emit " mknod /dev/\$i b \$MAJOR_NUM \$MINOR_NUM" emit " if [ \"\$MINOR_RANGE\" -gt 1 ]" @@ -1371,12 +1476,21 @@ emit " for j in \`seq \$MINOR_START 1 \$MINOR_END\`" emit " do" emit " if [ ! -e /dev/\$i\$PART_NUM ]" emit " then" -emit " mknod /dev/\$i\$PART_NUM b \$MAJOR_NUM \$j" +emit " mknod /dev/\$i\$PART_SEP\$PART_NUM b \$MAJOR_NUM \$j" emit " fi" emit " PART_NUM=\`expr \$PART_NUM + 1\`" emit " done" emit " fi" emit "done" +#now do any software raid devices we might have +emit "if [ -f /etc/mdadm.conf ]" +emit "then" +emit " for i in \`awk '/.*ARRAY.*/{print \$2}' /etc/mdadm.conf\`" +emit " do" +emit " MD_MIN=\`echo \$i | sed -e's/\(^.*\)\([0-9]\+$\)/\2/'\`" +emit " mknod \$i b 9 \$MD_MIN" +emit " done" +emit "fi" if [ -n "$vg_list" ]; then emit "echo Making device-mapper control node" @@ -1402,6 +1516,11 @@ if [ -n "$raiddevices" ]; then done fi +emit "if [ -f /etc/mdadm.conf ]" +emit "then" +emit " mdadm -A -s" +emit "fi" + if [ -n "$vg_list" ]; then emit "echo Scanning logical volumes" emit "lvm vgscan --ignorelockingfailure --mknodes" @@ -1431,6 +1550,7 @@ kdump_chk() echo "$KDUMP_CONFIG_FILE: $2" exit 1 } + if [ -n "$KDUMP_CONFIG_FILE" ]; then memtotal=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'` @@ -1459,32 +1579,52 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then k_extras="/$lib/libnss_compat.so.2 /$lib/libnss_files.so.2" #traverse the config file and setup each dump location - while read type location; do - [ -z "$type" ] && continue #skip empty lines - [ "`echo $type| grep ^# `" ] && continue #skip comments - kdump_chk "test -n \"$location\"" "Need a location for $type" + while read config_opt config_val; do + [ -z "$config_opt" ] && continue #skip empty lines + [ "`echo $config_opt | grep ^# `" ] && continue #skip comments + kdump_chk "test -n \"$config_val\"" "Need a location for $config_opt" - case "$type" in + case "$config_opt" in \#*) continue;; #skip comments raw) #test raw partition - kdump_chk "dd if=$location count=1 of=/dev/null > /dev/null 2>&1" \ - "Bad raw partition $location" + kdump_chk "dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1" \ + "Bad raw partition $config_val" #check for available size is greater than $memtotal - available_size=$(fdisk -s $location) + available_size=$(fdisk -s $config_val) if [ $available_size -lt $memtotal ]; then echo "Warning: There is not space enough to save a vmcore." echo " The size of $config_val should be much greater than $memtotal kilo bytes." fi #setup raw case - emit "echo Saving to partition $location" - emit "dd if=/proc/vmcore of=$location" - emit "if [ \$? == 0 ]" + if [ -n "$KDUMP_PRE_INTERNAL" ] + then + emit "$KDUMP_PRE_INTERNAL" + emit "if [ $? -ne 0 ]" + emit "then" + emit " echo kdump_pre script exited with non-zero status" + emit " $FINAL_ACTION" + emit "fi" + fi + emit "echo Saving to partition $config_val" + if [ -z "$CORE_COLLECTOR" ] + then + emit "dd if=/proc/vmcore of=$config_val" + else + CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/\(^makedumpfile\)\(.*$\)/\1 -F \2/'` + emit "$CORE_COLLECTOR /proc/vmcore | dd of=$config_val" + fi + emit "exitcode=\$?" + emit "if [ \$exitcode == 0 ]" emit "then" - emit " reboot -f" + emit " echo \"Saving core complete\"" emit "fi" + if [ -x "$KDUMP_POST" ]; then + emit "$KDUMP_POST \$exitcode" + fi + emit "[ \$exitcode == 0 ] && $FINAL_ACTION" ;; net) @@ -1509,20 +1649,17 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then then emit " echo \"Dropping to shell. exit to reboot\"" emit " /bin/msh" - emit " reboot -f" - elif [ "$DEFAULT_ACTION" == "reboot" ] - then - emit " reboot -f" - fi + fi + emit " $FINAL_ACTION" emit "fi" #grab remote host and xlate into numbers - rhost=`echo $location | sed 's/.*@//' | cut -d':' -f1` + rhost=`echo $config_val | sed 's/.*@//' | cut -d':' -f1` need_dns=`echo $rhost|grep [a-zA-Z]` - [ -n "$need_dns" ] && rhost=`host $rhost|cut -d' ' -f4` + [ -n "$need_dns" ] && rhost=`getent hosts $rhost|cut -d' ' -f1` #find the local ip being used as a route to remote ip netdev=`/sbin/ip route get to $rhost 2>&1` - [ $? != 0 ] && echo "Bad kdump location: $location" && exit 1 + [ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1 OFF_SUBNET=`echo $netdev | grep via` if [ -n "$OFF_SUBNET" ] then @@ -1533,14 +1670,14 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then lhost=`echo $netdev|awk '{print $5}'|head -n 1` fi - emit "echo Saving to remote location $location" - if [ -z "`echo $location|grep @`" ]; then + emit "echo Saving to remote location $config_val" + if [ -z "`echo $config_val|grep @`" ]; then #NFS path #test nfs mount and directory creation - rlocation=`echo $location| sed 's/.*:/'"$rhost"':/'` + rlocation=`echo $config_val| sed 's/.*:/'"$rhost"':/'` tmnt=`mktemp -dq` kdump_chk "mount -t nfs -o nolock $rlocation $tmnt" \ - "Bad NFS mount $location" + "Bad NFS mount $config_val" mkdir -p $tmnt/$SAVE_PATH tdir=`mktemp -dqp $tmnt/$SAVE_PATH` available_size=$(df -P $tdir | tail -1 | tr -s ' ' ':' | cut -d: -f5) @@ -1553,7 +1690,7 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then fi rm -rf $tmnt if [ $rc != "0" ]; then - echo "Cannot create directory in $location: $SAVE_PATH" + echo "Cannot create directory in $config_val: $SAVE_PATH" exit 1 fi @@ -1564,40 +1701,62 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then #check for available size is greater than $memtotal if [ $available_size -lt $memtotal ]; then echo "Warning: There is not space enough to save a vmcore." - echo " The size of $location should be much greater than $memtotal kilo bytes." + echo " The size of $config_val should be much greater than $memtotal kilo bytes." fi #setup nfs case + if [ -n "$KDUMP_PRE_INTERNAL" ] + then + emit "$KDUMP_PRE_INTERNAL" + emit "if [ $? -ne 0 ]" + emit "then" + emit " echo kdump_pre script exited with non-zero status" + emit " $FINAL_ACTION" + emit "fi" + fi + mkdir -p $MNTIMAGE/mnt emit "mount -t nfs -o nolock $rlocation /mnt" emit "if [ \$? == 0 ]" emit "then" emit " mkdir -p /mnt/$SAVE_PATH/$lhost-\$DATE" - emit " $CORE_COLLECTOR /proc/vmcore /mnt/$SAVE_PATH/$lhost-\$DATE/vmcore-incomplete" - emit " if [ \$? == 0 ]" + emit " VMCORE=/mnt/$SAVE_PATH/$lhost-\$DATE/vmcore" + emit " export VMCORE" + emit " $CORE_COLLECTOR /proc/vmcore \$VMCORE-incomplete >/dev/null" + emit " exitcode=\$?" + emit " if [ \$exitcode == 0 ]" emit " then" - emit " mv /mnt/$SAVE_PATH/$lhost-\$DATE/vmcore-incomplete /mnt/$SAVE_PATH/$lhost-\$DATE/vmcore" - emit " umount /mnt" - emit " reboot -f" + emit " mv \$VMCORE-incomplete \$VMCORE" + emit " echo \"Saving core complete\"" emit " fi" + if [ -x "$KDUMP_POST" ]; then + emit " $KDUMP_POST \$exitcode" + fi emit " umount /mnt" + emit " [ \$exitcode == 0 ] && $FINAL_ACTION" emit "fi" else #SSH path - #rebuild $location replacing machine name with ip address + #rebuild $config_val replacing machine name with ip address + if [ -n "$CORE_COLLECTOR" ] + then + CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e's/\(^makedumpfile\)\(.*$\)/\1 -F \2/'` + fi + bin="$bin /usr/bin/ssh /usr/bin/scp" - rlocation=`echo $location|sed 's/@.*/@'"$rhost"'/'` + rlocation=`echo $config_val|sed 's/@.*/@'"$rhost"'/'` #test ssh path and directory creation s_opts="-o BatchMode=yes -o StrictHostKeyChecking=no" kdump_chk "ssh -q $s_opts $rlocation mkdir -p $SAVE_PATH $SAVE_PATH/$lhost-\$DATE/vmcore-incomplete\"" + fi + emit "exitcode=\$?" + emit "if [ \$exitcode == 0 ]" emit "then" - emit " ssh -q -o BatchMode=yes -o StrictHostKeyChecking=no $rlocation mv $SAVE_PATH/$lhost-\$DATE/vmcore-incomplete $SAVE_PATH/$lhost-\$DATE/vmcore" - emit " reboot -f" + if [ -z "$CORE_COLLECTOR" ] + then + emit " ssh -q -o BatchMode=yes -o StrictHostKeyChecking=no $rlocation mv \$VMCORE-incomplete \$VMCORE" + else + emit " ssh -q -o BatchMode=yes -o StrictHostKeyChecking=no $rlocation mv \$VMCORE-incomplete \$VMCORE.flat" + fi + emit " echo \"Saving core complete\"" emit "fi" + if [ -x "$KDUMP_POST" ]; then + emit "$KDUMP_POST \$exitcode" + fi + emit "[ \$exitcode == 0 ] && $FINAL_ACTION" fi ;; core_collector) ;; + kdump_post) + ;; + extra_bins) + ;; + extra_modules) + ;; default) ;; link_delay) @@ -1635,52 +1827,71 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then ;; *) #test filesystem and directory creation - kdump_chk "test -f /sbin/fsck.$type" "Unsupported type $type" + kdump_chk "test -f /sbin/fsck.$config_opt" "Unsupported type $config_opt" tmnt=`mktemp -dq` - kdump_chk "mount -t $type $location $tmnt" "Bad mount point $location" + kdump_chk "mount -t $config_opt $config_val $tmnt" "Bad mount point $config_val" mkdir -p $tmnt/$SAVE_PATH tdir=`mktemp -dqp $tmnt/$SAVE_PATH` + rc=$? available_size=$(df $tdir | tail -1 | tr -s ' ' ':' | cut -d: -f4) - rc=$? && rm -rf $tdir && umount $tmnt + rm -rf $tdir > /dev/null 2>&1 + umount $tmnt > /dev/null 2>&1 if [ $rc != "0" ]; then - echo "Cannot create directory in $location: $SAVE_PATH" + echo "Cannot create directory in $config_val: $SAVE_PATH" exit 1 fi #check for available size is greater than $memtotal if [ $available_size -lt $memtotal ]; then echo "Warning: There is not space enough to save a vmcore." - echo " The size of $location should be much greater than $memtotal kilo bytes." + echo " The size of $config_val should be much greater than $memtotal kilo bytes." fi #setup filesystem case + + if [ -n "$KDUMP_PRE_INTERNAL" ] + then + emit "$KDUMP_PRE_INTERNAL" + emit "if [ $? -ne 0 ]" + emit "then" + emit " echo kdump_pre script exited with non-zero status" + emit " $FINAL_ACTION" + emit "fi" + fi + mkdir -p $MNTIMAGE/mnt touch $MNTIMAGE/etc/mtab if [ -z "$CORE_COLLECTOR" ]; then CORE_COLLECTOR="cp" fi - emit "echo Saving to the local filesystem $location" - emit "DUMPDEV=$location" + emit "echo Saving to the local filesystem $config_val" + emit "DUMPDEV=$config_val" emit "IS_LABEL=\`echo \$DUMPDEV | grep LABEL\`" emit "IS_UUID=\`echo \$DUMPDEV | grep UUID\`" emit "if [ -n \"\$IS_LABEL\" -o -n \"\$IS_UUID\" ] " emit "then" emit " DUMPDEV=\`findfs \$DUMPDEV\`" emit "fi" - emit "fsck.$type \$DUMPDEV" - emit "mount -t $type \$DUMPDEV /mnt" + emit "fsck.$config_opt \$DUMPDEV" + emit "mount -t $config_opt \$DUMPDEV /mnt" emit "if [ \$? == 0 ]" emit "then" emit " mkdir -p /mnt/$SAVE_PATH/127.0.0.1-\$DATE" - emit " $CORE_COLLECTOR /proc/vmcore /mnt/$SAVE_PATH/127.0.0.1-\$DATE/vmcore-incomplete" - emit " if [ \$? == 0 ]" + emit " VMCORE=/mnt/$SAVE_PATH/127.0.0.1-\$DATE/vmcore" + emit " export VMCORE" + emit " $CORE_COLLECTOR /proc/vmcore \$VMCORE-incomplete >/dev/null" + emit " exitcode=\$?" + emit " if [ \$exitcode == 0 ]" emit " then" - emit " mv /mnt/$SAVE_PATH/127.0.0.1-\$DATE/vmcore-incomplete /mnt/$SAVE_PATH/127.0.0.1-\$DATE/vmcore" - emit " umount /mnt" - emit " reboot -f" + emit " mv \$VMCORE-incomplete \$VMCORE" + emit " echo \"Saving core complete\"" emit " fi" + if [ -x "$KDUMP_POST" ]; then + emit " $KDUMP_POST \$exitcode" + fi emit "fi" emit "umount /mnt" + emit "[ \$exitcode == 0 ] && $FINAL_ACTION" ;; esac done < $KDUMP_CONFIG_FILE @@ -1691,17 +1902,29 @@ if [ -n "$KDUMP_CONFIG_FILE" ]; then emit "echo dropping to initramfs shell" emit "echo exiting this shell will reboot your system" emit "/bin/msh" - emit "reboot -f" - elif [ "$DEFAULT_ACTION" == "reboot" ] - then - emit "reboot -f" fi + case $DEFAULT_ACTION in + reboot|halt|shell) + emit "$FINAL_ACTION" + ;; + *) + emit "echo Attempting to enter user-space to capture vmcore" + ;; + esac #find the shared libraries. this snippet taken from kboot + TEMPLDCFG=`mktemp` + for lib in `ls /etc/ld.so.conf.d/* | grep -v kernelcap` + do + echo "include " $lib >> $TEMPLDCFG + done + /sbin/ldconfig -f $TEMPLDCFG kdump_libs=`for n in $bin; do ldd "$n" 2>/dev/null | tr -s '\011' ' ' | sed 's/.*=> *//;s/^ *//;/ *(0x.*)/s///p;d' done | sort | uniq | sed '/^ *$/d'` + /sbin/ldconfig + rm -f $TEMPLDCFG #copy the binaries and their shared libraries to the archive for n in $bin $kdump_libs $k_extras; do @@ -1734,11 +1957,18 @@ emit "fi" emit "echo Checking root filesystem." emit "fsck \$ROOTDEV" emit "echo Mounting root filesystem." -emit "FSTYPE=\`fsck -N \$ROOTDEV | awk '/.*sbin.*/ {print \$1}' | sed -e's/\\(^.*\\.\\)\\(.*\\)/\\2/'\`" -emit "fsck -t \$FSTYPE \$ROOTDEV" -emit "echo mount -t \$FSTYPE \$ROOTDEV /sysroot" -emit "mount -t \$FSTYPE \$ROOTDEV /sysroot" -emit "if [ \$? != 0 ]" +emit "for FSTYPE in ext3 ext2 minix" +emit "do" +emit " echo Trying mount -t \$FSTYPE \$ROOTDEV /sysroot" +emit " mount -t \$FSTYPE \$ROOTDEV /sysroot >/dev/null 2>&1 " +emit " if [ \$? == 0 ]" +emit " then" +emit " echo Using \$FSTYPE on root filesystem" +emit " ROOT_MOUNT_GOOD=1" +emit " break;" +emit " fi" +emit "done" +emit "if [ -z \"\$ROOT_MOUNT_GOOD\" ]" emit "then" emit " echo unable to mount rootfs. Dropping to shell" emit " /bin/msh" @@ -1754,6 +1984,8 @@ emit "touch /sysroot/fastboot" emit "echo Switching to new root and running init." emit "exec switch_root /sysroot /sbin/init" +# END OF INIT SCRIPT + chmod +x $RCFILE (cd $MNTIMAGE; findall . | cpio --quiet -c -o) >| $IMAGE || exit 1