All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] kexec-tools, x86: E820 memmap pass for kdump
@ 2014-03-10 15:09 WANG Chao
  2014-03-10 15:09 ` [PATCH v3 1/4] cleanup: add dbgprint_mem_range function WANG Chao
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: WANG Chao @ 2014-03-10 15:09 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung, linn; +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!

v2->v3:
Linn: do not free sd (setup_data) buffer

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      | 171 ++++++++++++++++++++++-----------
 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, 231 insertions(+), 133 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 v3 1/4] cleanup: add dbgprint_mem_range function
  2014-03-10 15:09 [PATCH v3 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
@ 2014-03-10 15:09 ` WANG Chao
  2014-03-10 15:09 ` [PATCH v3 2/4] x86: Store memory ranges globally used for crash kernel to boot into WANG Chao
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-03-10 15:09 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung, linn; +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 v3 2/4] x86: Store memory ranges globally used for crash kernel to boot into
  2014-03-10 15:09 [PATCH v3 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
  2014-03-10 15:09 ` [PATCH v3 1/4] cleanup: add dbgprint_mem_range function WANG Chao
@ 2014-03-10 15:09 ` WANG Chao
  2014-03-10 15:09 ` [PATCH v3 3/4] x86: add --pass-memmap-cmdline option WANG Chao
  2014-03-10 15:09 ` [PATCH v3 4/4] x86: Pass memory range via E820 for kdump WANG Chao
  3 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-03-10 15:09 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung, linn; +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 v3 3/4] x86: add --pass-memmap-cmdline option
  2014-03-10 15:09 [PATCH v3 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
  2014-03-10 15:09 ` [PATCH v3 1/4] cleanup: add dbgprint_mem_range function WANG Chao
  2014-03-10 15:09 ` [PATCH v3 2/4] x86: Store memory ranges globally used for crash kernel to boot into WANG Chao
@ 2014-03-10 15:09 ` WANG Chao
  2014-03-10 15:09 ` [PATCH v3 4/4] x86: Pass memory range via E820 for kdump WANG Chao
  3 siblings, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-03-10 15:09 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung, linn; +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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-10 15:09 [PATCH v3 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
                   ` (2 preceding siblings ...)
  2014-03-10 15:09 ` [PATCH v3 3/4] x86: add --pass-memmap-cmdline option WANG Chao
@ 2014-03-10 15:09 ` WANG Chao
  2014-03-13 22:24   ` Linn Crosetto
  3 siblings, 1 reply; 19+ messages in thread
From: WANG Chao @ 2014-03-10 15:09 UTC (permalink / raw)
  To: horms, vgoyal, ebiederm, hpa, trenn, dyoung, linn; +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 | 171 +++++++++++++++++++++++++-------------
 3 files changed, 130 insertions(+), 67 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..e630366 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,98 @@ out:
 	return ret;
 }
 
+static void add_e820_map_from_mr(struct x86_linux_param_header *real_mode,
+			struct e820entry *e820, struct memory_range *range, int nr_range)
+{
+	int i;
+
+	for (i = 0; i < nr_range; i++) {
+		e820[i].addr = range[i].start;
+		e820[i].size = range[i].end - range[i].start;
+		switch (range[i].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[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;
+			}
+		}
+	}
+}
+
+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 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");
+	add_e820_map_from_mr(real_mode, e820, range + E820MAX, nr_range_ext);
+	add_setup_data(info, real_mode, sd);
+}
+
+static void setup_e820(struct kexec_info *info, struct x86_linux_param_header *real_mode)
+{
+	struct memory_range *range;
+	int nr_range, nr_range_saved;
+
+
+	if (info->kexec_flags & KEXEC_ON_CRASH && !pass_memmap_cmdline) {
+		range = crash_memory_range;
+		nr_range = crash_memory_ranges;
+	} else {
+		range = info->memory_range;
+		nr_range = info->memory_ranges;
+	}
+
+	nr_range_saved = nr_range;
+	if (nr_range > E820MAX) {
+		nr_range = E820MAX;
+	}
+
+	real_mode->e820_map_nr = nr_range;
+	dbgprintf("E820 memmap:\n");
+	add_e820_map_from_mr(real_mode, real_mode->e820_map, range, nr_range);
+
+	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)
 {
@@ -702,10 +807,6 @@ static void setup_efi_info(struct kexec_info *info,
 void setup_linux_system_parameters(struct kexec_info *info,
 				   struct x86_linux_param_header *real_mode)
 {
-	/* Fill in information the BIOS would usually provide */
-	struct memory_range *range;
-	int i, ranges;
-
 	/* get subarch from running kernel */
 	setup_subarch(real_mode);
 	if (bzImage_support_efi_boot)
@@ -746,51 +847,7 @@ 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;
-			}
-		}
-	}
+	setup_e820(info, real_mode);
 
 	/* 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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-10 15:09 ` [PATCH v3 4/4] x86: Pass memory range via E820 for kdump WANG Chao
