提交 133760dd 编写于 作者: L Li Huafei 提交者: openeuler-sync-bot

arm64: kdump: Avoid reserving low memory repeatedly

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I6Y5Y1

-------------------------------

We call reserve_crashkernel_high() before map_mem() to reserve high
memory in advance, which in turn can avoid using page level mapping for
all memory above 4G to optimize performance. And after
reserve_crashkernel_high(), reserve_crashkernel_low() is also needed to
reserve low memory. But when the system RAM is less than 4G, the memory
reserved by reserve_crashkernel_high() is already low memory (less than
4G), reserve_crashkernel_low() may reserve low memory again and the
memory it reserves may be higher than that reserved by
reserve_crashkernel_high(). Looking at /proc/iomem would have:

 # cat /proc/iomem | grep -i crash
    65400000-953fffff : Crash kernel  ==> crashk_res
    a7800000-b77fffff : Crash kernel  ==> crashk_res_low

At this point kexec-tools will incorrectly use the second memory segment
for the kdump kernel image load, causing the kernel load address check
to fail during kexec load (see sanity_check_segment_list()).

When the memory reserved by reserve_crashkernel_high() meets the low
memory requirement, reserve_crashkernel_low() is no longer called to
reserve memory and avoid introducing problems with duplicate
reservations.

Fixes: baac34dd ("arm64: kdump: Use page-level mapping for the high memory of crashkernel")
Signed-off-by: NLi Huafei <lihuafei1@huawei.com>
Reviewed-by: NYang Jihong <yangjihong1@huawei.com>
(cherry picked from commit e5c9d379)
上级 c4fb2bc6
......@@ -440,6 +440,13 @@ static void __init free_reserved_high_mem(void)
memblock_free(crashk_res_high.start, resource_size(&crashk_res_high));
}
static bool __init within_low_mem(unsigned long long crash_base,
unsigned long long crash_size)
{
return crash_base < CRASH_ADDR_LOW_MAX &&
CRASH_ADDR_LOW_MAX - crash_base >= crash_size;
}
/*
* reserve_crashkernel() - reserves memory for crash kernel
*
......@@ -469,6 +476,8 @@ void __init reserve_crashkernel(void)
if (crash_high_mem_reserved) {
take_reserved_high_mem(&crash_base, &crash_size);
if (within_low_mem(crash_base, crash_size))
goto reserve_ok;
goto reserve_low;
}
}
......@@ -490,6 +499,8 @@ void __init reserve_crashkernel(void)
CRASH_ALIGN);
if (!crash_base && crash_high_mem_reserved) {
take_reserved_high_mem(&crash_base, &crash_size);
if (within_low_mem(crash_base, crash_size))
goto reserve_ok;
goto reserve_low;
}
}
......@@ -539,6 +550,7 @@ void __init reserve_crashkernel(void)
free_reserved_high_mem();
}
reserve_ok:
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
(unsigned long)(crash_size >> 20),
(unsigned long)(crash_base >> 20),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册