summaryrefslogtreecommitdiff
path: root/kexec/arch/i386/crashdump-x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexec/arch/i386/crashdump-x86.c')
-rw-r--r--kexec/arch/i386/crashdump-x86.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index 7717219..478d6be 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -57,7 +57,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;
@@ -74,10 +75,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;
@@ -128,6 +131,22 @@ static int get_crash_memory_ranges(struct memory_range **range, int *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("Too small mem_max: 0x%lx.\n", mem_max);
+ return -1;
+ }
+ crash_reserved_mem.end = mem_max;
+ crash_reserved_mem.type = RANGE_RAM;
+ }
if (exclude_crash_reserve_region(&memory_ranges) < 0)
return -1;
*range = crash_memory_range;
@@ -514,7 +533,8 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
int nr_ranges, align = 1024;
struct memory_range *mem_range, *memmap_p;
- 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;
/*
@@ -535,14 +555,17 @@ 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);
- dbgprintf("Created backup segment at 0x%lx\n", info->backup_start);
- 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);
+ dbgprintf("Created backup segment at 0x%lx\n",
+ info->backup_start);
+ if (delete_memmap(memmap_p, info->backup_start, sz) < 0)
+ return -1;
+ }
/* Create elf header segment and store crash image data. */
if (arch_options.core_header_type == CORE_TYPE_ELF64) {