@ 2014-03-13 22:24   ` Linn Crosetto
  2014-03-14  2:47       ` Dave Young
  2014-03-14  3:49     ` WANG Chao
  0 siblings, 2 replies; 19+ messages in thread
From: Linn Crosetto @ 2014-03-13 22:24 UTC (permalink / raw)
  To: WANG Chao; +Cc: kexec, horms, ebiederm, hpa, dyoung, trenn, vgoyal

Wang Chao,

On Mon, Mar 10, 2014 at 11:09:09PM +0800, WANG Chao wrote:
> 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 | 171 +++++++++++++++++++++++++-------------
>  3 files changed, 130 insertions(+), 67 deletions(-)
> 

[..]

> +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 nr_range_ext;
> +
> +	nr_range_ext = nr_range - E820MAX;
> +	sd = malloc(sizeof(struct setup_data) + nr_range_ext * sizeof(struct e820entry));

You might check the return value from malloc().

> +	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");
> +	add_e820_map_from_mr(real_mode, e820, range + E820MAX, nr_range_ext);
> +	add_setup_data(info, real_mode, sd);
> +}

[..]

I tested on a prototype system with 231 entries in the map with good results.
Everything succeeds when using kexec to initiate a fast reboot. For crash, it
works with and without --pass-memmap-cmdline when using noefi. I hit the
following panic when initiating a crash leaving EFI enabled in the crash kernel:

 ? __unmap_pmd_range+0x77/0x190
 unmap_pmd_range+0xcf/0x1c0
 populate_pgd+0x16d/0x250
 __cpa_process_fault+0x15/0xb0
 __change_page_attr+0x15e/0x2a0
 __change_page_attr_set_clr+0x59/0xc0
 kernel_map_pages_in_pgd+0x7a/0xb0
 __map_region+0x46/0x64
 ? early_idt_handlers+0x117/0x120
 efi_map_region_fixed+0xd/0xf
 efi_enter_virtual_mode+0x4c/0x476
 ? early_idt_handlers+0x117/0x120
 ? early_idt_handlers+0x117/0x120
 start_kernel+0x2e5/0x376
 ? repair_env_string+0x5b/0x5b
 ? memblock_reserve+0x49/0x4e
 x86_64_start_reservations+0x2a/0x2c
 x86_64_start_kernel+0x19f/0x1ae

However, I was able to reproduce this panic using an earlier version of
kexec-tools, so I believe it is unrelated to this patch.

For this patch:

Reviewed-by: Linn Crosetto <linn@hp.com>

For the series:

Tested-by: Linn Crosetto <linn@hp.com>

_______________________________________________
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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-13 22:24   ` Linn Crosetto
@ 2014-03-14  2:47       ` Dave Young
  2014-03-14  3:49     ` WANG Chao
  1 sibling, 0 replies; 19+ messages in thread
From: Dave Young @ 2014-03-14  2:47 UTC (permalink / raw)
  To: Linn Crosetto
  Cc: WANG Chao, kexec, horms, ebiederm, hpa, trenn, vgoyal, matt, bp,
	toshi.kani, dyoung, linux-kernel

