* [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.