All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
@ 2014-02-20  9:28 WANG Chao
  2014-02-20  9:28 ` [PATCH v2 1/4] cleanup: add dbgprint_mem_range function WANG Chao
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: WANG Chao @ 2014-02-20  9:28 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung; +Cc: kexec

Hi, All

When kaslr comes in and kdump is broken, it seems about the right time to use
E820 instead of memmap=exactmap to pass memmap for kdump for the default memmap
passing mechanism:
http://lists.infradead.org/pipermail/kexec/2014-February/011048.html

Unfortunately, saved_max_pfn still got its user out there (calgry pci, it looks
like the only one). So for backward compatibility, I'm introducing a new option
--pass-memmap-cmdline to force kexec-tools to pass memmap=exactmap, the old way.

Any comment is appreciate!

v1->v2:

Vivek:
 - Use function instead of macro for dbgprint_mem_range
 - Do not pass reserved memory range for kdump. It could addressed later
   separately.

WANG Chao (4):
  cleanup: add dbgprint_mem_range function
  x86: Store memory ranges globally used for crash kernel to boot into
  x86: add --pass-memmap-cmdline option
  x86: Pass memory range via E820 for kdump

 kexec/arch/i386/crashdump-x86.c        | 157 ++++++++++++++------------
 kexec/arch/i386/crashdump-x86.h        |   6 +-
 kexec/arch/i386/include/arch/options.h |   2 +
 kexec/arch/i386/kexec-x86-common.c     |   6 +-
 kexec/arch/i386/kexec-x86.c            |   4 +
 kexec/arch/i386/kexec-x86.h            |   1 +
 kexec/arch/i386/x86-linux-setup.c      | 195 ++++++++++++++++++++++++---------
 kexec/arch/i386/x86-linux-setup.h      |   1 +
 kexec/arch/x86_64/kexec-x86_64.c       |   5 +
 kexec/kexec.c                          |  10 ++
 kexec/kexec.h                          |   1 +
 11 files changed, 259 insertions(+), 129 deletions(-)

-- 
1.8.5.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/4] cleanup: add dbgprint_mem_range function
  2014-02-20  9:28 [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
@ 2014-02-20  9:28 ` WANG Chao
  2014-02-20  9:28 ` [PATCH v2 2/4] x86: Store memory ranges globally used for crash kernel to boot into WANG Chao
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-02-20  9:28 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung; +Cc: kexec

dbgprint_mem_range is used for printing the given memory range under
debugging mode.

Signed-off-by: WANG Chao <chaowang@redhat.com>
---
 kexec/arch/i386/kexec-x86-common.c |  6 +-----
 kexec/kexec.c                      | 10 ++++++++++
 kexec/kexec.h                      |  1 +
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/kexec/arch/i386/kexec-x86-common.c b/kexec/arch/i386/kexec-x86-common.c
index f55e2c2..e416177 100644
--- a/kexec/arch/i386/kexec-x86-common.c
+++ b/kexec/arch/i386/kexec-x86-common.c
@@ -374,11 +374,7 @@ int get_memory_ranges(struct memory_range **range, int *ranges,
 			mem_max = end;
 	}
 
-	dbgprintf("MEMORY RANGES\n");
-	for (i = 0; i < *ranges; i++) {
-		dbgprintf("%016Lx-%016Lx (%d)\n", (*range)[i].start,
-			  (*range)[i].end, (*range)[i].type);
-	}
+	dbgprint_mem_range("MEMORY RANGES", *range, *ranges);
 
 	return ret;
 }
diff --git a/kexec/kexec.c b/kexec/kexec.c
index 703d524..2d5a2e1 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -53,6 +53,16 @@ unsigned long long mem_max = ULONG_MAX;
 static unsigned long kexec_flags = 0;
 int kexec_debug = 0;
 
+void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr)
+{
+	int i;
+	dbgprintf(prefix, "\n");
+	for (i = 0; i < nr_mr; i++) {
+		dbgprintf("%016llx-%016llx (%d)\n", mr[i].start,
+			  mr[i].end, mr[i].type);
+	}
+}
+
 void die(const char *fmt, ...)
 {
 	va_list args;
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 2bd6e96..d69bba2 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -232,6 +232,7 @@ extern int file_types;
 
 #define KEXEC_OPT_STR "h?vdfxluet:p"
 
+extern void dbgprint_mem_range(const char *prefix, struct memory_range *mr, int nr_mr);
 extern void die(const char *fmt, ...)
 	__attribute__ ((format (printf, 1, 2)));
 extern void *xmalloc(size_t size);
-- 
1.8.5.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/4] x86: Store memory ranges globally used for crash kernel to boot into
  2014-02-20  9:28 [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
  2014-02-20  9:28 ` [PATCH v2 1/4] cleanup: add dbgprint_mem_range function WANG Chao
@ 2014-02-20  9:28 ` WANG Chao
  2014-02-20  9:28 ` [PATCH v2 3/4] x86: add --pass-memmap-cmdline option WANG Chao
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-02-20  9:28 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung; +Cc: kexec

Use these two variables to store the memory ranges and the number of
memory ranges for crash kernel to boot into:

struct memory_range crash_memory_range;
int crash_memory_range;

These two variables are not static now, so can be used in other file
later.

Signed-off-by: WANG Chao <chaowang@redhat.com>
---
 kexec/arch/i386/crashdump-x86.c | 134 ++++++++++++++++++++++------------------
 kexec/arch/i386/crashdump-x86.h |   5 +-
 2 files changed, 77 insertions(+), 62 deletions(-)

diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index 979c2bd..c55a6b1 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -179,7 +179,8 @@ static int exclude_region(int *nr_ranges, uint64_t start, uint64_t end);
 
 /* 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];
+struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
+int crash_memory_ranges;
 
 /* Memory region reserved for storing panic kernel and other data. */
 #define CRASH_RESERVED_MEM_NR	8
@@ -201,7 +202,7 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
 				   int kexec_flags, unsigned long lowmem_limit)
 {
 	const char *iomem = proc_iomem();
-	int memory_ranges = 0, gart = 0, i;
+	int gart = 0, i;
 	char line[MAX_LINE];
 	FILE *fp;
 	unsigned long long start, end;
@@ -218,7 +219,7 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
 		char *str;
 		int type, consumed, count;
 
-		if (memory_ranges >= CRASH_MAX_MEMORY_RANGES)
+		if (crash_memory_ranges >= CRASH_MAX_MEMORY_RANGES)
 			break;
 		count = sscanf(line, "%Lx-%Lx : %n",
 			&start, &end, &consumed);
@@ -250,17 +251,17 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
 			continue;
 		}
 
-		crash_memory_range[memory_ranges].start = start;
-		crash_memory_range[memory_ranges].end = end;
-		crash_memory_range[memory_ranges].type = type;
+		crash_memory_range[crash_memory_ranges].start = start;
+		crash_memory_range[crash_memory_ranges].end = end;
+		crash_memory_range[crash_memory_ranges].type = type;
 
-		segregate_lowmem_region(&memory_ranges, lowmem_limit);
+		segregate_lowmem_region(&crash_memory_ranges, lowmem_limit);
 