> [..]
> 
> I tested on a prototype system with 231 entries in the map with good results.
> Everything succeeds when using kexec to initiate a fast reboot. For crash, it
> works with and without --pass-memmap-cmdline when using noefi. I hit the
> following panic when initiating a crash leaving EFI enabled in the crash kernel:
> 
>  ? __unmap_pmd_range+0x77/0x190
>  unmap_pmd_range+0xcf/0x1c0
>  populate_pgd+0x16d/0x250
>  __cpa_process_fault+0x15/0xb0
>  __change_page_attr+0x15e/0x2a0
>  __change_page_attr_set_clr+0x59/0xc0
>  kernel_map_pages_in_pgd+0x7a/0xb0
>  __map_region+0x46/0x64
>  ? early_idt_handlers+0x117/0x120
>  efi_map_region_fixed+0xd/0xf
>  efi_enter_virtual_mode+0x4c/0x476
>  ? early_idt_handlers+0x117/0x120
>  ? early_idt_handlers+0x117/0x120
>  start_kernel+0x2e5/0x376
>  ? repair_env_string+0x5b/0x5b
>  ? memblock_reserve+0x49/0x4e
>  x86_64_start_reservations+0x2a/0x2c
>  x86_64_start_kernel+0x19f/0x1ae
> 
> However, I was able to reproduce this panic using an earlier version of
> kexec-tools, so I believe it is unrelated to this patch.

Can you test with matt's tree to see if it works?
If it still happens please post the full log.

Thanks
Dave

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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
@ 2014-03-14  2:47       ` Dave Young
  0 siblings, 0 replies; 19+ messages in thread
From: Dave Young @ 2014-03-14  2:47 UTC (permalink / raw)
  To: Linn Crosetto
  Cc: matt, toshi.kani, kexec, linux-kernel, vgoyal, horms, bp,
	ebiederm, hpa, dyoung, trenn, WANG Chao

> [..]
> 
> I tested on a prototype system with 231 entries in the map with good results.
> Everything succeeds when using kexec to initiate a fast reboot. For crash, it
> works with and without --pass-memmap-cmdline when using noefi. I hit the
> following panic when initiating a crash leaving EFI enabled in the crash kernel:
> 
>  ? __unmap_pmd_range+0x77/0x190
>  unmap_pmd_range+0xcf/0x1c0
>  populate_pgd+0x16d/0x250
>  __cpa_process_fault+0x15/0xb0
>  __change_page_attr+0x15e/0x2a0
>  __change_page_attr_set_clr+0x59/0xc0
>  kernel_map_pages_in_pgd+0x7a/0xb0
>  __map_region+0x46/0x64
>  ? early_idt_handlers+0x117/0x120
>  efi_map_region_fixed+0xd/0xf
>  efi_enter_virtual_mode+0x4c/0x476
>  ? early_idt_handlers+0x117/0x120
>  ? early_idt_handlers+0x117/0x120
>  start_kernel+0x2e5/0x376
>  ? repair_env_string+0x5b/0x5b
>  ? memblock_reserve+0x49/0x4e
>  x86_64_start_reservations+0x2a/0x2c
>  x86_64_start_kernel+0x19f/0x1ae
> 
> However, I was able to reproduce this panic using an earlier version of
> kexec-tools, so I believe it is unrelated to this patch.

Can you test with matt's tree to see if it works?
If it still happens please post the full log.

Thanks
Dave

_______________________________________________
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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-13 22:24   ` Linn Crosetto
  2014-03-14  2:47       ` Dave Young
@ 2014-03-14  3:49     ` WANG Chao
  1 sibling, 0 replies; 19+ messages in thread
From: WANG Chao @ 2014-03-14  3:49 UTC (permalink / raw)
  To: Linn Crosetto; +Cc: kexec, horms, ebiederm, hpa, dyoung, trenn, vgoyal

On 03/13/14 at 04:24pm, Linn Crosetto wrote:
> Wang Chao,
> 
> On Mon, Mar 10, 2014 at 11:09:09PM +0800, WANG Chao wrote:
> > 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 | 171 +++++++++++++++++++++++++-------------
> >  3 files changed, 130 insertions(+), 67 deletions(-)
> > 
> 
> [..]
> 
> > +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 nr_range_ext;
> > +
> > +	nr_range_ext = nr_range - E820MAX;
> > +	sd = malloc(sizeof(struct setup_data) + nr_range_ext * sizeof(struct e820entry));
> 
> You might check the return value from malloc().

Right.
I'll use xmalloc(), defined in kexec/kexec.h.

