188 lines
5.9 KiB
Diff
188 lines
5.9 KiB
Diff
From 726c130af8b1371aa32dc14f108a3fb1695860bb Mon Sep 17 00:00:00 2001
|
|
From: Chandru <chandru@in.ibm.com>
|
|
Date: Wed, 24 Sep 2008 17:19:07 +0530
|
|
Subject: [PATCH] kexec/kdump: read crash memory ranges from drconf memory
|
|
|
|
Get the memory ranges of the 1st kernel excluding the memory reserved for
|
|
kexec/kdump kernel in case of ibm,dynamic-reconfiguration-memory node of
|
|
device tree
|
|
|
|
Signed-off-by: Chandru Siddalingappa <chandru@in.ibm.com>
|
|
Signed-off-by: Simon Horman <horms@verge.net.au>
|
|
Acked-by: Bernhard Walle <bwalle@suse.de>
|
|
|
|
---
|
|
kexec/arch/ppc64/crashdump-ppc64.c | 121 ++++++++++++++++++++++++++-----------
|
|
kexec/arch/ppc64/crashdump-ppc64.h | 3
|
|
2 files changed, 90 insertions(+), 34 deletions(-)
|
|
|
|
--- a/kexec/arch/ppc64/crashdump-ppc64.c
|
|
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
|
|
@@ -84,6 +84,82 @@ mem_rgns_t usablemem_rgns = {0, NULL};
|
|
*/
|
|
uint64_t saved_max_mem = 0;
|
|
|
|
+static unsigned long long cstart, cend;
|
|
+static int memory_ranges;
|
|
+
|
|
+/*
|
|
+ * Exclude the region that lies within crashkernel
|
|
+ */
|
|
+static void exclude_crash_region(uint64_t start, uint64_t end)
|
|
+{
|
|
+ if (cstart < end && cend > start) {
|
|
+ if (start < cstart && end > cend) {
|
|
+ crash_memory_range[memory_ranges].start = start;
|
|
+ crash_memory_range[memory_ranges].end = cstart;
|
|
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
+ memory_ranges++;
|
|
+ crash_memory_range[memory_ranges].start = cend;
|
|
+ crash_memory_range[memory_ranges].end = end;
|
|
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
+ memory_ranges++;
|
|
+ } else if (start < cstart) {
|
|
+ crash_memory_range[memory_ranges].start = start;
|
|
+ crash_memory_range[memory_ranges].end = cstart;
|
|
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
+ memory_ranges++;
|
|
+ } else if (end > cend) {
|
|
+ crash_memory_range[memory_ranges].start = cend;
|
|
+ crash_memory_range[memory_ranges].end = end;
|
|
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
+ memory_ranges++;
|
|
+ }
|
|
+ } else {
|
|
+ crash_memory_range[memory_ranges].start = start;
|
|
+ crash_memory_range[memory_ranges].end = end;
|
|
+ crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
+ memory_ranges++;
|
|
+ }
|
|
+}
|
|
+
|
|
+static int get_dyn_reconf_crash_memory_ranges()
|
|
+{
|
|
+ uint64_t start, end;
|
|
+ char fname[128], buf[32];
|
|
+ FILE *file;
|
|
+ int i, n;
|
|
+
|
|
+ strcpy(fname, "/proc/device-tree/");
|
|
+ strcat(fname, "ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
|
|
+ if ((file = fopen(fname, "r")) == NULL) {
|
|
+ perror(fname);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ fseek(file, 4, SEEK_SET);
|
|
+ for (i = 0; i < num_of_lmbs; i++) {
|
|
+ if ((n = fread(buf, 1, 24, file)) < 0) {
|
|
+ perror(fname);
|
|
+ fclose(file);
|
|
+ return -1;
|
|
+ }
|
|
+ if (memory_ranges >= (max_memory_ranges + 1)) {
|
|
+ /* No space to insert another element. */
|
|
+ fprintf(stderr,
|
|
+ "Error: Number of crash memory ranges"
|
|
+ " excedeed the max limit\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ start = ((uint64_t *)buf)[0];
|
|
+ end = start + lmb_size;
|
|
+ if (start == 0 && end >= (BACKUP_SRC_END + 1))
|
|
+ start = BACKUP_SRC_END + 1;
|
|
+ exclude_crash_region(start, end);
|
|
+ }
|
|
+ fclose(file);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* 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.
|
|
@@ -98,7 +174,6 @@ uint64_t saved_max_mem = 0;
|
|
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];
|
|
@@ -106,7 +181,7 @@ static int get_crash_memory_ranges(struc
|
|
FILE *file;
|
|
struct dirent *dentry, *mentry;
|
|
int i, n, crash_rng_len = 0;
|
|
- unsigned long long start, end, cstart, cend;
|
|
+ unsigned long long start, end;
|
|
int page_size;
|
|
|
|
crash_max_memory_ranges = max_memory_ranges + 6;
|
|
@@ -129,7 +204,16 @@ static int get_crash_memory_ranges(struc
|
|
perror(device_tree);
|
|
goto err;
|
|
}
|
|
+
|
|
+ cstart = crash_base;
|
|
+ cend = crash_base + crash_size;
|
|
+
|
|
while ((dentry = readdir(dir)) != NULL) {
|
|
+ if (!strncmp(dentry->d_name,
|
|
+ "ibm,dynamic-reconfiguration-memory", 35)){
|
|
+ get_dyn_reconf_crash_memory_ranges();
|
|
+ continue;
|
|
+ }
|
|
if (strncmp(dentry->d_name, "memory@", 7) &&
|
|
strcmp(dentry->d_name, "memory"))
|
|
continue;
|
|
@@ -170,38 +254,7 @@ static int get_crash_memory_ranges(struc
|
|
if (start == 0 && end >= (BACKUP_SRC_END + 1))
|
|
start = BACKUP_SRC_END + 1;
|
|
|
|
- cstart = crash_base;
|
|
- cend = crash_base + crash_size;
|
|
- /*
|
|
- * Exclude the region that lies within crashkernel
|
|
- */
|
|
- if (cstart < end && cend > start) {
|
|
- if (start < cstart && end > cend) {
|
|
- crash_memory_range[memory_ranges].start = start;
|
|
- crash_memory_range[memory_ranges].end = cstart;
|
|
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
- memory_ranges++;
|
|
- crash_memory_range[memory_ranges].start = cend;
|
|
- crash_memory_range[memory_ranges].end = end;
|
|
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
- memory_ranges++;
|
|
- } else if (start < cstart) {
|
|
- crash_memory_range[memory_ranges].start = start;
|
|
- crash_memory_range[memory_ranges].end = cstart;
|
|
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
- memory_ranges++;
|
|
- } else if (end > cend){
|
|
- crash_memory_range[memory_ranges].start = cend;
|
|
- crash_memory_range[memory_ranges].end = end;
|
|
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
- memory_ranges++;
|
|
- }
|
|
- } else {
|
|
- crash_memory_range[memory_ranges].start = start;
|
|
- crash_memory_range[memory_ranges].end = end;
|
|
- crash_memory_range[memory_ranges].type = RANGE_RAM;
|
|
- memory_ranges++;
|
|
- }
|
|
+ exclude_crash_region(start, end);
|
|
fclose(file);
|
|
}
|
|
closedir(dmem);
|
|
--- a/kexec/arch/ppc64/crashdump-ppc64.h
|
|
+++ b/kexec/arch/ppc64/crashdump-ppc64.h
|
|
@@ -28,4 +28,7 @@ extern uint64_t crash_size;
|
|
extern unsigned int rtas_base;
|
|
extern unsigned int rtas_size;
|
|
|
|
+uint64_t lmb_size;
|
|
+unsigned int num_of_lmbs;
|
|
+
|
|
#endif /* CRASHDUMP_PPC64_H */
|