separate lowmem and highmem in crashdump segments for ppc32

Yadviga yadviga at mvista.com
Fri Feb 28 06:48:43 EST 2014


Hello all
I would like to suggest the patch for ppc32 arch against kexec-2.0.5.
Could you please include it into kexec tools.

The patch separates highmem and lowmem.
Usually highmem and lowmem merges in common segment.
Virtual  addresses for this segment are invalid because code from
crashdump-elf.c set virtual address -1 for lowmem
addresses if they share segment with highmem addresses.

                 /* HIGMEM has a virtual address of -1 */

                  if (elf_info->lowmem_limit
&& (mend > (elf_info->lowmem_limit - 1)))
                          phdr->p_vaddr = -1;

The patch locates them in different segments.
So lowmem will have the valid  virtual address

This is result of gdb backtrace before applying the patch.

powerpc-montavista-linux-gnuspe-gdb vmlinux /opt/tmp/vmcore_kexec2.0.5
GNU gdb (MontaVista Linux G++ 4.7-140117041417) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i686-pc-linux-gnu
--target=powerpc-montavista-linux-gnuspe".
For bug reporting instructions, please see:
<http://support.mvista.com/>...
Reading symbols from /home/yadviga/MVL7/mvl7kernel_jan/vmlinux...done.
[New LWP 1993]
#0  0xc033c1e0 in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
138             *killer = 1;
(gdb) bt
#0  0xc033c1e0 in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
#1  0xc033ca68 in __handle_sysrq (key=99,
      key at entry=<error reading variable: Cannot access memory at address
0xcf6a5ed4>,
      check_mask=<optimized out>) at drivers/tty/sysrq.c:533
(gdb)

Here is backtrace after aapying the patch. Backtrace looks better.

powerpc-montavista-linux-gnuspe-gdb vmlinux /opt/tmp/vmcore
GNU gdb (MontaVista Linux G++ 4.7-140117041417) 7.6
...
Reading symbols from /home/yadviga/MVL7/mvl7kernel_jan/vmlinux...done.
[New LWP 1969]
#0  0xc033c1e0 in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
138             *killer = 1;
(gdb) bt
#0  0xc033c1e0 in sysrq_handle_crash (key=99) at drivers/tty/sysrq.c:138
#1  0xc033ca68 in __handle_sysrq (key=99,
check_mask=check_mask at entry=false) at drivers/tty/sysrq.c:533
#2  0xc033cb24 in write_sysrq_trigger (file=<optimized out>,
buf=<optimized out>, count=2,
      ppos=<optimized out>) at drivers/tty/sysrq.c:1030
#3  0xc0192654 in proc_reg_write (file=<optimized out>, buf=<optimized
out>, count=<optimized out>,
      ppos=<optimized out>) at fs/proc/inode.c:224
#4  0xc0135dd4 in vfs_write (file=file at entry=0xcfb2e480,
      buf=buf at entry=0x1011b408 <Address 0x1011b408 out of bounds>,
count=count at entry=2,
      pos=pos at entry=0xcf063f18) at fs/read_write.c:446
#5  0xc0136258 in SYSC_write (count=2, buf=0x1011b408 <Address
0x1011b408 out of bounds>, fd=<optimized out>)
      at fs/read_write.c:494
#6  SyS_write (fd=<optimized out>, buf=269595656, count=2) at
fs/read_write.c:487
#7  0xc000ed08 in syscall_dotrace_cont () at
arch/powerpc/kernel/entry_32.S:385
Backtrace stopped: frame did not save the PC
(gdb)

Best regards
Yadviga




-------------- next part --------------
>From f8454324a060b997b652362fdaa2f01a7c548cc0 Mon Sep 17 00:00:00 2001
From: Yadviga Grigoryeva <yadviga at mvista.com>
Date: Fri, 28 Feb 2014 00:49:59 +0400
Subject: [PATCH] separate highmem and lowmem for ppc32

The patch separates highmem and lowmem.
Usually highmem and lowmem merges in common segment.
Virtual  addresses for this segment are invalid because
 code from crashdump-elf.c set virtual address -1 for lowmem 
addresses if they share segment with highmem addresses

               /* HIGMEM has a virtual address of -1 */

                if (elf_info->lowmem_limit
                   && (mend > (elf_info->lowmem_limit - 1)))
                        phdr->p_vaddr = -1;

The patch locates them in different segments.
So lowmem will have the valid  virtual address

Signed-off-by: Yadviga Grigoryeva <yadviga at mvista.com>
---
 kexec/arch/ppc/crashdump-powerpc.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/kexec/arch/ppc/crashdump-powerpc.c b/kexec/arch/ppc/crashdump-powerpc.c
index c06d310..39a12ca 100644
--- a/kexec/arch/ppc/crashdump-powerpc.c
+++ b/kexec/arch/ppc/crashdump-powerpc.c
@@ -214,6 +214,34 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
 		crash_memory_range[memory_ranges++].end = cend;
 	}
 
+#ifndef CONFIG_PPC64
+	/* separate lowmem and highmem in segment */
+	if (memory_ranges < crash_max_memory_ranges ) {
+		int k,l;
+		for (l=0; l<memory_ranges; l++) {
+			if (crash_memory_range[l].start <
+			    elf_info32.lowmem_limit &&
+			    crash_memory_range[l].end >
+			    elf_info32.lowmem_limit) {
+				/* shift crash_memory_range */
+				for (k=memory_ranges; k>l; k--) {
+					crash_memory_range[k].start
+						= crash_memory_range[k-1].start;
+					crash_memory_range[k].end
+						= crash_memory_range[k-1].end;
+					crash_memory_range[k].type
+						= crash_memory_range[k-1].type;
+				}
+				memory_ranges++;
+				crash_memory_range[l].end
+					= elf_info32.lowmem_limit;
+				crash_memory_range[l+1].start
+					= elf_info32.lowmem_limit;
+			break;
+			}
+		}
+	}
+#endif
 	*range = crash_memory_range;
 	*ranges = memory_ranges;
 
-- 
1.6.3.3.334.gb7e98.dirty




More information about the kexec mailing list