> 
> > +	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");
> > +	add_e820_map_from_mr(real_mode, e820, range + E820MAX, nr_range_ext);
> > +	add_setup_data(info, real_mode, sd);
> > +}
> 
> [..]
> 
> I tested on a prototype system with 231 entries in the map with good results.
> Everything succeeds when using kexec to initiate a fast reboot. For crash, it
> works with and without --pass-memmap-cmdline when using noefi. I hit the
> following panic when initiating a crash leaving EFI enabled in the crash kernel:

Good to know!

> 
>  ? __unmap_pmd_range+0x77/0x190
>  unmap_pmd_range+0xcf/0x1c0
>  populate_pgd+0x16d/0x250
>  __cpa_process_fault+0x15/0xb0
>  __change_page_attr+0x15e/0x2a0
>  __change_page_attr_set_clr+0x59/0xc0
>  kernel_map_pages_in_pgd+0x7a/0xb0
>  __map_region+0x46/0x64
>  ? early_idt_handlers+0x117/0x120
>  efi_map_region_fixed+0xd/0xf
>  efi_enter_virtual_mode+0x4c/0x476
>  ? early_idt_handlers+0x117/0x120
>  ? early_idt_handlers+0x117/0x120
>  start_kernel+0x2e5/0x376
>  ? repair_env_string+0x5b/0x5b
>  ? memblock_reserve+0x49/0x4e
>  x86_64_start_reservations+0x2a/0x2c
>  x86_64_start_kernel+0x19f/0x1ae
> 
> However, I was able to reproduce this panic using an earlier version of
> kexec-tools, so I believe it is unrelated to this patch.
> 
> For this patch:
> 
> Reviewed-by: Linn Crosetto <linn@hp.com>
> 
> For the series:
> 
> Tested-by: Linn Crosetto <linn@hp.com>

Thank you for your review and test. I really appreciate it.

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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-14  2:47       ` Dave Young
@ 2014-03-14  8:26         ` Matt Fleming
  -1 siblings, 0 replies; 19+ messages in thread
From: Matt Fleming @ 2014-03-14  8:26 UTC (permalink / raw)
  To: Dave Young
  Cc: Linn Crosetto, WANG Chao, kexec, horms, ebiederm, hpa, trenn,
	vgoyal, bp, toshi.kani, linux-kernel

On Fri, 14 Mar, at 10:47:26AM, Dave Young wrote:
> 
> Can you test with matt's tree to see if it works?
> If it still happens please post the full log.

So that'd be the 'next' branch at,

  git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git

which contains Borislav's fixes for the EFI memmap code.

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
@ 2014-03-14  8:26         ` Matt Fleming
  0 siblings, 0 replies; 19+ messages in thread
From: Matt Fleming @ 2014-03-14  8:26 UTC (permalink / raw)
  To: Dave Young
  Cc: toshi.kani, kexec, linux-kernel, vgoyal, horms, bp,
	Linn Crosetto, hpa, trenn, WANG Chao, ebiederm

On Fri, 14 Mar, at 10:47:26AM, Dave Young wrote:
> 
> Can you test with matt's tree to see if it works?
> If it still happens please post the full log.

So that'd be the 'next' branch at,

  git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git

which contains Borislav's fixes for the EFI memmap code.

-- 
Matt Fleming, Intel Open Source Technology Center

_______________________________________________
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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-14  8:26         ` Matt Fleming
@ 2014-03-14 20:27           ` Linn Crosetto
  -1 siblings, 0 replies; 19+ messages in thread
From: Linn Crosetto @ 2014-03-14 20:27 UTC (permalink / raw)
  To: Matt Fleming
  Cc: Dave Young, WANG Chao, kexec, horms, ebiederm, hpa, trenn,
	vgoyal, bp, toshi.kani, linux-kernel

On Fri, Mar 14, 2014 at 08:26:15AM +0000, Matt Fleming wrote:
> On Fri, 14 Mar, at 10:47:26AM, Dave Young wrote:
> > 
> > Can you test with matt's tree to see if it works?
> > If it still happens please post the full log.
> 
> So that'd be the 'next' branch at,
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
> 
> which contains Borislav's fixes for the EFI memmap code.

I believe I included those fixes when testing with 3.14 rc6, adding:

https://lkml.org/lkml/2014/3/8/209
92b71d8
52d201e
a52f515
b660133
e91925d

Since this testing was done on a prototype, I will send you the log in a
separate email. I tried efi.git/next (with the addition of 4ce7a86), and hit the
same panic.


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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
@ 2014-03-14 20:27           ` Linn Crosetto
  0 siblings, 0 replies; 19+ messages in thread
