On Fri, 18 Sep 2015 08:03:24 +0200 Petr Tesarik <ptesarik at suse.com> wrote: > Hello, > > There may be more than one crash kernel regions on x86. However, the kexec > syscall checks that target address is within crashk_res boundaries. Looking > at the logic in arch/x86/kernel/setup.c, there are only two possible layouts: > > 1. crashk_res is below 4G, and there is only one region, > 2. crashk_res is above 4G, and crashk_low_res is below 4G > > In either case, kexec-tools must pick the highest region. > > Currently, kexec-tools picks the largest region. If high reservation is > smaller than low, kexec(2) returns -EADDRNOTAVAIL, and kexec prints out > this error message: > > kexec_load failed: Cannot assign requested address I have just re-checked with kexec_file(2), and it is also affected. At this point, you may think that it would be better to fix the check in sanity_check_segment_list() instead. I don't think so. Low memory reservation is intended for swiotlb and DMA buffers, i.e. it is somehow precious. The kernel can run above 4G, initrd can also be located above 4G, so why should I place it in the _precious_ low memory? If you agree, I'll also post a kernel patch for kexec_file(2). Petr T > Signed-off-by: Petr Tesarik <ptesarik at suse.com> > --- > kexec/arch/i386/crashdump-x86.c | 12 ++---------- > 1 file changed, 2 insertions(+), 10 deletions(-) > > diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c > index 63959b7..2710a9e 100644 > --- a/kexec/arch/i386/crashdump-x86.c > +++ b/kexec/arch/i386/crashdump-x86.c > @@ -1034,16 +1034,8 @@ int get_max_crash_kernel_limit(uint64_t *start, uint64_t *end) > if (!crash_reserved_mem_nr) > return -1; > > - for (i = crash_reserved_mem_nr - 1; i >= 0; i--) { > - sz = crash_reserved_mem[i].end - crash_reserved_mem[i].start +1; > - if (sz <= sz_max) > - continue; > - sz_max = sz; > - idx = i; > - } > - > - *start = crash_reserved_mem[idx].start; > - *end = crash_reserved_mem[idx].end; > + *start = crash_reserved_mem[crash_reserved_mem_nr - 1].start; > + *end = crash_reserved_mem[crash_reserved_mem_nr - 1].end; > > return 0; > }