[PATCH] kexec: ppc, ppc64: increment saved_max_mem in case firmware exports inclusive maps

HATAYAMA Daisuke d.hatayama at jp.fujitsu.com
Mon Mar 18 23:29:21 EDT 2013


There are two kinds of notation to represent a map: inclusive and
exclusive. Here are the examples:

  1)  [mem 0x0000000100000000-0x000000013fffffff]
  2)  [mem 0x0000000100000000-0x0000000140000000]

1) is inclusive and 2) is exclusive. In case of 1), the pfn calculated
from the end address belongs to the map, while in case of 2), it
doesn't.

The variable saved_max_pfn is exclusive, but the condition of sanity
check in read_oldmem() wrongly treats it as inclusive, i.e.

		if (pfn > saved_max_pfn)
			return read;

This should have been

		if (pfn >= saved_max_pfn)
			return read;

Currently, architecture mips, powerpc and s390 noticed this fact and
treat saved_max_pfn as inclusive.

$ git grep ".*saved_max_pfn.*" ./
arch/ia64/kernel/efi.c:         /* saved_max_pfn should ignore max_addr= command line arg */
arch/ia64/kernel/efi.c:         if (saved_max_pfn < (efi_md_end(md) >> PAGE_SHIFT))
arch/ia64/kernel/efi.c:                 saved_max_pfn = (efi_md_end(md) >> PAGE_SHIFT);
arch/mips/kernel/crash_dump.c:          saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
arch/powerpc/kernel/crash_dump.c:               saved_max_pfn = (memparse(p, &p) >> PAGE_SHIFT) - 1;
arch/s390/kernel/setup.c:               saved_max_pfn = PFN_DOWN(OLDMEM_BASE) - 1;
arch/s390/kernel/setup.c:               saved_max_pfn = PFN_DOWN(real_memory_size) - 1;
arch/x86/kernel/e820.c:         saved_max_pfn = e820_end_of_ram_pfn();
arch/x86/kernel/pci-calgary_64.c:                                       saved_max_pfn : max_pfn) * PAGE_SIZE);
drivers/char/mem.c:             if (pfn > saved_max_pfn)
include/linux/crash_dump.h:extern unsigned long saved_max_pfn;
kernel/crash_dump.c:unsigned long saved_max_pfn;

In kexec-tools, both mips and s390 increments the corresponding
saved_max_mem. From the above, the existing firmware for powerpc is
expected to being exporting memory mapping as exclusive. Hence, it's
possible to rewrite saved_max_pfn in kernel side uniformly so it's
treated as exclusive.

Signed-off-by: HATAYAMA Daisuke <d.hatayama at jp.fujitsu.com>
---
 kexec/arch/ppc/crashdump-powerpc.c |    2 +-
 kexec/arch/ppc64/crashdump-ppc64.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/kexec/arch/ppc/crashdump-powerpc.c b/kexec/arch/ppc/crashdump-powerpc.c
index eee5b37..1122c18 100644
--- a/kexec/arch/ppc/crashdump-powerpc.c
+++ b/kexec/arch/ppc/crashdump-powerpc.c
@@ -230,7 +230,7 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 	 */
 	for (i = 0; i < memory_ranges; i++)
 		if (saved_max_mem < crash_memory_range[i].end)
-			saved_max_mem = crash_memory_range[i].end;
+			saved_max_mem = crash_memory_range[i].end + 1;
 
 	*range = crash_memory_range;
 	*ranges = memory_ranges;
diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c
index 49cab12..743fc15 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -309,7 +309,7 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 	 */
 	for (i = 0; i < memory_ranges; i++)
 		if (saved_max_mem < crash_memory_range[i].end)
-			saved_max_mem = crash_memory_range[i].end;
+			saved_max_mem = crash_memory_range[i].end + 1;
 
 	*range = crash_memory_range;
 	*ranges = memory_ranges;
-- 
1.7.7.6





More information about the kexec mailing list