From: Linn Crosetto @ 2014-03-14 20:27 UTC (permalink / raw)
  To: Matt Fleming
  Cc: toshi.kani, kexec, linux-kernel, vgoyal, horms, bp, ebiederm,
	hpa, Dave Young, trenn, WANG Chao

On Fri, Mar 14, 2014 at 08:26:15AM +0000, Matt Fleming wrote:
> On Fri, 14 Mar, at 10:47:26AM, Dave Young wrote:
> > 
> > Can you test with matt's tree to see if it works?
> > If it still happens please post the full log.
> 
> So that'd be the 'next' branch at,
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git
> 
> which contains Borislav's fixes for the EFI memmap code.

I believe I included those fixes when testing with 3.14 rc6, adding:

https://lkml.org/lkml/2014/3/8/209
92b71d8
52d201e
a52f515
b660133
e91925d

Since this testing was done on a prototype, I will send you the log in a
separate email. I tried efi.git/next (with the addition of 4ce7a86), and hit the
same panic.


_______________________________________________
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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-14 20:27           ` Linn Crosetto
@ 2014-03-15 14:26             ` Borislav Petkov
  -1 siblings, 0 replies; 19+ messages in thread
From: Borislav Petkov @ 2014-03-15 14:26 UTC (permalink / raw)
  To: Linn Crosetto
  Cc: Matt Fleming, Dave Young, WANG Chao, kexec, horms, ebiederm, hpa,
	trenn, vgoyal, toshi.kani, linux-kernel

On Fri, Mar 14, 2014 at 02:27:06PM -0600, Linn Crosetto wrote:
> Since this testing was done on a prototype, I will send you the log in
> a separate email. I tried efi.git/next (with the addition of 4ce7a86),
> and hit the same panic.

Well, if the stack trace is the same:

>  ? __unmap_pmd_range+0x77/0x190
>  unmap_pmd_range+0xcf/0x1c0
>  populate_pgd+0x16d/0x250
>  __cpa_process_fault+0x15/0xb0
...

it looks like populate_pgd() fails and unmaps the whole range. You could
add some debug printks to find out exactly why populate_pgd() fails.
Also, please try to catch full dmesg and the whole oops.

Btw, Matt, your whole efi/next stuff is already in tip, right? Because
if so, Linn could simply test latest tip/master.

Thanks.

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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
@ 2014-03-15 14:26             ` Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: Borislav Petkov @ 2014-03-15 14:26 UTC (permalink / raw)
  To: Linn Crosetto
  Cc: Matt Fleming, toshi.kani, kexec, linux-kernel, vgoyal, horms,
	ebiederm, hpa, Dave Young, trenn, WANG Chao

On Fri, Mar 14, 2014 at 02:27:06PM -0600, Linn Crosetto wrote:
> Since this testing was done on a prototype, I will send you the log in
> a separate email. I tried efi.git/next (with the addition of 4ce7a86),
> and hit the same panic.

Well, if the stack trace is the same:

>  ? __unmap_pmd_range+0x77/0x190
>  unmap_pmd_range+0xcf/0x1c0
>  populate_pgd+0x16d/0x250
>  __cpa_process_fault+0x15/0xb0
...

it looks like populate_pgd() fails and unmaps the whole range. You could
add some debug printks to find out exactly why populate_pgd() fails.
Also, please try to catch full dmesg and the whole oops.

Btw, Matt, your whole efi/next stuff is already in tip, right? Because
if so, Linn could simply test latest tip/master.

Thanks.

_______________________________________________
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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-15 14:26             ` Borislav Petkov
@ 2014-03-15 14:41               ` Borislav Petkov
  -1 siblings, 0 replies; 19+ messages in thread
From: Borislav Petkov @ 2014-03-15 14:41 UTC (permalink / raw)
  To: Linn Crosetto
  Cc: Matt Fleming, Dave Young, WANG Chao, kexec, horms, ebiederm, hpa,
	trenn, vgoyal, toshi.kani, linux-kernel

On Sat, Mar 15, 2014 at 03:26:25PM +0100, Borislav Petkov wrote:
> Also, please try to catch full dmesg and the whole oops.

Ok, nevermind, I've got your mail with full dmesg in my other mbox; I'll
take a look next week.

Thanks.


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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
@ 2014-03-15 14:41               ` Borislav Petkov
  0 siblings, 0 replies; 19+ messages in thread
