diff -up kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.c.orig kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.c
--- kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.c.orig	2010-06-02 09:19:34.000000000 -0400
+++ kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.c	2010-06-02 09:14:31.000000000 -0400
@@ -84,6 +84,90 @@ 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;
+	uint32_t flags;
+
+	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)[DRCONF_ADDR];
+		end = start + lmb_size;
+		if (start == 0 && end >= (BACKUP_SRC_END + 1))
+			start = BACKUP_SRC_END + 1;
+
+		flags = (*((uint32_t *)&buf[DRCONF_FLAGS]));
+		/* skip this block if the reserved bit is set in flags (0x80)
+		   or if the block is not assigned to this partition (0x8) */
+		if ((flags & 0x80) || !(flags & 0x8))
+			continue;
+
+		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 +182,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 +189,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 +212,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 +262,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);
diff -up kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.h.orig kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.h
--- kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.h.orig	2010-06-02 09:19:34.000000000 -0400
+++ kexec-tools-2.0.0/kexec/arch/ppc64/crashdump-ppc64.h	2010-06-02 09:14:31.000000000 -0400
@@ -30,4 +30,10 @@ extern uint64_t crash_size;
 extern unsigned int rtas_base;
 extern unsigned int rtas_size;
 
+uint64_t lmb_size;
+unsigned int num_of_lmbs;
+
+#define DRCONF_ADDR	0
+#define DRCONF_FLAGS	20
+
 #endif /* CRASHDUMP_PPC64_H */
diff -up kexec-tools-2.0.0/kexec/arch/ppc64/fs2dt.c.orig kexec-tools-2.0.0/kexec/arch/ppc64/fs2dt.c
--- kexec-tools-2.0.0/kexec/arch/ppc64/fs2dt.c.orig	2010-06-02 09:19:34.000000000 -0400
+++ kexec-tools-2.0.0/kexec/arch/ppc64/fs2dt.c	2010-06-02 09:14:08.000000000 -0400
@@ -122,6 +122,74 @@ static unsigned propnum(const char *name
 	return offset;
 }
 
+static void add_dyn_reconf_usable_mem_property(int fd)
+{
+	char fname[MAXPATH], *bname;
+	uint64_t buf[32];
+	uint64_t ranges[2*MAX_MEMORY_RANGES];
+	uint64_t base, end, loc_base, loc_end;
+	int range, rlen = 0, i;
+	int rngs_cnt, tmp_indx;
+
+	strcpy(fname, pathname);
+	bname = strrchr(fname, '/');
+	bname[0] = '\0';
+	bname = strrchr(fname, '/');
+	if (strncmp(bname, "/ibm,dynamic-reconfiguration-memory", 36))
+		return;
+
+	if (lseek(fd, 4, SEEK_SET) < 0)
+		die("unrecoverable error: error seeking in \"%s\": %s\n",
+			pathname, strerror(errno));
+
+	rlen = 0;
+	for (i = 0; i < num_of_lmbs; i++) {
+		if (read(fd, buf, 24) < 0)
+			die("unrecoverable error: error reading \"%s\": %s\n",
+				pathname, strerror(errno));
+
+		base = (uint64_t) buf[0];
+		end = base + lmb_size;
+		if (~0ULL - base < end)
+			die("unrecoverable error: mem property overflow\n");
+
+		tmp_indx = rlen++;
+
+		rngs_cnt = 0;
+		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;
+				rngs_cnt++;
+			} 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;
+				rngs_cnt++;
+			}
+		}
+		/* Store the count of (base, size) duple */
+		ranges[tmp_indx] = rngs_cnt;
+	}
+		
+	rlen = rlen * sizeof(uint64_t);
+	/*
+	 * Add linux,drconf-usable-memory property.
+	 */
+	*dt++ = 3;
+	*dt++ = rlen;
+	*dt++ = propnum("linux,drconf-usable-memory");
+	if ((rlen >= 8) && ((unsigned long)dt & 0x4))
+		dt++;
+	memcpy(dt, &ranges, rlen);
+	dt += (rlen + 3)/4;
+}
+
 static void add_usable_mem_property(int fd, int len)
 {
 	char fname[MAXPATH], *bname;
@@ -267,6 +335,10 @@ static void putprops(char *fn, struct di
 		dt += (len + 3)/4;
 		if (!strcmp(dp->d_name, "reg") && usablemem_rgns.size)
 			add_usable_mem_property(fd, len);
+		if (!strcmp(dp->d_name, "ibm,dynamic-memory") &&
+					usablemem_rgns.size)
+			add_dyn_reconf_usable_mem_property(fd);
+
 		close(fd);
 	}
 
diff -up kexec-tools-2.0.0/kexec/arch/ppc64/kexec-ppc64.c.orig kexec-tools-2.0.0/kexec/arch/ppc64/kexec-ppc64.c
--- kexec-tools-2.0.0/kexec/arch/ppc64/kexec-ppc64.c.orig	2010-06-02 09:19:34.000000000 -0400
+++ kexec-tools-2.0.0/kexec/arch/ppc64/kexec-ppc64.c	2010-06-02 09:19:31.000000000 -0400
@@ -96,39 +96,109 @@ err1:
 
 }
 