-		memory_ranges++;
+		crash_memory_ranges++;
 	}
 	fclose(fp);
 	if (kexec_flags & KEXEC_PRESERVE_CONTEXT) {
-		for (i = 0; i < memory_ranges; i++) {
+		for (i = 0; i < crash_memory_ranges; i++) {
 			if (crash_memory_range[i].end > 0x0009ffff) {
 				crash_reserved_mem[0].start = \
 					crash_memory_range[i].start;
@@ -278,17 +279,17 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges,
 	}
 
 	for (i = 0; i < crash_reserved_mem_nr; i++)
-		if (exclude_region(&memory_ranges, crash_reserved_mem[i].start,
+		if (exclude_region(&crash_memory_ranges, crash_reserved_mem[i].start,
 				crash_reserved_mem[i].end) < 0)
 			return -1;
 
 	if (gart) {
 		/* exclude GART region if the system has one */
-		if (exclude_region(&memory_ranges, gart_start, gart_end) < 0)
+		if (exclude_region(&crash_memory_ranges, gart_start, gart_end) < 0)
 			return -1;
 	}
 	*range = crash_memory_range;
-	*ranges = memory_ranges;
+	*ranges = crash_memory_ranges;
 
 	return 0;
 }
@@ -324,7 +325,7 @@ static int get_crash_memory_ranges_xen(struct memory_range **range,
 	}
 
 	*range = crash_memory_range;
-	*ranges = j;
+	*ranges = crash_memory_ranges = j;
 
 	qsort(*range, *ranges, sizeof(struct memory_range), compare_ranges);
 
@@ -417,8 +418,8 @@ static int exclude_region(int *nr_ranges, uint64_t start, uint64_t end)
 
 /* 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)
+static int add_memmap(struct memory_range *memmap_p, int *nr_range,
+					unsigned long long addr, size_t size)
 {
 	int i, j, nr_entries = 0, tidx = 0, align = 1024;
 	unsigned long long mstart, mend;
@@ -450,29 +451,23 @@ static int add_memmap(struct memory_range *memmap_p, unsigned long long addr,
 		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;
+	/* 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;
+	memmap_p[tidx].type = RANGE_RAM;
+	*nr_range = nr_entries + 1;
 
-	dbgprintf("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;
-		dbgprintf("%016llx - %016llx\n",
-			mstart, mend);
-	}
+	dbgprint_mem_range("Memmap after adding segment", memmap_p, *nr_range);
 
 	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)
+static int delete_memmap(struct memory_range *memmap_p, int *nr_range,
+					unsigned long long addr, size_t size)
 {
 	int i, j, nr_entries = 0, tidx = -1, operation = 0, align = 1024;
 	unsigned long long mstart, mend;
@@ -534,24 +529,17 @@ static int delete_memmap(struct memory_range *memmap_p, unsigned long long addr,
 		for (j = nr_entries-1; j > tidx; j--)
 			memmap_p[j+1] = memmap_p[j];
 		memmap_p[tidx+1] = temp_region;
+		*nr_range = nr_entries + 1;
 	}
 	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;
+		*nr_range = nr_entries - 1;
 	}
 
-	dbgprintf("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;
-		}
-		dbgprintf("%016llx - %016llx\n",
-			mstart, mend);
-	}
+	dbgprint_mem_range("Memmap after deleting segment", memmap_p, *nr_range);
 
 	return 0;
 }
@@ -626,6 +614,9 @@ static int cmdline_add_memmap(char *cmdline, struct memory_range *memmap_p)
 			/* All regions traversed. */
 			break;
 
+		if (memmap_p[i].type != RANGE_RAM)
+			continue;
+
 		/* A region is not worth adding if region size < 100K. It eats
 		 * up precious command line length. */
 		if ((endk - startk) < min_sizek)
@@ -797,6 +788,25 @@ static void get_backup_area(struct kexec_info *info,
 	info->backup_src_size = BACKUP_SRC_END - BACKUP_SRC_START + 1;
 }
 
+static void exclude_ram(struct memory_range *mr, int *nr_mr)
+{
+	int ranges, i, j, m;
+
+	ranges = *nr_mr;
+	for (i = 0, j = 0; i < ranges; i++) {
+		if (mr[j].type == RANGE_RAM) {
+			dbgprintf("Remove RAM %016llx-%016llxx: (%d)\n", mr[j].start, mr[j].end, mr[j].type);
+			for (m = j; m < *nr_mr; m++)
+				mr[m] = mr[m+1];
+			(*nr_mr)--;
+		} else {
+			j++;
+		}
+	}
+
+	dbgprint_mem_range("After remove RAM", mr, *nr_mr);
+}
+
 /* 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.
@@ -807,7 +817,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 	void *tmp;
 	unsigned long sz, bufsz, memsz, elfcorehdr;
 	int nr_ranges = 0, align = 1024, i;
-	struct memory_range *mem_range, *memmap_p;
+	struct memory_range *mem_range;
 	struct crash_elf_info elf_info;
 	unsigned kexec_arch;
 
@@ -850,10 +860,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 
 	get_backup_area(info, mem_range, nr_ranges);
 
-	dbgprintf("CRASH MEMORY RANGES\n");
-
-	for(i = 0; i < nr_ranges; ++i)
-		dbgprintf("%016Lx-%016Lx\n", mem_range[i].start, mem_range[i].end);
+	dbgprint_mem_range("CRASH MEMORY RANGES", mem_range, nr_ranges);
 
 	/*
 	 * if the core type has not been set on command line, set it here
@@ -878,17 +885,6 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 	if (get_kernel_vaddr_and_size(info, &elf_info))
 		return -1;
 
-	/* Memory regions which panic kernel can safely use to boot into */
-	sz = (sizeof(struct memory_range) * CRASH_MAX_MEMMAP_NR);
-	memmap_p = xmalloc(sz);
-	memset(memmap_p, 0, sz);
-	add_memmap(memmap_p, info->backup_src_start, info->backup_src_size);
-	for (i = 0; i < crash_reserved_mem_nr; i++) {
-		sz = crash_reserved_mem[i].end - crash_reserved_mem[i].start +1;
-		if (add_memmap(memmap_p, crash_reserved_mem[i].start, sz) < 0)
-			return ENOCRASHKERNEL;
-	}
-
 	/* Create a backup region segment to store backup data*/
 	if (!(info->kexec_flags & KEXEC_PRESERVE_CONTEXT)) {
 		sz = _ALIGN(info->backup_src_size, align);
@@ -898,8 +894,6 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 						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 EFAILED;
 	}
 
 	/* Create elf header segment and store crash image data. */
@@ -915,6 +909,23 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 						ELF_CORE_HEADER_ALIGN) < 0)
 			return EFAILED;
 	}
+
+	/* Memory regions which panic kernel can safely use to boot into */
+	exclude_ram(crash_memory_range, &crash_memory_ranges);
+
+	add_memmap(crash_memory_range, &crash_memory_ranges, info->backup_src_start, info->backup_src_size);
+	for (i = 0; i < crash_reserved_mem_nr; i++) {
+		sz = crash_reserved_mem[i].end - crash_reserved_mem[i].start +1;
+		if (add_memmap(crash_memory_range, &crash_memory_ranges, crash_reserved_mem[i].start, sz) < 0)
+			return ENOCRASHKERNEL;
+	}
+
+	/* exclude backup region from crash dump memory range */
+	sz = _ALIGN(info->backup_src_size, align);
+	if (delete_memmap(crash_memory_range, &crash_memory_ranges, info->backup_start, sz) < 0) {
+		return EFAILED;
+	}
+
 	/* the size of the elf headers allocated is returned in 'bufsz' */
 
 	/* Hack: With some ld versions (GNU ld version 2.14.90.0.4 20030523),
@@ -934,9 +945,9 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 	elfcorehdr = add_buffer(info, tmp, bufsz, memsz, align, min_base,
 							max_addr, -1);
 	dbgprintf("Created elf header segment at 0x%lx\n", elfcorehdr);
-	if (delete_memmap(memmap_p, elfcorehdr, memsz) < 0)
+	if (delete_memmap(crash_memory_range, &crash_memory_ranges, elfcorehdr, memsz) < 0)
 		return -1;
-	cmdline_add_memmap(mod_cmdline, memmap_p);
+	cmdline_add_memmap(mod_cmdline, crash_memory_range);
 	if (!bzImage_support_efi_boot)
 		cmdline_add_efi(mod_cmdline);
 	cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
@@ -951,6 +962,7 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 		end = mem_range[i].end;
 		cmdline_add_memmap_acpi(mod_cmdline, start, end);
 	}
+
 	return 0;
 }
 
diff --git a/kexec/arch/i386/crashdump-x86.h b/kexec/arch/i386/crashdump-x86.h
index b61cf0a..633ee0e 100644
--- a/kexec/arch/i386/crashdump-x86.h
+++ b/kexec/arch/i386/crashdump-x86.h
@@ -20,7 +20,7 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
 /* Kernel text size */
 #define X86_64_KERNEL_TEXT_SIZE  (512UL*1024*1024)
 
-#define CRASH_MAX_MEMMAP_NR	(KEXEC_MAX_SEGMENTS + 1)
+#define CRASH_MAX_MEMMAP_NR	CRASH_MAX_MEMORY_RANGES
 #define CRASH_MAX_MEMORY_RANGES	(MAX_MEMORY_RANGES + 2)
 
 /* Backup Region, First 640K of System RAM. */
@@ -28,4 +28,7 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
 #define BACKUP_SRC_END		0x0009ffff
 #define BACKUP_SRC_SIZE	(BACKUP_SRC_END - BACKUP_SRC_START + 1)
 
+extern struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
+extern int crash_memory_ranges;
+
 #endif /* CRASHDUMP_X86_H */
-- 
1.8.5.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/4] x86: add --pass-memmap-cmdline option
  2014-02-20  9:28 [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
  2014-02-20  9:28 ` [PATCH v2 1/4] cleanup: add dbgprint_mem_range function WANG Chao
  2014-02-20  9:28 ` [PATCH v2 2/4] x86: Store memory ranges globally used for crash kernel to boot into WANG Chao
@ 2014-02-20  9:28 ` WANG Chao
  2014-02-20  9:28 ` [PATCH v2 4/4] x86: Pass memory range via E820 for kdump WANG Chao
  2014-02-24 10:38 ` [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass " Thomas Renninger
  4 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-02-20  9:28 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung; +Cc: kexec

--pass-memmap-cmdline is used for pass memmap=exactmap cmdline for 2nd
kernel. Later we will use this option to disable passing E820 memmap
method but use the old exactmap method.

Signed-off-by: WANG Chao <chaowang@redhat.com>
---
 kexec/arch/i386/include/arch/options.h | 2 ++
 kexec/arch/i386/kexec-x86.c            | 4 ++++
 kexec/arch/i386/kexec-x86.h            | 1 +
 kexec/arch/i386/x86-linux-setup.h      | 1 +
 kexec/arch/x86_64/kexec-x86_64.c       | 5 +++++
 5 files changed, 13 insertions(+)

diff --git a/kexec/arch/i386/include/arch/options.h b/kexec/arch/i386/include/arch/options.h
index aaac731..e5300b5 100644
--- a/kexec/arch/i386/include/arch/options.h
+++ b/kexec/arch/i386/include/arch/options.h
@@ -30,6 +30,7 @@
 #define OPT_VGA 		(OPT_ARCH_MAX+8)
 #define OPT_REAL_MODE		(OPT_ARCH_MAX+9)
 #define OPT_ENTRY_32BIT		(OPT_ARCH_MAX+10)
+#define OPT_PASS_MEMMAP_CMDLINE	(OPT_ARCH_MAX+11)
 
 /* Options relevant to the architecture (excluding loader-specific ones): */
 #define KEXEC_ARCH_OPTIONS \
@@ -41,6 +42,7 @@
 	{ "console-serial", 0, 0, OPT_CONSOLE_SERIAL }, \
 	{ "elf32-core-headers", 0, 0, OPT_ELF32_CORE }, \
 	{ "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \
+	{ "pass-memmap-cmdline", 0, 0, OPT_PASS_MEMMAP_CMDLINE }, \
 
 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
 
diff --git a/kexec/arch/i386/kexec-x86.c b/kexec/arch/i386/kexec-x86.c
index 014ecd5..0b58dff 100644
--- a/kexec/arch/i386/kexec-x86.c
+++ b/kexec/arch/i386/kexec-x86.c
@@ -54,6 +54,7 @@ void arch_usage(void)
 		"     --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"
+		"     --pass--memmap-cmdline    Pass memory map via command line in kexec on panic case\n"
 		);
 }
 
@@ -64,6 +65,7 @@ struct arch_options_t arch_options = {
 	.console_vga = 0,
 	.console_serial = 0,
 	.core_header_type = CORE_TYPE_UNDEF,
+	.pass_memmap_cmdline = 0,
 };
 
 int arch_process_options(int argc, char **argv)
@@ -133,6 +135,8 @@ int arch_process_options(int argc, char **argv)
 		case OPT_ELF64_CORE:
 			arch_options.core_header_type = CORE_TYPE_ELF64;
 			break;
+		case OPT_PASS_MEMMAP_CMDLINE:
+			arch_options.pass_memmap_cmdline = 1;
 		}
 	}
 	/* Reset getopt for the next pass; called in other source modules */
diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h
index 5aa2a46..e8c9188 100644
--- a/kexec/arch/i386/kexec-x86.h
+++ b/kexec/arch/i386/kexec-x86.h
@@ -50,6 +50,7 @@ struct arch_options_t {
 	uint8_t  	console_vga;
 	uint8_t  	console_serial;
 	enum coretype	core_header_type;
+	uint8_t  	pass_memmap_cmdline;
 };
 
 int multiboot_x86_probe(const char *buf, off_t len);
diff --git a/kexec/arch/i386/x86-linux-setup.h b/kexec/arch/i386/x86-linux-setup.h
index 6fb84b4..b0ccd26 100644
--- a/kexec/arch/i386/x86-linux-setup.h
+++ b/kexec/arch/i386/x86-linux-setup.h
@@ -30,5 +30,6 @@ void setup_linux_system_parameters(struct kexec_info *info,
 /* command line parameter may be appended by purgatory */
 #define PURGATORY_CMDLINE_SIZE 64
 extern int bzImage_support_efi_boot;
+extern int pass_memmap_cmdline;
 
 #endif /* X86_LINUX_SETUP_H */
diff --git a/kexec/arch/x86_64/kexec-x86_64.c b/kexec/arch/x86_64/kexec-x86_64.c
index 5c23e01..f70851d 100644
--- a/kexec/arch/x86_64/kexec-x86_64.c
+++ b/kexec/arch/x86_64/kexec-x86_64.c
@@ -53,6 +53,7 @@ void arch_usage(void)
 		"     --serial-baud=<baud_rate> Specify the serial port baud rate\n"
 		"     --console-vga             Enable the vga console\n"
 		"     --console-serial          Enable the serial console\n"
+		"     --pass-memmap-cmdline     Pass memory map via command line in kexec on panic case\n"
 		);
 }
 
@@ -63,6 +64,7 @@ struct arch_options_t arch_options = {
 	.console_vga = 0,
 	.console_serial = 0,
 	.core_header_type = CORE_TYPE_ELF64,
+	.pass_memmap_cmdline = 0,
 };
 
 int arch_process_options(int argc, char **argv)
@@ -126,6 +128,9 @@ int arch_process_options(int argc, char **argv)
 			}
 			arch_options.serial_baud = value;
 			break;
+		case OPT_PASS_MEMMAP_CMDLINE:
+			arch_options.pass_memmap_cmdline = 1;
+			break;
 		}
 	}
 	/* Reset getopt for the next pass; called in other source modules */
-- 
1.8.5.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/4] x86: Pass memory range via E820 for kdump
  2014-02-20  9:28 [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
                   ` (2 preceding siblings ...)
  2014-02-20  9:28 ` [PATCH v2 3/4] x86: add --pass-memmap-cmdline option WANG Chao
@ 2014-02-20  9:28 ` WANG Chao
  2014-02-27 20:53   ` Linn Crosetto
  2014-02-24 10:38 ` [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass " Thomas Renninger
  4 siblings, 1 reply; 19+ messages in thread
From: WANG Chao @ 2014-02-20  9:28 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung; +Cc: kexec

command line size is restricted by kernel, sometimes memmap=exactmap has
too many memory ranges to pass to cmdline. A better approach, to pass the
memory ranges for crash kernel to boot into, is filling the memory
ranges into E820.

boot_params only got 128 slots for E820 map to fit in, when the number of
memory map exceeds 128, use setup_data to pass the rest as extended E820
memory map.

kexec boot could also benefit from setup_data in case E820 memory map
exceeds 128.

Now this new approach becomes default instead of memmap=exactmap.
saved_max_pfn users can specify --pass-memmap-cmdline to use the
exactmap approach.

Signed-off-by: WANG Chao <chaowang@redhat.com>
---
 kexec/arch/i386/crashdump-x86.c   |  25 +++--
 kexec/arch/i386/crashdump-x86.h   |   1 +
 kexec/arch/i386/x86-linux-setup.c | 195 +++++++++++++++++++++++++++-----------
 3 files changed, 158 insertions(+), 63 deletions(-)

diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index c55a6b1..cb19e7d 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -182,6 +182,8 @@ static int exclude_region(int *nr_ranges, uint64_t start, uint64_t end);
 struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
 int crash_memory_ranges;
 
+int pass_memmap_cmdline;
+
 /* Memory region reserved for storing panic kernel and other data. */
 #define CRASH_RESERVED_MEM_NR	8
 static struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
@@ -947,20 +949,23 @@ int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
 	dbgprintf("Created elf header segment at 0x%lx\n", elfcorehdr);
 	if (delete_memmap(crash_memory_range, &crash_memory_ranges, elfcorehdr, memsz) < 0)
 		return -1;
-	cmdline_add_memmap(mod_cmdline, crash_memory_range);
 	if (!bzImage_support_efi_boot)
 		cmdline_add_efi(mod_cmdline);
 	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
-			|| mem_range[i].type == RANGE_ACPI_NVS) )
-			continue;
-		start = mem_range[i].start;
-		end = mem_range[i].end;
-		cmdline_add_memmap_acpi(mod_cmdline, start, end);
+	pass_memmap_cmdline = arch_options.pass_memmap_cmdline;
+	if (pass_memmap_cmdline) {
+		cmdline_add_memmap(mod_cmdline, crash_memory_range);
+		/* 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
+						|| mem_range[i].type == RANGE_ACPI_NVS) )
+				continue;
+			start = mem_range[i].start;
+			end = mem_range[i].end;
+			cmdline_add_memmap_acpi(mod_cmdline, start, end);
+		}
 	}
 
 	return 0;
diff --git a/kexec/arch/i386/crashdump-x86.h b/kexec/arch/i386/crashdump-x86.h
index 633ee0e..e68b626 100644
--- a/kexec/arch/i386/crashdump-x86.h
+++ b/kexec/arch/i386/crashdump-x86.h
@@ -30,5 +30,6 @@ int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
 
 extern struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
 extern int crash_memory_ranges;
+extern int pass_memmap_cmdline;
 
 #endif /* CRASHDUMP_X86_H */
diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c
index 5884f4d..209652c 100644
--- a/kexec/arch/i386/x86-linux-setup.c
+++ b/kexec/arch/i386/x86-linux-setup.c
@@ -35,8 +35,7 @@
 #include "kexec-x86.h"
 #include "x86-linux-setup.h"
 #include "../../kexec/kexec-syscall.h"
-
-#define SETUP_EFI	4
+#include "crashdump-x86.h"
 
 void init_linux_parameters(struct x86_linux_param_header *real_mode)
 {
@@ -502,6 +501,11 @@ struct efi_setup_data {
 struct setup_data {
 	uint64_t next;
 	uint32_t type;
+#define SETUP_NONE	0
+#define SETUP_E820_EXT	1
+#define SETUP_DTB	2
+#define SETUP_PCI	3
+#define SETUP_EFI	4
 	uint32_t len;
 	uint8_t data[0];
 } __attribute__((packed));
@@ -602,6 +606,17 @@ struct efi_info {
 	uint32_t efi_memmap_hi;
 };
 
+static void add_setup_data(struct kexec_info *info,
+			   struct x86_linux_param_header *real_mode,
+			   struct setup_data *sd)
+{
+	int sdsize = sizeof(struct setup_data) + sd->len;
+
+	sd->next = real_mode->setup_data;
+	real_mode->setup_data = add_buffer(info, sd, sdsize, sdsize, getpagesize(),
+			    0x100000, ULONG_MAX, INT_MAX);
+}
+
 /*
  * setup_efi_data will collect below data and pass them to 2nd kernel.
  * 1) SMBIOS, fw_vendor, runtime, config_table, they are passed via x86
@@ -611,11 +626,11 @@ struct efi_info {
 static int setup_efi_data(struct kexec_info *info,
 			  struct x86_linux_param_header *real_mode)
 {
-	int64_t setup_data_paddr, memmap_paddr;
+	int64_t memmap_paddr;
 	struct setup_data *sd;
 	struct efi_setup_data *esd;
 	struct efi_mem_descriptor *maps;
-	int nr_maps, size, sdsize, ret = 0;
+	int nr_maps, size, ret = 0;
 	struct efi_info *ei = (struct efi_info *)real_mode->efi_info;
 
 	ret = access("/sys/firmware/efi/systab", F_OK);
@@ -648,10 +663,8 @@ static int setup_efi_data(struct kexec_info *info,
 	sd->len = sizeof(*esd);
 	memcpy(sd->data, esd, sizeof(*esd));
 	free(esd);
-	sdsize = sd->len + sizeof(struct setup_data);
-	setup_data_paddr = add_buffer(info, sd, sdsize, sdsize, getpagesize(),
-					0x100000, ULONG_MAX, INT_MAX);
-	real_mode->setup_data = setup_data_paddr;
+
+	add_setup_data(info, real_mode, sd);
 
 	size = nr_maps * sizeof(struct efi_mem_descriptor);
 	memmap_paddr = add_buffer(info, maps, size, size, getpagesize(),
@@ -669,6 +682,119 @@ out:
 	return ret;
 }
 
+static void setup_e820_ext(struct kexec_info *info, struct x86_linux_param_header *real_mode,
+			   struct memory_range *range, int nr_range)
+{
+	struct setup_data *sd;
+	struct e820entry *e820;
+	int i, j, nr_range_ext;
+
+	nr_range_ext = nr_range - E820MAX;
+	sd = malloc(sizeof(struct setup_data) + nr_range_ext * sizeof(struct e820entry));
+	sd->next = 0;
+	sd->len = nr_range_ext * sizeof(struct e820entry);
+	sd->type = SETUP_E820_EXT;
+
+	e820 = (struct e820entry *) sd->data;
+	dbgprintf("Extended E820 via setup_data:\n");
+	for(i = 0, j = E820MAX; i < nr_range_ext; i++, j++) {
+		e820[i].addr = range[j].start;
+		e820[i].size = range[j].end - range[j].start;
+		switch (range[j].type) {
+		case RANGE_RAM:
+			e820[i].type = E820_RAM;
+			break;
+		case RANGE_ACPI:
+			e820[i].type = E820_ACPI;
+			break;
+		case RANGE_ACPI_NVS:
+			e820[i].type = E820_NVS;
+			break;
+		default:
+		case RANGE_RESERVED:
+			e820[i].type = E820_RESERVED;
+			break;
+		}
+		dbgprintf("%016lx-%016lx (%d)\n",
+				e820[i].addr,
+				e820[i].addr + e820[i].size - 1,
+				e820[i].type);
+
+		if (range[j].type != RANGE_RAM)
+			continue;
+		if ((range[j].start <= 0x100000) && range[j].end > 0x100000) {
+			unsigned long long mem_k = (range[j].end >> 10) - (0x100000 >> 10);
+			real_mode->ext_mem_k = mem_k;
+			real_mode->alt_mem_k = mem_k;
+			if (mem_k > 0xfc00) {
+				real_mode->ext_mem_k = 0xfc00; /* 64M */
+			}
+			if (mem_k > 0xffffffff) {
+				real_mode->alt_mem_k = 0xffffffff;
+			}
+		}
+	}
+	add_setup_data(info, real_mode, sd);
+	free(sd);
+}
+
+static void setup_e820(struct kexec_info *info, struct x86_linux_param_header *real_mode,
+		       struct memory_range *range, int nr_range)
+{
+
+	int nr_range_saved = nr_range;
+	int i;
+
+	if (nr_range > E820MAX) {
+		nr_range = E820MAX;
+	}
+
+	real_mode->e820_map_nr = nr_range;
+	dbgprintf("E820 memmap:\n");
+	for(i = 0; i < nr_range; i++) {
+		real_mode->e820_map[i].addr = range[i].start;
+		real_mode->e820_map[i].size = range[i].end - range[i].start;
+		switch (range[i].type) {
+			case RANGE_RAM:
+				real_mode->e820_map[i].type = E820_RAM;
+				break;
+			case RANGE_ACPI:
+				real_mode->e820_map[i].type = E820_ACPI;
+				break;
+			case RANGE_ACPI_NVS:
+				real_mode->e820_map[i].type = E820_NVS;
+				break;
+			default:
+			case RANGE_RESERVED:
+				real_mode->e820_map[i].type = E820_RESERVED;
+				break;
+		}
+		dbgprintf("%016lx-%016lx (%d)\n",
+				real_mode->e820_map[i].addr,
+				real_mode->e820_map[i].addr + real_mode->e820_map[i].size - 1,
+				real_mode->e820_map[i].type);
+
+		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 >> 10);
+			real_mode->ext_mem_k = mem_k;
+			real_mode->alt_mem_k = mem_k;
+			if (mem_k > 0xfc00) {
+				real_mode->ext_mem_k = 0xfc00; /* 64M */
+			}
+			if (mem_k > 0xffffffff) {
+				real_mode->alt_mem_k = 0xffffffff;
+			}
+		}
+	}
+
+	if (nr_range_saved > E820MAX) {
+		dbgprintf("extra E820 memmap are passed via setup_data\n");
+		setup_e820_ext(info, real_mode, range, nr_range_saved);
+	}
+}
+
 static int
 get_efi_mem_desc_version(struct x86_linux_param_header *real_mode)
 {
@@ -704,7 +830,7 @@ void setup_linux_system_parameters(struct kexec_info *info,
 {
 	/* Fill in information the BIOS would usually provide */
 	struct memory_range *range;
-	int i, ranges;
+	int ranges;
 
 	/* get subarch from running kernel */
 	setup_subarch(real_mode);
@@ -746,51 +872,14 @@ void setup_linux_system_parameters(struct kexec_info *info,
 	/* another safe default */
 	real_mode->aux_device_info = 0;
 
-	range = info->memory_range;
-	ranges = info->memory_ranges;
-	if (ranges > E820MAX) {
-		if (!(info->kexec_flags & KEXEC_ON_CRASH))
-			/*
-			 * this e820 not used for capture kernel, see
-			 * do_bzImage_load()
-			 */
-			fprintf(stderr,
-				"Too many memory ranges, truncating...\n");
-		ranges = E820MAX;
-	}
-	real_mode->e820_map_nr = ranges;
-	for(i = 0; i < ranges; i++) {
-		real_mode->e820_map[i].addr = range[i].start;
-		real_mode->e820_map[i].size = range[i].end - range[i].start;
-		switch (range[i].type) {
-		case RANGE_RAM:
-			real_mode->e820_map[i].type = E820_RAM; 
-			break;
-		case RANGE_ACPI:
-			real_mode->e820_map[i].type = E820_ACPI; 
-			break;
-		case RANGE_ACPI_NVS:
-			real_mode->e820_map[i].type = E820_NVS;
-			break;
-		default:
-		case RANGE_RESERVED:
-			real_mode->e820_map[i].type = E820_RESERVED; 
-			break;
-		}
-		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 >> 10);
-			real_mode->ext_mem_k = mem_k;
-			real_mode->alt_mem_k = mem_k;
-			if (mem_k > 0xfc00) {
-				real_mode->ext_mem_k = 0xfc00; /* 64M */
-			}
-			if (mem_k > 0xffffffff) {
-				real_mode->alt_mem_k = 0xffffffff;
-			}
-		}
+	if (info->kexec_flags & KEXEC_ON_CRASH && !pass_memmap_cmdline) {
+		range = crash_memory_range;
+		ranges = crash_memory_ranges;
+	} else {
+		range = info->memory_range;
+		ranges = info->memory_ranges;
 	}
+	setup_e820(info, real_mode, range, ranges);
 
 	/* fill the EDD information */
 	setup_edd_info(real_mode);
-- 
1.8.5.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-20  9:28 [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
                   ` (3 preceding siblings ...)
  2014-02-20  9:28 ` [PATCH v2 4/4] x86: Pass memory range via E820 for kdump WANG Chao
@ 2014-02-24 10:38 ` Thomas Renninger
  2014-02-24 14:58   ` WANG Chao
  4 siblings, 1 reply; 19+ messages in thread
From: Thomas Renninger @ 2014-02-24 10:38 UTC (permalink / raw)
  To: WANG Chao; +Cc: kexec, horms, ebiederm, hpa, dyoung, vgoyal

On Thursday, February 20, 2014 05:28:28 PM WANG Chao wrote:
> Hi, All
> 
> When kaslr comes in and kdump is broken, it seems about the right time to
> use E820 instead of memmap=exactmap to pass memmap for kdump for the
> default memmap passing mechanism:
> http://lists.infradead.org/pipermail/kexec/2014-February/011048.html
> 
> Unfortunately, saved_max_pfn still got its user out there (calgry pci, it
> looks like the only one). So for backward compatibility, I'm introducing a
> new option --pass-memmap-cmdline to force kexec-tools to pass
> memmap=exactmap, the old way.
The saved_max_pfn usage is calgary pci looks bad/wrong and I wonder:
  - whether this is still worth touching, so that the old mechanism:
    --pass-memmap-cmdline could vanish in the one or other year and need
    not to be carried forever
I tried to find such a machine, but couldn't find anything mentioning calgary
in quite some machines' dmesg.

Approaches to avoid saved_max_pfn in calgary case:
  1) If done correctly from the beginning, the TCE table size would have
     been exposed via /sys and kexec-tools could simply add:
     calgary="128k|512K...|8M" which is already caught by pci-calgary and
     saved_max_pfn is not needed/touched anymore.
     -> Disadvantage: needs a new sysfs entry
  2) When finding max_pfn for calgary table size usage, we could try in 
     kdump case to use the highest memory (RAM or RESERVED) showing up
     in e820 map.

Please find below a patch which would eleminate the last saved_max_pfn
user. Unfortunately I could not find a calgary system to test this on.

Be aware: I could not test this.
If someone tells me for what kind of machine (and BIOS stuff enabled?)
I should look for, I can try to search for such a platform.

Something else: There is quite some duplicate code in kexec-tools when it
is about retrieving the e820 table info (normal kexec vs kdump).
Did you see my cleanups I posted long ago? Do you plan to still clean up
a bit after this series?

        Thomas



X86: Eliminate saved_max_pfn user in pci-calgary and remove the unused variable

Searching for the highest value of RAM and RESERVED memory in kdump case
should be the same as max_pfn of the original kernel.
At least this is always the case as long as type usable RAM is the highest
entry in original e820 map.

Signed-off-by: Thomas Renninger <trenn@suse.de>

diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
index 779c2ef..712173e 100644
--- a/arch/x86/include/asm/e820.h
+++ b/arch/x86/include/asm/e820.h
@@ -49,6 +49,7 @@ static inline void early_memtest(unsigned long start, unsigned long end)
 #endif
 
 extern unsigned long e820_end_of_ram_pfn(void);
+extern unsigned long e820_end_of_e820_pfn(void);
 extern unsigned long e820_end_of_low_ram_pfn(void);
 extern u64 early_reserve_e820(u64 sizet, u64 align);
 
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 988c00a..699e8fe 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -757,7 +757,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
 /*
  * Find the highest page frame number we have available
  */
-static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
 {
 	int i;
 	unsigned long last_pfn = 0;
@@ -796,6 +796,12 @@ unsigned long __init e820_end_of_ram_pfn(void)
 	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
 }
 
+unsigned long __init e820_end_of_e820_pfn(void)
+{
+	return max(e820_end_pfn(MAX_ARCH_PFN, E820_RAM),
+		   e820_end_pfn(MAX_ARCH_PFN, E820_RESERVED);
+}
+
 unsigned long __init e820_end_of_low_ram_pfn(void)
 {
 	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
@@ -847,14 +853,6 @@ static int __init parse_memmap_one(char *p)
 		return -EINVAL;
 
 	if (!strncmp(p, "exactmap", 8)) {
-#ifdef CONFIG_CRASH_DUMP
-		/*
-		 * If we are doing a crash dump, we still need to know
-		 * the real mem size before original memory map is
-		 * reset.
-		 */
-		saved_max_pfn = e820_end_of_ram_pfn();
-#endif
 		e820.nr_map = 0;
 		userdef = 1;
 		return 0;
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 299d493..89ae766 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -1371,6 +1371,7 @@ int __init detect_calgary(void)
 	unsigned long ptr;
 	unsigned int offset, prev_offset;
 	int ret;
+	unsigned long orig_max_pfn = max_pfn;
 
 	/*
 	 * if the user specified iommu=off or iommu=soft or we found
@@ -1418,8 +1419,10 @@ int __init detect_calgary(void)
 		return -ENOMEM;
 	}
 
-	specified_table_size = determine_tce_table_size((is_kdump_kernel() ?
-					saved_max_pfn : max_pfn) * PAGE_SIZE);
+	if (is_kdump_kernel())
+		orig_max_pfn = e820_end_of_e820_pfn();
+	specified_table_size = determine_tce_table_size(orig_max_pfn
+							* PAGE_SIZE);
 
 	for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
 		struct calgary_bus_info *info = &bus_info[bus];
diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
index 7032518..bce4d97 100644
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -87,5 +87,4 @@ extern void unregister_oldmem_pfn_is_ram(void);
 static inline int is_kdump_kernel(void) { return 0; }
 #endif /* CONFIG_CRASH_DUMP */
 
-extern unsigned long saved_max_pfn;
 #endif /* LINUX_CRASHDUMP_H */
diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
index c766ee5..9d50486 100644
--- a/kernel/crash_dump.c
+++ b/kernel/crash_dump.c
@@ -5,12 +5,6 @@
 #include <linux/export.h>
 
 /*
- * If we have booted due to a crash, max_pfn will be a very low value. We need
- * to know the amount of memory that the previous kernel used.
- */
-unsigned long saved_max_pfn;
-
-/*
  * stores the physical address of elf header of crash image
  *
  * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 10:38 ` [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass " Thomas Renninger
@ 2014-02-24 14:58   ` WANG Chao
  2014-02-24 15:03     ` H. Peter Anvin
  2014-02-24 15:22     ` Vivek Goyal
  0 siblings, 2 replies; 19+ messages in thread
From: WANG Chao @ 2014-02-24 14:58 UTC (permalink / raw)
  To: Thomas Renninger; +Cc: kexec, horms, ebiederm, hpa, dyoung, vgoyal

On 02/24/14 at 11:38am, Thomas Renninger wrote:
> On Thursday, February 20, 2014 05:28:28 PM WANG Chao wrote:
> > Hi, All
> > 
> > When kaslr comes in and kdump is broken, it seems about the right time to
> > use E820 instead of memmap=exactmap to pass memmap for kdump for the
> > default memmap passing mechanism:
> > http://lists.infradead.org/pipermail/kexec/2014-February/011048.html
> > 
> > Unfortunately, saved_max_pfn still got its user out there (calgry pci, it
> > looks like the only one). So for backward compatibility, I'm introducing a
> > new option --pass-memmap-cmdline to force kexec-tools to pass
> > memmap=exactmap, the old way.
> The saved_max_pfn usage is calgary pci looks bad/wrong and I wonder:
>   - whether this is still worth touching, so that the old mechanism:
>     --pass-memmap-cmdline could vanish in the one or other year and need
>     not to be carried forever
> I tried to find such a machine, but couldn't find anything mentioning calgary
> in quite some machines' dmesg.
> 
> Approaches to avoid saved_max_pfn in calgary case:
>   1) If done correctly from the beginning, the TCE table size would have
>      been exposed via /sys and kexec-tools could simply add:
>      calgary="128k|512K...|8M" which is already caught by pci-calgary and
>      saved_max_pfn is not needed/touched anymore.
>      -> Disadvantage: needs a new sysfs entry
>   2) When finding max_pfn for calgary table size usage, we could try in 
>      kdump case to use the highest memory (RAM or RESERVED) showing up
>      in e820 map.

How could this replace saved_max_pfn? The highest memory in kdump can't
necessarily be the real ram size. In kdump, RAM range is just part of the real
ram, not mentioning we don't pass RESERVED range to kdump E820.

Thanks
WANG Chao

> 
> Please find below a patch which would eleminate the last saved_max_pfn
> user. Unfortunately I could not find a calgary system to test this on.
> 
> Be aware: I could not test this.
> If someone tells me for what kind of machine (and BIOS stuff enabled?)
> I should look for, I can try to search for such a platform.
> 
> Something else: There is quite some duplicate code in kexec-tools when it
> is about retrieving the e820 table info (normal kexec vs kdump).
> Did you see my cleanups I posted long ago? Do you plan to still clean up
> a bit after this series?

Yes, I saw them and find some of them are pretty useful for this
patchset. I suppose some cleanups can be done later. Feel free to clean
up after this patchset is settled.

> 
>         Thomas
> 
> 
> 
> X86: Eliminate saved_max_pfn user in pci-calgary and remove the unused variable
> 
> Searching for the highest value of RAM and RESERVED memory in kdump case
> should be the same as max_pfn of the original kernel.
> At least this is always the case as long as type usable RAM is the highest
> entry in original e820 map.
> 
> Signed-off-by: Thomas Renninger <trenn@suse.de>
> 
> diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h
> index 779c2ef..712173e 100644
> --- a/arch/x86/include/asm/e820.h
> +++ b/arch/x86/include/asm/e820.h
> @@ -49,6 +49,7 @@ static inline void early_memtest(unsigned long start, unsigned long end)
>  #endif
>  
>  extern unsigned long e820_end_of_ram_pfn(void);
> +extern unsigned long e820_end_of_e820_pfn(void);
>  extern unsigned long e820_end_of_low_ram_pfn(void);
>  extern u64 early_reserve_e820(u64 sizet, u64 align);
>  
> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> index 988c00a..699e8fe 100644
> --- a/arch/x86/kernel/e820.c
> +++ b/arch/x86/kernel/e820.c
> @@ -757,7 +757,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
>  /*
>   * Find the highest page frame number we have available
>   */
> -static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
> +unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
>  {
>  	int i;
>  	unsigned long last_pfn = 0;
> @@ -796,6 +796,12 @@ unsigned long __init e820_end_of_ram_pfn(void)
>  	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
>  }
>  
> +unsigned long __init e820_end_of_e820_pfn(void)
> +{
> +	return max(e820_end_pfn(MAX_ARCH_PFN, E820_RAM),
> +		   e820_end_pfn(MAX_ARCH_PFN, E820_RESERVED);
> +}
> +
>  unsigned long __init e820_end_of_low_ram_pfn(void)
>  {
>  	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
> @@ -847,14 +853,6 @@ static int __init parse_memmap_one(char *p)
>  		return -EINVAL;
>  
>  	if (!strncmp(p, "exactmap", 8)) {
> -#ifdef CONFIG_CRASH_DUMP
> -		/*
> -		 * If we are doing a crash dump, we still need to know
> -		 * the real mem size before original memory map is
> -		 * reset.
> -		 */
> -		saved_max_pfn = e820_end_of_ram_pfn();
> -#endif
>  		e820.nr_map = 0;
>  		userdef = 1;
>  		return 0;
> diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
> index 299d493..89ae766 100644
> --- a/arch/x86/kernel/pci-calgary_64.c
> +++ b/arch/x86/kernel/pci-calgary_64.c
> @@ -1371,6 +1371,7 @@ int __init detect_calgary(void)
>  	unsigned long ptr;
>  	unsigned int offset, prev_offset;
>  	int ret;
> +	unsigned long orig_max_pfn = max_pfn;
>  
>  	/*
>  	 * if the user specified iommu=off or iommu=soft or we found
> @@ -1418,8 +1419,10 @@ int __init detect_calgary(void)
>  		return -ENOMEM;
>  	}
>  
> -	specified_table_size = determine_tce_table_size((is_kdump_kernel() ?
> -					saved_max_pfn : max_pfn) * PAGE_SIZE);
> +	if (is_kdump_kernel())
> +		orig_max_pfn = e820_end_of_e820_pfn();
> +	specified_table_size = determine_tce_table_size(orig_max_pfn
> +							* PAGE_SIZE);
>  
>  	for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
>  		struct calgary_bus_info *info = &bus_info[bus];
> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> index 7032518..bce4d97 100644
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -87,5 +87,4 @@ extern void unregister_oldmem_pfn_is_ram(void);
>  static inline int is_kdump_kernel(void) { return 0; }
>  #endif /* CONFIG_CRASH_DUMP */
>  
> -extern unsigned long saved_max_pfn;
>  #endif /* LINUX_CRASHDUMP_H */
> diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
> index c766ee5..9d50486 100644
> --- a/kernel/crash_dump.c
> +++ b/kernel/crash_dump.c
> @@ -5,12 +5,6 @@
>  #include <linux/export.h>
>  
>  /*
> - * If we have booted due to a crash, max_pfn will be a very low value. We need
> - * to know the amount of memory that the previous kernel used.
> - */
> -unsigned long saved_max_pfn;
> -
> -/*
>   * stores the physical address of elf header of crash image
>   *
>   * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 14:58   ` WANG Chao
@ 2014-02-24 15:03     ` H. Peter Anvin
  2014-02-24 15:11       ` Vivek Goyal
  2014-02-24 15:22     ` Vivek Goyal
  1 sibling, 1 reply; 19+ messages in thread
From: H. Peter Anvin @ 2014-02-24 15:03 UTC (permalink / raw)
  To: WANG Chao, Thomas Renninger; +Cc: kexec, horms, dyoung, ebiederm, vgoyal

First question is if Calgary even exists anymore and if so if someone actually cares about it enough to maintain it.

On February 24, 2014 6:58:41 AM PST, WANG Chao <chaowang@redhat.com> wrote:
>On 02/24/14 at 11:38am, Thomas Renninger wrote:
>> On Thursday, February 20, 2014 05:28:28 PM WANG Chao wrote:
>> > Hi, All
>> > 
>> > When kaslr comes in and kdump is broken, it seems about the right
>time to
>> > use E820 instead of memmap=exactmap to pass memmap for kdump for
>the
>> > default memmap passing mechanism:
>> >
>http://lists.infradead.org/pipermail/kexec/2014-February/011048.html
>> > 
>> > Unfortunately, saved_max_pfn still got its user out there (calgry
>pci, it
>> > looks like the only one). So for backward compatibility, I'm
>introducing a
>> > new option --pass-memmap-cmdline to force kexec-tools to pass
>> > memmap=exactmap, the old way.
>> The saved_max_pfn usage is calgary pci looks bad/wrong and I wonder:
>>   - whether this is still worth touching, so that the old mechanism:
>>     --pass-memmap-cmdline could vanish in the one or other year and
>need
>>     not to be carried forever
>> I tried to find such a machine, but couldn't find anything mentioning
>calgary
>> in quite some machines' dmesg.
>> 
>> Approaches to avoid saved_max_pfn in calgary case:
>>   1) If done correctly from the beginning, the TCE table size would
>have
>>      been exposed via /sys and kexec-tools could simply add:
>>      calgary="128k|512K...|8M" which is already caught by pci-calgary
>and
>>      saved_max_pfn is not needed/touched anymore.
>>      -> Disadvantage: needs a new sysfs entry
>>   2) When finding max_pfn for calgary table size usage, we could try
>in 
>>      kdump case to use the highest memory (RAM or RESERVED) showing
>up
>>      in e820 map.
>
>How could this replace saved_max_pfn? The highest memory in kdump can't
>necessarily be the real ram size. In kdump, RAM range is just part of
>the real
>ram, not mentioning we don't pass RESERVED range to kdump E820.
>
>Thanks
>WANG Chao
>
>> 
>> Please find below a patch which would eleminate the last
>saved_max_pfn
>> user. Unfortunately I could not find a calgary system to test this
>on.
>> 
>> Be aware: I could not test this.
>> If someone tells me for what kind of machine (and BIOS stuff
>enabled?)
>> I should look for, I can try to search for such a platform.
>> 
>> Something else: There is quite some duplicate code in kexec-tools
>when it
>> is about retrieving the e820 table info (normal kexec vs kdump).
>> Did you see my cleanups I posted long ago? Do you plan to still clean
>up
>> a bit after this series?
>
>Yes, I saw them and find some of them are pretty useful for this
>patchset. I suppose some cleanups can be done later. Feel free to clean
>up after this patchset is settled.
>
>> 
>>         Thomas
>> 
>> 
>> 
>> X86: Eliminate saved_max_pfn user in pci-calgary and remove the
>unused variable
>> 
>> Searching for the highest value of RAM and RESERVED memory in kdump
>case
>> should be the same as max_pfn of the original kernel.
>> At least this is always the case as long as type usable RAM is the
>highest
>> entry in original e820 map.
>> 
>> Signed-off-by: Thomas Renninger <trenn@suse.de>
>> 
>> diff --git a/arch/x86/include/asm/e820.h
>b/arch/x86/include/asm/e820.h
>> index 779c2ef..712173e 100644
>> --- a/arch/x86/include/asm/e820.h
>> +++ b/arch/x86/include/asm/e820.h
>> @@ -49,6 +49,7 @@ static inline void early_memtest(unsigned long
>start, unsigned long end)
>>  #endif
>>  
>>  extern unsigned long e820_end_of_ram_pfn(void);
>> +extern unsigned long e820_end_of_e820_pfn(void);
>>  extern unsigned long e820_end_of_low_ram_pfn(void);
>>  extern u64 early_reserve_e820(u64 sizet, u64 align);
>>  
>> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
>> index 988c00a..699e8fe 100644
>> --- a/arch/x86/kernel/e820.c
>> +++ b/arch/x86/kernel/e820.c
>> @@ -757,7 +757,7 @@ u64 __init early_reserve_e820(u64 size, u64
>align)
>>  /*
>>   * Find the highest page frame number we have available
>>   */
>> -static unsigned long __init e820_end_pfn(unsigned long limit_pfn,
>unsigned type)
>> +unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned
>type)
>>  {
>>  	int i;
>>  	unsigned long last_pfn = 0;
>> @@ -796,6 +796,12 @@ unsigned long __init e820_end_of_ram_pfn(void)
>>  	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
>>  }
>>  
>> +unsigned long __init e820_end_of_e820_pfn(void)
>> +{
>> +	return max(e820_end_pfn(MAX_ARCH_PFN, E820_RAM),
>> +		   e820_end_pfn(MAX_ARCH_PFN, E820_RESERVED);
>> +}
>> +
>>  unsigned long __init e820_end_of_low_ram_pfn(void)
>>  {
>>  	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
>> @@ -847,14 +853,6 @@ static int __init parse_memmap_one(char *p)
>>  		return -EINVAL;
>>  
>>  	if (!strncmp(p, "exactmap", 8)) {
>> -#ifdef CONFIG_CRASH_DUMP
>> -		/*
>> -		 * If we are doing a crash dump, we still need to know
>> -		 * the real mem size before original memory map is
>> -		 * reset.
>> -		 */
>> -		saved_max_pfn = e820_end_of_ram_pfn();
>> -#endif
>>  		e820.nr_map = 0;
>>  		userdef = 1;
>>  		return 0;
>> diff --git a/arch/x86/kernel/pci-calgary_64.c
>b/arch/x86/kernel/pci-calgary_64.c
>> index 299d493..89ae766 100644
>> --- a/arch/x86/kernel/pci-calgary_64.c
>> +++ b/arch/x86/kernel/pci-calgary_64.c
>> @@ -1371,6 +1371,7 @@ int __init detect_calgary(void)
>>  	unsigned long ptr;
>>  	unsigned int offset, prev_offset;
>>  	int ret;
>> +	unsigned long orig_max_pfn = max_pfn;
>>  
>>  	/*
>>  	 * if the user specified iommu=off or iommu=soft or we found
>> @@ -1418,8 +1419,10 @@ int __init detect_calgary(void)
>>  		return -ENOMEM;
>>  	}
>>  
>> -	specified_table_size = determine_tce_table_size((is_kdump_kernel()
>?
>> -					saved_max_pfn : max_pfn) * PAGE_SIZE);
>> +	if (is_kdump_kernel())
>> +		orig_max_pfn = e820_end_of_e820_pfn();
>> +	specified_table_size = determine_tce_table_size(orig_max_pfn
>> +							* PAGE_SIZE);
>>  
>>  	for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
>>  		struct calgary_bus_info *info = &bus_info[bus];
>> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
>> index 7032518..bce4d97 100644
>> --- a/include/linux/crash_dump.h
>> +++ b/include/linux/crash_dump.h
>> @@ -87,5 +87,4 @@ extern void unregister_oldmem_pfn_is_ram(void);
>>  static inline int is_kdump_kernel(void) { return 0; }
>>  #endif /* CONFIG_CRASH_DUMP */
>>  
>> -extern unsigned long saved_max_pfn;
>>  #endif /* LINUX_CRASHDUMP_H */
>> diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
>> index c766ee5..9d50486 100644
>> --- a/kernel/crash_dump.c
>> +++ b/kernel/crash_dump.c
>> @@ -5,12 +5,6 @@
>>  #include <linux/export.h>
>>  
>>  /*
>> - * If we have booted due to a crash, max_pfn will be a very low
>value. We need
>> - * to know the amount of memory that the previous kernel used.
>> - */
>> -unsigned long saved_max_pfn;
>> -
>> -/*
>>   * stores the physical address of elf header of crash image
>>   *
>>   * Note: elfcorehdr_addr is not just limited to vmcore. It is also
>used by
>> 

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:03     ` H. Peter Anvin
@ 2014-02-24 15:11       ` Vivek Goyal
  2014-02-24 15:24         ` Vivek Goyal
  0 siblings, 1 reply; 19+ messages in thread
From: Vivek Goyal @ 2014-02-24 15:11 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: muli, kexec, horms, ebiederm, jdmason, dyoung, Thomas Renninger,
	WANG Chao

On Mon, Feb 24, 2014 at 07:03:07AM -0800, H. Peter Anvin wrote:
> First question is if Calgary even exists anymore and if so if someone actually cares about it enough to maintain it.

Atleast MAINTAINERS file says it is maintained.

CALGARY x86-64 IOMMU
M:      Muli Ben-Yehuda <muli@il.ibm.com>
M:      "Jon D. Mason" <jdmason@kudzu.us>
L:      discuss@x86-64.org
S:      Maintained
F:      arch/x86/kernel/pci-calgary_64.c
F:      arch/x86/kernel/tce_64.c
F:      arch/x86/include/asm/calgary.h
F:      arch/x86/include/asm/tce.h


I am add maintainers to CC list and they can shed more light on if
calgary still exists and if somebody actually cares about it.

Thanks
Vivek
> 
> On February 24, 2014 6:58:41 AM PST, WANG Chao <chaowang@redhat.com> wrote:
> >On 02/24/14 at 11:38am, Thomas Renninger wrote:
> >> On Thursday, February 20, 2014 05:28:28 PM WANG Chao wrote:
> >> > Hi, All
> >> > 
> >> > When kaslr comes in and kdump is broken, it seems about the right
> >time to
> >> > use E820 instead of memmap=exactmap to pass memmap for kdump for
> >the
> >> > default memmap passing mechanism:
> >> >
> >http://lists.infradead.org/pipermail/kexec/2014-February/011048.html
> >> > 
> >> > Unfortunately, saved_max_pfn still got its user out there (calgry
> >pci, it
> >> > looks like the only one). So for backward compatibility, I'm
> >introducing a
> >> > new option --pass-memmap-cmdline to force kexec-tools to pass
> >> > memmap=exactmap, the old way.
> >> The saved_max_pfn usage is calgary pci looks bad/wrong and I wonder:
> >>   - whether this is still worth touching, so that the old mechanism:
> >>     --pass-memmap-cmdline could vanish in the one or other year and
> >need
> >>     not to be carried forever
> >> I tried to find such a machine, but couldn't find anything mentioning
> >calgary
> >> in quite some machines' dmesg.
> >> 
> >> Approaches to avoid saved_max_pfn in calgary case:
> >>   1) If done correctly from the beginning, the TCE table size would
> >have
> >>      been exposed via /sys and kexec-tools could simply add:
> >>      calgary="128k|512K...|8M" which is already caught by pci-calgary
> >and
> >>      saved_max_pfn is not needed/touched anymore.
> >>      -> Disadvantage: needs a new sysfs entry
> >>   2) When finding max_pfn for calgary table size usage, we could try
> >in 
> >>      kdump case to use the highest memory (RAM or RESERVED) showing
> >up
> >>      in e820 map.
> >
> >How could this replace saved_max_pfn? The highest memory in kdump can't
> >necessarily be the real ram size. In kdump, RAM range is just part of
> >the real
> >ram, not mentioning we don't pass RESERVED range to kdump E820.
> >
> >Thanks
> >WANG Chao
> >
> >> 
> >> Please find below a patch which would eleminate the last
> >saved_max_pfn
> >> user. Unfortunately I could not find a calgary system to test this
> >on.
> >> 
> >> Be aware: I could not test this.
> >> If someone tells me for what kind of machine (and BIOS stuff
> >enabled?)
> >> I should look for, I can try to search for such a platform.
> >> 
> >> Something else: There is quite some duplicate code in kexec-tools
> >when it
> >> is about retrieving the e820 table info (normal kexec vs kdump).
> >> Did you see my cleanups I posted long ago? Do you plan to still clean
> >up
> >> a bit after this series?
> >
> >Yes, I saw them and find some of them are pretty useful for this
> >patchset. I suppose some cleanups can be done later. Feel free to clean
> >up after this patchset is settled.
> >
> >> 
> >>         Thomas
> >> 
> >> 
> >> 
> >> X86: Eliminate saved_max_pfn user in pci-calgary and remove the
> >unused variable
> >> 
> >> Searching for the highest value of RAM and RESERVED memory in kdump
> >case
> >> should be the same as max_pfn of the original kernel.
> >> At least this is always the case as long as type usable RAM is the
> >highest
> >> entry in original e820 map.
> >> 
> >> Signed-off-by: Thomas Renninger <trenn@suse.de>
> >> 
> >> diff --git a/arch/x86/include/asm/e820.h
> >b/arch/x86/include/asm/e820.h
> >> index 779c2ef..712173e 100644
> >> --- a/arch/x86/include/asm/e820.h
> >> +++ b/arch/x86/include/asm/e820.h
> >> @@ -49,6 +49,7 @@ static inline void early_memtest(unsigned long
> >start, unsigned long end)
> >>  #endif
> >>  
> >>  extern unsigned long e820_end_of_ram_pfn(void);
> >> +extern unsigned long e820_end_of_e820_pfn(void);
> >>  extern unsigned long e820_end_of_low_ram_pfn(void);
> >>  extern u64 early_reserve_e820(u64 sizet, u64 align);
> >>  
> >> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
> >> index 988c00a..699e8fe 100644
> >> --- a/arch/x86/kernel/e820.c
> >> +++ b/arch/x86/kernel/e820.c
> >> @@ -757,7 +757,7 @@ u64 __init early_reserve_e820(u64 size, u64
> >align)
> >>  /*
> >>   * Find the highest page frame number we have available
> >>   */
> >> -static unsigned long __init e820_end_pfn(unsigned long limit_pfn,
> >unsigned type)
> >> +unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned
> >type)
> >>  {
> >>  	int i;
> >>  	unsigned long last_pfn = 0;
> >> @@ -796,6 +796,12 @@ unsigned long __init e820_end_of_ram_pfn(void)
> >>  	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
> >>  }
> >>  
> >> +unsigned long __init e820_end_of_e820_pfn(void)
> >> +{
> >> +	return max(e820_end_pfn(MAX_ARCH_PFN, E820_RAM),
> >> +		   e820_end_pfn(MAX_ARCH_PFN, E820_RESERVED);
> >> +}
> >> +
> >>  unsigned long __init e820_end_of_low_ram_pfn(void)
> >>  {
> >>  	return e820_end_pfn(1UL<<(32 - PAGE_SHIFT), E820_RAM);
> >> @@ -847,14 +853,6 @@ static int __init parse_memmap_one(char *p)
> >>  		return -EINVAL;
> >>  
> >>  	if (!strncmp(p, "exactmap", 8)) {
> >> -#ifdef CONFIG_CRASH_DUMP
> >> -		/*
> >> -		 * If we are doing a crash dump, we still need to know
> >> -		 * the real mem size before original memory map is
> >> -		 * reset.
> >> -		 */
> >> -		saved_max_pfn = e820_end_of_ram_pfn();
> >> -#endif
> >>  		e820.nr_map = 0;
> >>  		userdef = 1;
> >>  		return 0;
> >> diff --git a/arch/x86/kernel/pci-calgary_64.c
> >b/arch/x86/kernel/pci-calgary_64.c
> >> index 299d493..89ae766 100644
> >> --- a/arch/x86/kernel/pci-calgary_64.c
> >> +++ b/arch/x86/kernel/pci-calgary_64.c
> >> @@ -1371,6 +1371,7 @@ int __init detect_calgary(void)
> >>  	unsigned long ptr;
> >>  	unsigned int offset, prev_offset;
> >>  	int ret;
> >> +	unsigned long orig_max_pfn = max_pfn;
> >>  
> >>  	/*
> >>  	 * if the user specified iommu=off or iommu=soft or we found
> >> @@ -1418,8 +1419,10 @@ int __init detect_calgary(void)
> >>  		return -ENOMEM;
> >>  	}
> >>  
> >> -	specified_table_size = determine_tce_table_size((is_kdump_kernel()
> >?
> >> -					saved_max_pfn : max_pfn) * PAGE_SIZE);
> >> +	if (is_kdump_kernel())
> >> +		orig_max_pfn = e820_end_of_e820_pfn();
> >> +	specified_table_size = determine_tce_table_size(orig_max_pfn
> >> +							* PAGE_SIZE);
> >>  
> >>  	for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) {
> >>  		struct calgary_bus_info *info = &bus_info[bus];
> >> diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h
> >> index 7032518..bce4d97 100644
> >> --- a/include/linux/crash_dump.h
> >> +++ b/include/linux/crash_dump.h
> >> @@ -87,5 +87,4 @@ extern void unregister_oldmem_pfn_is_ram(void);
> >>  static inline int is_kdump_kernel(void) { return 0; }
> >>  #endif /* CONFIG_CRASH_DUMP */
> >>  
> >> -extern unsigned long saved_max_pfn;
> >>  #endif /* LINUX_CRASHDUMP_H */
> >> diff --git a/kernel/crash_dump.c b/kernel/crash_dump.c
> >> index c766ee5..9d50486 100644
> >> --- a/kernel/crash_dump.c
> >> +++ b/kernel/crash_dump.c
> >> @@ -5,12 +5,6 @@
> >>  #include <linux/export.h>
> >>  
> >>  /*
> >> - * If we have booted due to a crash, max_pfn will be a very low
> >value. We need
> >> - * to know the amount of memory that the previous kernel used.
> >> - */
> >> -unsigned long saved_max_pfn;
> >> -
> >> -/*
> >>   * stores the physical address of elf header of crash image
> >>   *
> >>   * Note: elfcorehdr_addr is not just limited to vmcore. It is also
> >used by
> >> 
> 
> -- 
> Sent from my mobile phone.  Please pardon brevity and lack of formatting.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 14:58   ` WANG Chao
  2014-02-24 15:03     ` H. Peter Anvin
@ 2014-02-24 15:22     ` Vivek Goyal
  2014-02-24 15:27       ` H. Peter Anvin
  2014-02-24 15:34       ` Thomas Renninger
  1 sibling, 2 replies; 19+ messages in thread
From: Vivek Goyal @ 2014-02-24 15:22 UTC (permalink / raw)
  To: WANG Chao; +Cc: jdmason, kexec, horms, ebiederm, hpa, dyoung, Thomas Renninger

On Mon, Feb 24, 2014 at 10:58:41PM +0800, WANG Chao wrote:
[..]
> > Approaches to avoid saved_max_pfn in calgary case:
> >   1) If done correctly from the beginning, the TCE table size would have
> >      been exposed via /sys and kexec-tools could simply add:
> >      calgary="128k|512K...|8M" which is already caught by pci-calgary and
> >      saved_max_pfn is not needed/touched anymore.
> >      -> Disadvantage: needs a new sysfs entry
> >   2) When finding max_pfn for calgary table size usage, we could try in 
> >      kdump case to use the highest memory (RAM or RESERVED) showing up
> >      in e820 map.
> 
> How could this replace saved_max_pfn? The highest memory in kdump can't
> necessarily be the real ram size. In kdump, RAM range is just part of the real
> ram, not mentioning we don't pass RESERVED range to kdump E820.

I vaguely remember there was some discussion about passing first kerne's
RAM as special reserved ranges. Say E820_RESERVED_KDUMP. And use that
to figure out saved_max_pfn.

I personally feel that just create a new command line parameter
"saved_max_pfn" and pass it to second kernel and be done with it. Modify
calgary code to first look for saved_max_pfn and if not present, calculate
saved_max_pfn from e820.

saved_max_pfn command line option is pretty ugly, not sure what are the
better options here.

Thanks
Vivek

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:11       ` Vivek Goyal
@ 2014-02-24 15:24         ` Vivek Goyal
  2014-02-24 15:28           ` H. Peter Anvin
  0 siblings, 1 reply; 19+ messages in thread
From: Vivek Goyal @ 2014-02-24 15:24 UTC (permalink / raw)
  To: jdmason
  Cc: kexec, horms, ebiederm, H. Peter Anvin, dyoung, Thomas Renninger,
	WANG Chao

On Mon, Feb 24, 2014 at 10:11:03AM -0500, Vivek Goyal wrote:
> On Mon, Feb 24, 2014 at 07:03:07AM -0800, H. Peter Anvin wrote:
> > First question is if Calgary even exists anymore and if so if someone actually cares about it enough to maintain it.
> 
> Atleast MAINTAINERS file says it is maintained.
> 
> CALGARY x86-64 IOMMU
> M:      Muli Ben-Yehuda <muli@il.ibm.com>
> M:      "Jon D. Mason" <jdmason@kudzu.us>
> L:      discuss@x86-64.org
> S:      Maintained
> F:      arch/x86/kernel/pci-calgary_64.c
> F:      arch/x86/kernel/tce_64.c
> F:      arch/x86/include/asm/calgary.h
> F:      arch/x86/include/asm/tce.h
> 
> 
> I am add maintainers to CC list and they can shed more light on if
> calgary still exists and if somebody actually cares about it.

Jon,

Muli's mail is bouncing. Is he still maintaining calgary and is his
mail id still valid as mentioned in MAINTAINERS entry above.

Thanks
Vivek

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:22     ` Vivek Goyal
@ 2014-02-24 15:27       ` H. Peter Anvin
  2014-02-24 15:34       ` Thomas Renninger
  1 sibling, 0 replies; 19+ messages in thread
From: H. Peter Anvin @ 2014-02-24 15:27 UTC (permalink / raw)
  To: Vivek Goyal, WANG Chao
  Cc: kexec, horms, ebiederm, jdmason, dyoung, Thomas Renninger

I would like to see if there is any actual use for it before doing anything else.  The Calgary code may just be off.

On February 24, 2014 7:22:05 AM PST, Vivek Goyal <vgoyal@redhat.com> wrote:
>On Mon, Feb 24, 2014 at 10:58:41PM +0800, WANG Chao wrote:
>[..]
>> > Approaches to avoid saved_max_pfn in calgary case:
>> >   1) If done correctly from the beginning, the TCE table size would
>have
>> >      been exposed via /sys and kexec-tools could simply add:
>> >      calgary="128k|512K...|8M" which is already caught by
>pci-calgary and
>> >      saved_max_pfn is not needed/touched anymore.
>> >      -> Disadvantage: needs a new sysfs entry
>> >   2) When finding max_pfn for calgary table size usage, we could
>try in 
>> >      kdump case to use the highest memory (RAM or RESERVED) showing
>up
>> >      in e820 map.
>> 
>> How could this replace saved_max_pfn? The highest memory in kdump
>can't
>> necessarily be the real ram size. In kdump, RAM range is just part of
>the real
>> ram, not mentioning we don't pass RESERVED range to kdump E820.
>
>I vaguely remember there was some discussion about passing first
>kerne's
>RAM as special reserved ranges. Say E820_RESERVED_KDUMP. And use that
>to figure out saved_max_pfn.
>
>I personally feel that just create a new command line parameter
>"saved_max_pfn" and pass it to second kernel and be done with it.
>Modify
>calgary code to first look for saved_max_pfn and if not present,
>calculate
>saved_max_pfn from e820.
>
>saved_max_pfn command line option is pretty ugly, not sure what are the
>better options here.
>
>Thanks
>Vivek

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:24         ` Vivek Goyal
@ 2014-02-24 15:28           ` H. Peter Anvin
  0 siblings, 0 replies; 19+ messages in thread
From: H. Peter Anvin @ 2014-02-24 15:28 UTC (permalink / raw)
  To: Vivek Goyal, jdmason
  Cc: kexec, horms, ebiederm, dyoung, Thomas Renninger, WANG Chao

I think Muli had moved on a while ago.

On February 24, 2014 7:24:27 AM PST, Vivek Goyal <vgoyal@redhat.com> wrote:
>On Mon, Feb 24, 2014 at 10:11:03AM -0500, Vivek Goyal wrote:
>> On Mon, Feb 24, 2014 at 07:03:07AM -0800, H. Peter Anvin wrote:
>> > First question is if Calgary even exists anymore and if so if
>someone actually cares about it enough to maintain it.
>> 
>> Atleast MAINTAINERS file says it is maintained.
>> 
>> CALGARY x86-64 IOMMU
>> M:      Muli Ben-Yehuda <muli@il.ibm.com>
>> M:      "Jon D. Mason" <jdmason@kudzu.us>
>> L:      discuss@x86-64.org
>> S:      Maintained
>> F:      arch/x86/kernel/pci-calgary_64.c
>> F:      arch/x86/kernel/tce_64.c
>> F:      arch/x86/include/asm/calgary.h
>> F:      arch/x86/include/asm/tce.h
>> 
>> 
>> I am add maintainers to CC list and they can shed more light on if
>> calgary still exists and if somebody actually cares about it.
>
>Jon,
>
>Muli's mail is bouncing. Is he still maintaining calgary and is his
>mail id still valid as mentioned in MAINTAINERS entry above.
>
>Thanks
>Vivek

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:22     ` Vivek Goyal
  2014-02-24 15:27       ` H. Peter Anvin
@ 2014-02-24 15:34       ` Thomas Renninger
  2014-02-24 15:45         ` Vivek Goyal
  1 sibling, 1 reply; 19+ messages in thread
From: Thomas Renninger @ 2014-02-24 15:34 UTC (permalink / raw)
  To: Vivek Goyal; +Cc: jdmason, kexec, horms, ebiederm, hpa, dyoung, WANG Chao

On Monday, February 24, 2014 10:22:05 AM Vivek Goyal wrote:
> On Mon, Feb 24, 2014 at 10:58:41PM +0800, WANG Chao wrote:
> [..]
> 
> > > Approaches to avoid saved_max_pfn in calgary case:
> > >   1) If done correctly from the beginning, the TCE table size would have
> > >   
> > >      been exposed via /sys and kexec-tools could simply add:
> > >      calgary="128k|512K...|8M" which is already caught by pci-calgary
> > >      and
> > >      saved_max_pfn is not needed/touched anymore.
> > >      -> Disadvantage: needs a new sysfs entry
> > >   
> > >   2) When finding max_pfn for calgary table size usage, we could try in
> > >   
> > >      kdump case to use the highest memory (RAM or RESERVED) showing up
> > >      in e820 map.
> > 
> > How could this replace saved_max_pfn? The highest memory in kdump can't
> > necessarily be the real ram size. In kdump, RAM range is just part of the
> > real ram, not mentioning we don't pass RESERVED range to kdump E820.
I expected you pass RAM that must not be used as RESERVED. Then, still 
depending on which mem type is the last one, it might have worked.
 
> I vaguely remember there was some discussion about passing first kerne's
> RAM as special reserved ranges. Say E820_RESERVED_KDUMP. And use that
> to figure out saved_max_pfn.
> 
> I personally feel that just create a new command line parameter
> "saved_max_pfn" and pass it to second kernel and be done with it. Modify
> calgary code to first look for saved_max_pfn and if not present, calculate
> saved_max_pfn from e820.
> 
> saved_max_pfn command line option is pretty ugly, not sure what are the
> better options here.

It should be done like that:

The specified_table_size variable must be exported via sysfs.
If kexec-tools finds it existing it can pass in the table size via
boot param:
calgary=
(compare with calgary_parse_options() in arch/x86/kernel/pci-calgary_64.c).

Then the table size detection (for which saved_max_pfn is needed) would
fall off in kdump case.

If this really is supported/relevant, I can send something, but it
would need kexec-tools code as well.

          Thomas

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:34       ` Thomas Renninger
@ 2014-02-24 15:45         ` Vivek Goyal
  2014-02-24 15:50           ` H. Peter Anvin
  0 siblings, 1 reply; 19+ messages in thread
From: Vivek Goyal @ 2014-02-24 15:45 UTC (permalink / raw)
  To: Thomas Renninger; +Cc: jdmason, kexec, horms, ebiederm, hpa, dyoung, WANG Chao

On Mon, Feb 24, 2014 at 04:34:26PM +0100, Thomas Renninger wrote:

[..]
> > > How could this replace saved_max_pfn? The highest memory in kdump can't
> > > necessarily be the real ram size. In kdump, RAM range is just part of the
> > > real ram, not mentioning we don't pass RESERVED range to kdump E820.
> I expected you pass RAM that must not be used as RESERVED. Then, still 
> depending on which mem type is the last one, it might have worked.

No we don't. There is a proposal though to pass first kernel's reserved
ranges to second kernel as SGI folks need that somehow.

Thanks
Vivek

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:45         ` Vivek Goyal
@ 2014-02-24 15:50           ` H. Peter Anvin
  2014-02-24 15:59             ` Vivek Goyal
  0 siblings, 1 reply; 19+ messages in thread
From: H. Peter Anvin @ 2014-02-24 15:50 UTC (permalink / raw)
  To: Vivek Goyal, Thomas Renninger
  Cc: kexec, horms, ebiederm, jdmason, dyoung, WANG Chao

Not just SGI, I don't think. You definitely need to do this.

On February 24, 2014 7:45:19 AM PST, Vivek Goyal <vgoyal@redhat.com> wrote:
>On Mon, Feb 24, 2014 at 04:34:26PM +0100, Thomas Renninger wrote:
>
>[..]
>> > > How could this replace saved_max_pfn? The highest memory in kdump
>can't
>> > > necessarily be the real ram size. In kdump, RAM range is just
>part of the
>> > > real ram, not mentioning we don't pass RESERVED range to kdump
>E820.
>> I expected you pass RAM that must not be used as RESERVED. Then,
>still 
>> depending on which mem type is the last one, it might have worked.
>
>No we don't. There is a proposal though to pass first kernel's reserved
>ranges to second kernel as SGI folks need that somehow.
>
>Thanks
>Vivek

-- 
Sent from my mobile phone.  Please pardon brevity and lack of formatting.

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump
  2014-02-24 15:50           ` H. Peter Anvin
@ 2014-02-24 15:59             ` Vivek Goyal
  0 siblings, 0 replies; 19+ messages in thread
From: Vivek Goyal @ 2014-02-24 15:59 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: kexec, horms, ebiederm, jdmason, dyoung, Thomas Renninger, WANG Chao

On Mon, Feb 24, 2014 at 07:50:19AM -0800, H. Peter Anvin wrote:
> Not just SGI, I don't think. You definitely need to do this.

Ok. Once we have resolved the calgary issue and merged the patches
where kdump memory ranges are passed in bootparams, we can take care
of passing reserved ranges too. One thing at a time.

Solving calgary issue is important though as this has been blocking
new patches for quite some time now.

Thanks
Vivek

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/4] x86: Pass memory range via E820 for kdump
  2014-02-20  9:28 ` [PATCH v2 4/4] x86: Pass memory range via E820 for kdump WANG Chao
@ 2014-02-27 20:53   ` Linn Crosetto
  2014-02-28  8:32     ` WANG Chao
  0 siblings, 1 reply; 19+ messages in thread
From: Linn Crosetto @ 2014-02-27 20:53 UTC (permalink / raw)
  To: WANG Chao; +Cc: kexec, horms, ebiederm, hpa, dyoung, trenn, vgoyal

Hi Chao,

On Thu, Feb 20, 2014 at 02:28:32AM -0700, WANG Chao wrote:

[..]

> +static void setup_e820_ext(struct kexec_info *info, struct x86_linux_param_header *real_mode,
> +                          struct memory_range *range, int nr_range)
> +{
> +       struct setup_data *sd;
> +       struct e820entry *e820;
> +       int i, j, nr_range_ext;
> +
> +       nr_range_ext = nr_range - E820MAX;
> +       sd = malloc(sizeof(struct setup_data) + nr_range_ext * sizeof(struct e820entry));
> +       sd->next = 0;
> +       sd->len = nr_range_ext * sizeof(struct e820entry);
> +       sd->type = SETUP_E820_EXT;
> +
> +       e820 = (struct e820entry *) sd->data;
> +       dbgprintf("Extended E820 via setup_data:\n");
> +       for(i = 0, j = E820MAX; i < nr_range_ext; i++, j++) {
> +               e820[i].addr = range[j].start;
> +               e820[i].size = range[j].end - range[j].start;
> +               switch (range[j].type) {
> +               case RANGE_RAM:
> +                       e820[i].type = E820_RAM;
> +                       break;
> +               case RANGE_ACPI:
> +                       e820[i].type = E820_ACPI;
> +                       break;
> +               case RANGE_ACPI_NVS:
> +                       e820[i].type = E820_NVS;
> +                       break;
> +               default:
> +               case RANGE_RESERVED:
> +                       e820[i].type = E820_RESERVED;
> +                       break;
> +               }
> +               dbgprintf("%016lx-%016lx (%d)\n",
> +                               e820[i].addr,
> +                               e820[i].addr + e820[i].size - 1,
> +                               e820[i].type);
> +
> +               if (range[j].type != RANGE_RAM)
> +                       continue;
> +               if ((range[j].start <= 0x100000) && range[j].end > 0x100000) {
> +                       unsigned long long mem_k = (range[j].end >> 10) - (0x100000 >> 10);
> +                       real_mode->ext_mem_k = mem_k;
> +                       real_mode->alt_mem_k = mem_k;
> +                       if (mem_k > 0xfc00) {
> +                               real_mode->ext_mem_k = 0xfc00; /* 64M */
> +                       }
> +                       if (mem_k > 0xffffffff) {
> +                               real_mode->alt_mem_k = 0xffffffff;
> +                       }
> +               }
> +       }
> +       add_setup_data(info, real_mode, sd);
> +       free(sd);

Remove this call to free(sd) or the kernel will not boot if there are more than
E820MAX entries.

> +}
> +
> +static void setup_e820(struct kexec_info *info, struct x86_linux_param_header *real_mode,
> +                      struct memory_range *range, int nr_range)
> +{
> +
> +       int nr_range_saved = nr_range;
> +       int i;
> +
> +       if (nr_range > E820MAX) {
> +               nr_range = E820MAX;
> +       }
> +
> +       real_mode->e820_map_nr = nr_range;
> +       dbgprintf("E820 memmap:\n");
> +       for(i = 0; i < nr_range; i++) {
> +               real_mode->e820_map[i].addr = range[i].start;
> +               real_mode->e820_map[i].size = range[i].end - range[i].start;
> +               switch (range[i].type) {
> +                       case RANGE_RAM:
> +                               real_mode->e820_map[i].type = E820_RAM;
> +                               break;
> +                       case RANGE_ACPI:
> +                               real_mode->e820_map[i].type = E820_ACPI;
> +                               break;
> +                       case RANGE_ACPI_NVS:
> +                               real_mode->e820_map[i].type = E820_NVS;
> +                               break;
> +                       default:
> +                       case RANGE_RESERVED:
> +                               real_mode->e820_map[i].type = E820_RESERVED;
> +                               break;
> +               }
> +               dbgprintf("%016lx-%016lx (%d)\n",
> +                               real_mode->e820_map[i].addr,
> +                               real_mode->e820_map[i].addr + real_mode->e820_map[i].size - 1,
> +                               real_mode->e820_map[i].type);
> +
> +               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 >> 10);
> +                       real_mode->ext_mem_k = mem_k;
> +                       real_mode->alt_mem_k = mem_k;
> +                       if (mem_k > 0xfc00) {
> +                               real_mode->ext_mem_k = 0xfc00; /* 64M */
> +                       }
> +                       if (mem_k > 0xffffffff) {
> +                               real_mode->alt_mem_k = 0xffffffff;
> +                       }
> +               }
> +       }
> +
> +       if (nr_range_saved > E820MAX) {
> +               dbgprintf("extra E820 memmap are passed via setup_data\n");
> +               setup_e820_ext(info, real_mode, range, nr_range_saved);
> +       }
> +}
> +

setup_e820() and setup_e820_ext() contain a lot of duplication. You could
combine them into a single function, similar to the implementation of
setup_e820() in the kernel.

>  static int
>  get_efi_mem_desc_version(struct x86_linux_param_header *real_mode)
>  {
> @@ -704,7 +830,7 @@ void setup_linux_system_parameters(struct kexec_info *info,

[..]

> +       if (info->kexec_flags & KEXEC_ON_CRASH && !pass_memmap_cmdline) {
> +               range = crash_memory_range;
> +               ranges = crash_memory_ranges;
> +       } else {
> +               range = info->memory_range;
> +               ranges = info->memory_ranges;
>         }

You can move this code into setup_e820(), since range and ranges are not used
elsewhere in setup_linux_system_parameters().

> +       setup_e820(info, real_mode, range, ranges);
> 
>         /* fill the EDD information */
>         setup_edd_info(real_mode);
> --
> 1.8.5.3

I tested boot (with the above fix) on a system with a large memory map, and can
easily test changes, if needed.

Thanks,
Linn

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 4/4] x86: Pass memory range via E820 for kdump
  2014-02-27 20:53   ` Linn Crosetto
@ 2014-02-28  8:32     ` WANG Chao
  0 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-02-28  8:32 UTC (permalink / raw)
  To: Linn Crosetto; +Cc: kexec, horms, ebiederm, hpa, dyoung, trenn, vgoyal

On 02/27/14 at 01:53pm, Linn Crosetto wrote:
> Hi Chao,
> 
> On Thu, Feb 20, 2014 at 02:28:32AM -0700, WANG Chao wrote:
> 
> [..]
> 
> > +static void setup_e820_ext(struct kexec_info *info, struct x86_linux_param_header *real_mode,
> > +                          struct memory_range *range, int nr_range)
> > +{
> > +       struct setup_data *sd;
> > +       struct e820entry *e820;
> > +       int i, j, nr_range_ext;
> > +
> > +       nr_range_ext = nr_range - E820MAX;
> > +       sd = malloc(sizeof(struct setup_data) + nr_range_ext * sizeof(struct e820entry));
> > +       sd->next = 0;
> > +       sd->len = nr_range_ext * sizeof(struct e820entry);
> > +       sd->type = SETUP_E820_EXT;
> > +
> > +       e820 = (struct e820entry *) sd->data;
> > +       dbgprintf("Extended E820 via setup_data:\n");
> > +       for(i = 0, j = E820MAX; i < nr_range_ext; i++, j++) {
> > +               e820[i].addr = range[j].start;
> > +               e820[i].size = range[j].end - range[j].start;
> > +               switch (range[j].type) {
> > +               case RANGE_RAM:
> > +                       e820[i].type = E820_RAM;
> > +                       break;
> > +               case RANGE_ACPI:
> > +                       e820[i].type = E820_ACPI;
> > +                       break;
> > +               case RANGE_ACPI_NVS:
> > +                       e820[i].type = E820_NVS;
> > +                       break;
> > +               default:
> > +               case RANGE_RESERVED:
> > +                       e820[i].type = E820_RESERVED;
> > +                       break;
> > +               }
> > +               dbgprintf("%016lx-%016lx (%d)\n",
> > +                               e820[i].addr,
> > +                               e820[i].addr + e820[i].size - 1,
> > +                               e820[i].type);
> > +
> > +               if (range[j].type != RANGE_RAM)
> > +                       continue;
> > +               if ((range[j].start <= 0x100000) && range[j].end > 0x100000) {
> > +                       unsigned long long mem_k = (range[j].end >> 10) - (0x100000 >> 10);
> > +                       real_mode->ext_mem_k = mem_k;
> > +                       real_mode->alt_mem_k = mem_k;
> > +                       if (mem_k > 0xfc00) {
> > +                               real_mode->ext_mem_k = 0xfc00; /* 64M */
> > +                       }
> > +                       if (mem_k > 0xffffffff) {
> > +                               real_mode->alt_mem_k = 0xffffffff;
> > +                       }
> > +               }
> > +       }
> > +       add_setup_data(info, real_mode, sd);
> > +       free(sd);
> 
> Remove this call to free(sd) or the kernel will not boot if there are more than
> E820MAX entries.

You're right.

> 
> > +}
> > +
> > +static void setup_e820(struct kexec_info *info, struct x86_linux_param_header *real_mode,
> > +                      struct memory_range *range, int nr_range)
> > +{
> > +
> > +       int nr_range_saved = nr_range;
> > +       int i;
> > +
> > +       if (nr_range > E820MAX) {
> > +               nr_range = E820MAX;
> > +       }
> > +
> > +       real_mode->e820_map_nr = nr_range;
> > +       dbgprintf("E820 memmap:\n");
> > +       for(i = 0; i < nr_range; i++) {
> > +               real_mode->e820_map[i].addr = range[i].start;
> > +               real_mode->e820_map[i].size = range[i].end - range[i].start;
> > +               switch (range[i].type) {
> > +                       case RANGE_RAM:
> > +                               real_mode->e820_map[i].type = E820_RAM;
> > +                               break;
> > +                       case RANGE_ACPI:
> > +                               real_mode->e820_map[i].type = E820_ACPI;
> > +                               break;
> > +                       case RANGE_ACPI_NVS:
> > +                               real_mode->e820_map[i].type = E820_NVS;
> > +                               break;
> > +                       default:
> > +                       case RANGE_RESERVED:
> > +                               real_mode->e820_map[i].type = E820_RESERVED;
> > +                               break;
> > +               }
> > +               dbgprintf("%016lx-%016lx (%d)\n",
> > +                               real_mode->e820_map[i].addr,
> > +                               real_mode->e820_map[i].addr + real_mode->e820_map[i].size - 1,
> > +                               real_mode->e820_map[i].type);
> > +
> > +               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 >> 10);
> > +                       real_mode->ext_mem_k = mem_k;
> > +                       real_mode->alt_mem_k = mem_k;
> > +                       if (mem_k > 0xfc00) {
> > +                               real_mode->ext_mem_k = 0xfc00; /* 64M */
> > +                       }
> > +                       if (mem_k > 0xffffffff) {
> > +                               real_mode->alt_mem_k = 0xffffffff;
> > +                       }
> > +               }
> > +       }
> > +
> > +       if (nr_range_saved > E820MAX) {
> > +               dbgprintf("extra E820 memmap are passed via setup_data\n");
> > +               setup_e820_ext(info, real_mode, range, nr_range_saved);
> > +       }
> > +}
> > +
> 
> setup_e820() and setup_e820_ext() contain a lot of duplication. You could
> combine them into a single function, similar to the implementation of
> setup_e820() in the kernel.

OK. That makes sense to me.

> 
> >  static int
> >  get_efi_mem_desc_version(struct x86_linux_param_header *real_mode)
> >  {
> > @@ -704,7 +830,7 @@ void setup_linux_system_parameters(struct kexec_info *info,
> 
> [..]
> 
> > +       if (info->kexec_flags & KEXEC_ON_CRASH && !pass_memmap_cmdline) {
> > +               range = crash_memory_range;
> > +               ranges = crash_memory_ranges;
> > +       } else {
> > +               range = info->memory_range;
> > +               ranges = info->memory_ranges;
> >         }
> 
> You can move this code into setup_e820(), since range and ranges are not used
> elsewhere in setup_linux_system_parameters().

Will do.

> 
> > +       setup_e820(info, real_mode, range, ranges);
> > 
> >         /* fill the EDD information */
> >         setup_edd_info(real_mode);
> > --
> > 1.8.5.3
> 
> I tested boot (with the above fix) on a system with a large memory map, and can
> easily test changes, if needed.

Thanks for testing. The result on that real system is helpful and convincing.

I'm holding off v3 for serveral days in case someone would have a
comment.

Thanks
WANG Chao

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2014-02-28  8:33 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-20  9:28 [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
2014-02-20  9:28 ` [PATCH v2 1/4] cleanup: add dbgprint_mem_range function WANG Chao
2014-02-20  9:28 ` [PATCH v2 2/4] x86: Store memory ranges globally used for crash kernel to boot into WANG Chao
2014-02-20  9:28 ` [PATCH v2 3/4] x86: add --pass-memmap-cmdline option WANG Chao
2014-02-20  9:28 ` [PATCH v2 4/4] x86: Pass memory range via E820 for kdump WANG Chao
2014-02-27 20:53   ` Linn Crosetto
2014-02-28  8:32     ` WANG Chao
2014-02-24 10:38 ` [PATCH v2 0/4] kexec-tools, x86: E820 memmap pass " Thomas Renninger
2014-02-24 14:58   ` WANG Chao
2014-02-24 15:03     ` H. Peter Anvin
2014-02-24 15:11       ` Vivek Goyal
2014-02-24 15:24         ` Vivek Goyal
2014-02-24 15:28           ` H. Peter Anvin
2014-02-24 15:22     ` Vivek Goyal
2014-02-24 15:27       ` H. Peter Anvin
2014-02-24 15:34       ` Thomas Renninger
2014-02-24 15:45         ` Vivek Goyal
2014-02-24 15:50           ` H. Peter Anvin
2014-02-24 15:59             ` Vivek Goyal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.