From: Borislav Petkov @ 2014-03-15 14:41 UTC (permalink / raw)
  To: Linn Crosetto
  Cc: Matt Fleming, toshi.kani, kexec, linux-kernel, vgoyal, horms,
	ebiederm, hpa, Dave Young, trenn, WANG Chao

On Sat, Mar 15, 2014 at 03:26:25PM +0100, Borislav Petkov wrote:
> Also, please try to catch full dmesg and the whole oops.

Ok, nevermind, I've got your mail with full dmesg in my other mbox; I'll
take a look next week.

Thanks.


_______________________________________________
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 v3 4/4] x86: Pass memory range via E820 for kdump
  2014-03-15 14:26             ` Borislav Petkov
@ 2014-03-15 14:48               ` Matt Fleming
  -1 siblings, 0 replies; 19+ messages in thread
From: Matt Fleming @ 2014-03-15 14:48 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: Linn Crosetto, Dave Young, WANG Chao, kexec, horms, ebiederm,
	hpa, trenn, vgoyal, toshi.kani, linux-kernel

On Sat, 15 Mar, at 03:26:25PM, Borislav Petkov wrote:
> 
> Btw, Matt, your whole efi/next stuff is already in tip, right? Because
> if so, Linn could simply test latest tip/master.

Yep, everything is in tip/master.

-- 
Matt Fleming, Intel Open Source Technology Center

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

* Re: [PATCH v3 4/4] x86: Pass memory range via E820 for kdump
@ 2014-03-15 14:48               ` Matt Fleming
  0 siblings, 0 replies; 19+ messages in thread
From: Matt Fleming @ 2014-03-15 14:48 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: toshi.kani, kexec, linux-kernel, vgoyal, horms, Linn Crosetto,
	hpa, Dave Young, trenn, WANG Chao, ebiederm

On Sat, 15 Mar, at 03:26:25PM, Borislav Petkov wrote:
> 
> Btw, Matt, your whole efi/next stuff is already in tip, right? Because
> if so, Linn could simply test latest tip/master.

Yep, everything is in tip/master.

-- 
Matt Fleming, Intel Open Source Technology Center

_______________________________________________
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-03-15 14:49 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-10 15:09 [PATCH v3 0/4] kexec-tools, x86: E820 memmap pass for kdump WANG Chao
2014-03-10 15:09 ` [PATCH v3 1/4] cleanup: add dbgprint_mem_range function WANG Chao
2014-03-10 15:09 ` [PATCH v3 2/4] x86: Store memory ranges globally used for crash kernel to boot into WANG Chao
2014-03-10 15:09 ` [PATCH v3 3/4] x86: add --pass-memmap-cmdline option WANG Chao
2014-03-10 15:09 ` [PATCH v3 4/4] x86: Pass memory range via E820 for kdump WANG Chao
2014-03-13 22:24   ` Linn Crosetto
2014-03-14  2:47     ` Dave Young
2014-03-14  2:47       ` Dave Young
2014-03-14  8:26       ` Matt Fleming
2014-03-14  8:26         ` Matt Fleming
2014-03-14 20:27         ` Linn Crosetto
2014-03-14 20:27           ` Linn Crosetto
2014-03-15 14:26           ` Borislav Petkov
2014-03-15 14:26             ` Borislav Petkov
2014-03-15 14:41             ` Borislav Petkov
2014-03-15 14:41               ` Borislav Petkov
2014-03-15 14:48             ` Matt Fleming
2014-03-15 14:48               ` Matt Fleming
2014-03-14  3:49     ` WANG Chao

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.