You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.2 KiB

From f63d8530b9b6a2d7e79b946e326e5a2197eb8f87 Mon Sep 17 00:00:00 2001
From: Petr Tesarik <ptesarik@suse.com>
Date: Thu, 19 Jan 2017 18:37:09 +0100
Subject: [PATCH] ppc64: Reduce number of ELF LOAD segments
The number of program header table entries (e_phnum) is an Elf64_Half,
which is a 16-bit entity, i.e. the limit is 65534 entries (one entry is
reserved for NOTE). This is a hard limit, defined by the ELF standard.
It is possible that more LMBs (Logical Memory Blocks) are needed to
represent all RAM on some machines, and this field overflows, causing
an incomplete /proc/vmcore file.
This has actually happened on a machine with 31TB of RAM and an LMB size
of 256MB.
However, since there is usually no memory hole between adjacent LMBs, the
map can be "compressed", combining multiple adjacent into a single LOAD
segment.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Pingfan Liu <piliu@redhat.com>
---
kexec/arch/ppc64/crashdump-ppc64.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c
index b3c8928..f62b159 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -123,6 +123,7 @@ static void exclude_crash_region(uint64_t start, uint64_t end)
static int get_dyn_reconf_crash_memory_ranges(void)
{
uint64_t start, end;
+ uint64_t startrange, endrange;
char fname[128], buf[32];
FILE *file;
unsigned int i;
@@ -137,6 +138,7 @@ static int get_dyn_reconf_crash_memory_ranges(void)
}
fseek(file, 4, SEEK_SET);
+ startrange = endrange = 0;
for (i = 0; i < num_of_lmbs; i++) {
if ((n = fread(buf, 1, 24, file)) < 0) {
perror(fname);
@@ -162,8 +164,16 @@ static int get_dyn_reconf_crash_memory_ranges(void)
if ((flags & 0x80) || !(flags & 0x8))
continue;
- exclude_crash_region(start, end);
+ if (start != endrange) {
+ if (startrange != endrange)
+ exclude_crash_region(startrange, endrange);
+ startrange = start;
+ }
+ endrange = end;
}
+ if (startrange != endrange)
+ exclude_crash_region(startrange, endrange);
+
fclose(file);
return 0;
}
--
2.7.4