Hello,
I tried to reproduce the issue in a i386 qemu VM and think I found something.

Function is_crashkernel_mem_reserved tries to search for the start
and end of the crashkernel reserved memory area.

This is done by calling kexec_iomem_for_each_line and given a callback
function as parameter.

Unfortunately the expected function prototype and the given function
differ slightly (you see once long long):


the expected:
    int kexec_iomem_for_each_line(char *match,
                      int (*callback)(void *data,
                              int nr,
                              char *str,
                              unsigned long long base,
                              unsigned long long length),
                      void *data)

and the given:
    static int crashkernel_mem_callback(void *UNUSED(data), int nr,
                                              char *UNUSED(str),
                                              unsigned long base,
                                              unsigned long length)


This seems to be an upstream regression introduced in this commit [1].
There only one architecture dependent callback is changed.
And otherwise only i386 and sh seem to use kexec_iomem_for_each_line.
(The compiler would have warned of it [2].)

Attached is a patch which I think should fix the issue.
(At least no error message from the "kexec -p" or
"kdump-config load" commands anymore.)


Kind regards,
Bernhard





[1] 
https://git.kernel.org/cgit/utils/kernel/kexec/kexec-tools.git/commit/?id=4362bfaca4d8d2a4380532880f0d08c2bf14184e



[2]
Warning from the dpkg-buildpackage:

kexec/arch/i386/crashdump-x86.c:1073:7: warning: passing argument 2 of 
‘kexec_iomem_for_each_line’ from incompatible pointer type
       crashkernel_mem_callback, NULL);
       ^
In file included from kexec/arch/i386/crashdump-x86.c:38:0:
kexec/arch/i386/../../kexec.h:281:5: note: expected ‘int (*)(void *, int,  char 
*, long long unsigned int,  long long unsigned int)’ but argument is of type 
‘int (*)(void *, int,  char *, long unsigned int,  long unsigned int)’
 int kexec_iomem_for_each_line(char *match,
     ^



Steps to reproduce:
mkdir ~/debian/kexec; cd ~/debian/kexec
apt-get source kexec-tools
cd kexec-tools-2.0.7/
dpkg-buildpackage
sed -i 's/-g -O2/-g -O0/g' Makefile
make clean all
su
    gdb --args ./build/sbin/kexec -p 
'--command-line=BOOT_IMAGE=/boot/vmlinuz-3.16.0-4-686-pae 
root=UUID=6d06248a-7f13-40f2-952b-3b6a1d0752d2 ro vga=788 quiet irqpoll 
maxcpus=1 nousb systemd.unit=kdump-tools.service' 
--initrd=/boot/initrd.img-3.16.0-4-686-pae /boot/vmlinuz-3.16.0-4-686-pae
        (gdb) b crashkernel_mem_callback
        Breakpoint 1 at 0x8059f62: file kexec/arch/i386/crashdump-x86.c, line 
1047.
        (gdb) run
        Starting program: 
/home/benutzer/debian/kexec/kexec/unmod/kexec-tools-2.0.7/build/sbin/kexec -p 
--command-line=BOOT_IMAGE=/boot/vmlinuz-3.16.0-4-686-pae\ 
root=UUID=6d06248a-7f13-40f2-952b-3b6a1d0752d2\ ro\ vga=788\ quiet\ irqpoll\ 
maxcpus=1\ nousb\ systemd.unit=kdump-tools.service 
--initrd=/boot/initrd.img-3.16.0-4-686-pae /boot/vmlinuz-3.16.0-4-686-pae

        Breakpoint 1, crashkernel_mem_callback (UNUSED_data=0x0, nr=0, 
UNUSED_str=0xbffff462 "Crash kernel\n", base=50331648, length=0) at 
kexec/arch/i386/crashdump-x86.c:1047
        1047            if (nr >= CRASH_RESERVED_MEM_NR)

        (gdb) print base
        $1 = 50331648
        (gdb) print length
        $2 = 0

        (gdb) up
        #1  0x0804f8fd in kexec_iomem_for_each_line (match=0x8063d21 "Crash 
kernel\n", callback=0x8059f5e <crashkernel_mem_callback>, data=0x0) at 
kexec/kexec-iomem.c:54
        54                                  && callback(data, nr, str, start, 
size) < 0) {

        (gdb) print start
        $3 = 50331648
        (gdb) print size
        $4 = 134217728
Description: Fix callback functions given to kexec_iomem_for_each_line
Author: Bernhard Übelacker <bernha...@vr-web.de>
Bug-Debian: https://bugs.debian.org/771671
Last-Update: <2014-12-15>

--- kexec-tools-2.0.7.orig/kexec/arch/i386/crashdump-x86.c
+++ kexec-tools-2.0.7/kexec/arch/i386/crashdump-x86.c
@@ -1041,8 +1041,8 @@ int get_max_crash_kernel_limit(uint64_t
 
 static int crashkernel_mem_callback(void *UNUSED(data), int nr,
                                           char *UNUSED(str),
-                                          unsigned long base,
-                                          unsigned long length)
+                                          unsigned long long base,
+                                          unsigned long long length)
 {
 	if (nr >= CRASH_RESERVED_MEM_NR)
 		return 1;
--- kexec-tools-2.0.7.orig/kexec/arch/sh/crashdump-sh.c
+++ kexec-tools-2.0.7/kexec/arch/sh/crashdump-sh.c
@@ -34,8 +34,8 @@ static struct memory_range crash_memory_
 static int crash_sh_range_nr;
 static int crash_sh_memory_range_callback(void *UNUSED(data), int UNUSED(nr),
 					  char *str,
-					  unsigned long base,
-					  unsigned long length)
+					  unsigned long long base,
+					  unsigned long long length)
 {
 
 	struct memory_range *range = crash_memory_range;
--- kexec-tools-2.0.7.orig/kexec/arch/sh/kexec-sh.c
+++ kexec-tools-2.0.7/kexec/arch/sh/kexec-sh.c
@@ -24,8 +24,8 @@ static struct memory_range memory_range[
 
 static int kexec_sh_memory_range_callback(void *UNUSED(data), int nr,
 					  char *UNUSED(str),
-					  unsigned long base,
-					  unsigned long length)
+					  unsigned long long base,
+					  unsigned long long length)
 {
 	if (nr < MAX_MEMORY_RANGES) {
 		memory_range[nr].start = base;

Reply via email to