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 <[email protected]>
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;