-/*
- * Count the memory nodes under /proc/device-tree and populate the
- * max_memory_ranges variable. This variable replaces MAX_MEMORY_RANGES
- * macro used earlier.
- */
-static int count_memory_ranges(void)
+static int realloc_memory_ranges(void)
 {
-	char device_tree[256] = "/proc/device-tree/";
-	struct dirent *dentry;
-	DIR *dir;
+	size_t memory_range_len;
 
-	if ((dir = opendir(device_tree)) == NULL) {
-		perror(device_tree);
+	max_memory_ranges++;
+	memory_range_len = sizeof(struct memory_range) * max_memory_ranges;
+
+	memory_range = (struct memory_range *) realloc(memory_range, memory_range_len);
+	if (!memory_range)
+		goto err;
+
+	base_memory_range = (struct memory_range *) realloc(base_memory_range, memory_range_len);
+	if (!base_memory_range)
+		goto err;
+
+	exclude_range = (struct memory_range *) realloc(exclude_range, memory_range_len);
+	if (!exclude_range)
+		goto err;
+
+	usablemem_rgns.ranges = (struct memory_range *)
+				realloc(usablemem_rgns.ranges, memory_range_len);
+	if (!(usablemem_rgns.ranges))
+		goto err;
+
+	return 0;
+
+err:
+	fprintf(stderr, "memory range structure re-allocation failure\n");
+	return -1;
+}
+
+
+static void add_base_memory_range(uint64_t start, uint64_t end)
+{
+	base_memory_range[nr_memory_ranges].start = start;
+	base_memory_range[nr_memory_ranges].end  = end;
+	base_memory_range[nr_memory_ranges].type = RANGE_RAM;
+	nr_memory_ranges++;
+	if (nr_memory_ranges >= max_memory_ranges)
+		realloc_memory_ranges();
+
+	dbgprintf("%016llx-%016llx : %x\n",
+		base_memory_range[nr_memory_ranges-1].start,
+		base_memory_range[nr_memory_ranges-1].end,
+		base_memory_range[nr_memory_ranges-1].type);
+}
+
+static int get_dyn_reconf_base_ranges(void)
+{
+	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,lmb-size");
+	if ((file = fopen(fname, "r")) == NULL) {
+		perror(fname);
 		return -1;
 	}
+	if (fread(buf, 1, 8, file) != 8) {
+		perror(fname);
+		fclose(file);
+		return -1;
+	}
+	/*
+	 * lmb_size, num_of_lmbs(global variables) are
+	 * initialized once here.
+	 */
+	lmb_size = ((uint64_t *)buf)[0];
+	fclose(file);
 
-	while ((dentry = readdir(dir)) != NULL) {
-		if (strncmp(dentry->d_name, "memory@", 7) &&
-			strcmp(dentry->d_name, "memory") &&
-			strncmp(dentry->d_name, "pci@", 4))
-			continue;
-		max_memory_ranges++;
+	strcpy(fname, "/proc/device-tree/");
+	strcat(fname,
+		"ibm,dynamic-reconfiguration-memory/ibm,dynamic-memory");
+	if ((file = fopen(fname, "r")) == NULL) {
+		perror(fname);
+		return -1;
 	}
-	/* need to add extra region for retained initrd */
-	if (reuse_initrd) {
-		max_memory_ranges++;
+	/* first 4 bytes tell the number of lmbs */
+	if (fread(buf, 1, 4, file) != 4) {
+		perror(fname);
+		fclose(file);
+		return -1;
 	}
+	num_of_lmbs = ((unsigned int *)buf)[0];
 
-	closedir(dir);
+	for (i = 0; i < num_of_lmbs; i++) {
+		if ((n = fread(buf, 1, 24, file)) < 0) {
+			perror(fname);
+			fclose(file);
+			return -1;
+		}
+		if (nr_memory_ranges >= max_memory_ranges)
+			return -1;
 
+		start = ((uint64_t *)buf)[0];
+		end = start + lmb_size;
+		add_base_memory_range(start, end);
+	}
+	fclose(file);
 	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
@@ -156,7 +226,7 @@ static int sort_base_ranges(void)
 /* Get base memory ranges */
 static int get_base_ranges(void)
 {
-	int local_memory_ranges = 0;
+	uint64_t start, end;
 	char device_tree[256] = "/proc/device-tree/";
 	char fname[256];
 	char buf[MAXBYTES];
@@ -170,6 +240,11 @@ static int get_base_ranges(void)
 		return -1;
 	}
 	while ((dentry = readdir(dir)) != NULL) {
+		if (!strncmp(dentry->d_name,
+				"ibm,dynamic-reconfiguration-memory", 35)) {
+			get_dyn_reconf_base_ranges();
+			continue;
+		}
 		if (strncmp(dentry->d_name, "memory@", 7) &&
 			strcmp(dentry->d_name, "memory"))
 			continue;
@@ -197,27 +272,18 @@ static int get_base_ranges(void)
 				closedir(dir);
 				return -1;
 			}
-			if (local_memory_ranges >= max_memory_ranges) {
-				fclose(file);
-				break;
+			if (nr_memory_ranges >= max_memory_ranges) {
+				if (realloc_memory_ranges() < 0)
+					break;
 			}
-			base_memory_range[local_memory_ranges].start =
-				((uint64_t *)buf)[0];
-			base_memory_range[local_memory_ranges].end  =
-				base_memory_range[local_memory_ranges].start +
-				((uint64_t *)buf)[1];
-			base_memory_range[local_memory_ranges].type = RANGE_RAM;
-			local_memory_ranges++;
-			dbgprintf("%016llx-%016llx : %x\n",
-				base_memory_range[local_memory_ranges-1].start,
-				base_memory_range[local_memory_ranges-1].end,
-				base_memory_range[local_memory_ranges-1].type);
+			start = ((uint64_t *)buf)[0];
+			end = start + ((uint64_t *)buf)[1];
+			add_base_memory_range(start, end);
 			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
@@ -276,7 +342,7 @@ static int get_devtree_details(unsigned 
 			strncmp(dentry->d_name, "memory@", 7) &&
 			strcmp(dentry->d_name, "memory") &&
 			strncmp(dentry->d_name, "pci@", 4) &&
-			strncmp(dentry->d_name, "rtas", 4))
+			strncmp(dentry->d_name, "rtas", 4)) 
 			continue;
 		strcpy(fname, device_tree);
 		strcat(fname, dentry->d_name);
@@ -301,6 +367,8 @@ static int get_devtree_details(unsigned 
 			exclude_range[i].start = 0x0UL;
 			exclude_range[i].end = kernel_end;
 			i++;
+			if (i >= max_memory_ranges)
+				realloc_memory_ranges();
 
 			if (kexec_flags & KEXEC_ON_CRASH) {
 				memset(fname, 0, sizeof(fname));
@@ -336,7 +404,7 @@ static int get_devtree_details(unsigned 
 					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);
 			}
@@ -375,6 +443,8 @@ static int get_devtree_details(unsigned 
 			exclude_range[i].start = htab_base;
 			exclude_range[i].end = htab_base + htab_size;
 			i++;
+			if (i >= max_memory_ranges)
+				realloc_memory_ranges();
 
 			/* reserve the initrd_start and end locations. */
 			if (reuse_initrd) {
@@ -420,6 +490,8 @@ static int get_devtree_details(unsigned 
 				exclude_range[i].start = initrd_start;
 				exclude_range[i].end = initrd_end;
 				i++;
+				if (i >= max_memory_ranges)
+					realloc_memory_ranges();
 			}
 		} /* chosen */
 
@@ -450,6 +522,8 @@ static int get_devtree_details(unsigned 
 			exclude_range[i].start = rtas_base;
 			exclude_range[i].end = rtas_base + rtas_size;
 			i++;
+			if (i >= max_memory_ranges)
+				realloc_memory_ranges();
 			if (kexec_flags & KEXEC_ON_CRASH)
 				add_usable_mem_rgns(rtas_base, rtas_size);
 		} /* rtas */
@@ -507,6 +581,8 @@ static int get_devtree_details(unsigned 
 			exclude_range[i].start = tce_base;
 			exclude_range[i].end = tce_base + tce_size;
 			i++;
+			if (i >= max_memory_ranges)
+				realloc_memory_ranges();
 			if (kexec_flags & KEXEC_ON_CRASH)
 				add_usable_mem_rgns(tce_base, tce_size);
 			closedir(cdir);
@@ -560,6 +636,8 @@ int setup_memory_ranges(unsigned long ke
 				memory_range[j].end = exclude_range[i].start - 1;
 				memory_range[j].type = RANGE_RAM;
 				j++;
+				if (j >= max_memory_ranges)
+					realloc_memory_ranges();
 			}
 		} /* i == 0 */
 		/* If the last exclude range does not end at memory_max, include
@@ -572,6 +650,8 @@ int setup_memory_ranges(unsigned long ke
 				memory_range[j].end = memory_max;
 				memory_range[j].type = RANGE_RAM;
 				j++;
+				if (j >= max_memory_ranges)
+					realloc_memory_ranges();
 				/* Limit the end to rmo_top */
 				if (memory_range[j-1].start >= rmo_top) {
 					j--;
@@ -592,6 +672,8 @@ int setup_memory_ranges(unsigned long ke
 		memory_range[j].end = exclude_range[i+1].start - 1;
 		memory_range[j].type = RANGE_RAM;
 		j++;
+		if (j >= max_memory_ranges)
+			realloc_memory_ranges();
 		/* Limit range to rmo_top */
 		if (memory_range[j-1].start >= rmo_top) {
 			j--;
@@ -623,14 +705,24 @@ out:
 int get_memory_ranges(struct memory_range **range, int *ranges,
 			unsigned long kexec_flags)
 {
-	if (count_memory_ranges())
-		return -1;
+        /* allocate memory_range dynamically */
+        max_memory_ranges = 1;
+
 	if (alloc_memory_ranges())
 		return -1;
 	if (setup_memory_ranges(kexec_flags))
 		return -1;
 
-	*range = memory_range;
+	/*
+	 * copy the memory here, another realloc_memory_ranges might
+	 * corrupt the old memory
+	 */
+	*range = calloc(sizeof(struct memory_range), nr_memory_ranges);
+	if (*range == NULL)
+		return -1;
+	memmove(*range, memory_range,
+		sizeof(struct memory_range) * nr_memory_ranges);
+
 	*ranges = nr_memory_ranges;
 	fprintf(stderr, "get memory ranges:%d\n", nr_memory_ranges);
 	return 0;
