summaryrefslogtreecommitdiff
path: root/kexec/arch/x86_64/crashdump-x86_64.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/x86_64/crashdump-x86_64.c')
-rw-r--r--kexec/arch/x86_64/crashdump-x86_64.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/kexec/arch/x86_64/crashdump-x86_64.c b/kexec/arch/x86_64/crashdump-x86_64.c
index 9129458..8e33177 100644
--- a/kexec/arch/x86_64/crashdump-x86_64.c
+++ b/kexec/arch/x86_64/crashdump-x86_64.c
@@ -161,7 +161,8 @@ static struct memory_range crash_reserved_mem;
* to look into down the line. May be something like /proc/kernelmem or may
* be zone data structures exported from kernel.
*/
-static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
+static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
+ int kexec_flags)
{
const char *iomem= proc_iomem();
int memory_ranges = 0, gart = 0;
@@ -179,10 +180,12 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
/* First entry is for first 640K region. Different bios report first
* 640K in different manner hence hardcoding it */
- crash_memory_range[0].start = 0x00000000;
- crash_memory_range[0].end = 0x0009ffff;
- crash_memory_range[0].type = RANGE_RAM;
- memory_ranges++;
+ if (!(kexec_flags & KEXEC_PRESERVE_CONTEXT)) {
+ crash_memory_range[0].start = 0x00000000;
+ crash_memory_range[0].end = 0x0009ffff;
+ crash_memory_range[0].type = RANGE_RAM;
+ memory_ranges++;
+ }
while(fgets(line, sizeof(line), fp) != 0) {
char *str;
@@ -239,6 +242,22 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
memory_ranges++;
}
fclose(fp);
+ if (kexec_flags & KEXEC_PRESERVE_CONTEXT) {
+ int i;
+ for (i = 0; i < memory_ranges; i++) {
+ if (crash_memory_range[i].end > 0x0009ffff) {
+ crash_reserved_mem.start = \
+ crash_memory_range[i].start;
+ break;
+ }
+ }
+ if (crash_reserved_mem.start >= mem_max) {
+ fprintf(stderr, "Too small mem_max: 0x%llx.\n", mem_max);
+ return -1;
+ }
+ crash_reserved_mem.end = mem_max;
+ crash_reserved_mem.type = RANGE_RAM;
+ }
if (exclude_region(&memory_ranges, crash_reserved_mem.start,
crash_reserved_mem.end) < 0)
return -1;
@@ -590,7 +609,8 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
if (get_kernel_vaddr_and_size(info))
return -1;
- if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0)
+ if (get_crash_memory_ranges(&mem_range, &nr_ranges,
+ info->kexec_flags) < 0)
return -1;
/* Memory regions which panic kernel can safely use to boot into */
@@ -602,13 +622,15 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
add_memmap(memmap_p, crash_reserved_mem.start, sz);
/* Create a backup region segment to store backup data*/
- sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1);
- tmp = xmalloc(sz);
- memset(tmp, 0, sz);
- info->backup_start = add_buffer(info, tmp, sz, sz, align,
- 0, max_addr, 1);
- if (delete_memmap(memmap_p, info->backup_start, sz) < 0)
- return -1;
+ if (!(info->kexec_flags & KEXEC_PRESERVE_CONTEXT)) {
+ sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1);
+ tmp = xmalloc(sz);
+ memset(tmp, 0, sz);
+ info->backup_start = add_buffer(info, tmp, sz, sz, align,
+ 0, max_addr, 1);
+ if (delete_memmap(memmap_p, info->backup_start, sz) < 0)
+ return -1;
+ }
/* Create elf header segment and store crash image data. */
if (crash_create_elf64_headers(info, &elf_info,