|
@@ -507,11 +507,14 @@ static void __init memblock_x86_reserve_range_setup_data(void)
|
|
|
/*
|
|
|
* Keep the crash kernel below this limit. On 32 bits earlier kernels
|
|
|
* would limit the kernel to the low 512 MiB due to mapping restrictions.
|
|
|
+ * On 64bit, old kexec-tools need to under 896MiB.
|
|
|
*/
|
|
|
#ifdef CONFIG_X86_32
|
|
|
-# define CRASH_KERNEL_ADDR_MAX (512 << 20)
|
|
|
+# define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20)
|
|
|
+# define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20)
|
|
|
#else
|
|
|
-# define CRASH_KERNEL_ADDR_MAX MAXMEM
|
|
|
+# define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20)
|
|
|
+# define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM
|
|
|
#endif
|
|
|
|
|
|
static void __init reserve_crashkernel_low(void)
|
|
@@ -525,6 +528,7 @@ static void __init reserve_crashkernel_low(void)
|
|
|
int ret;
|
|
|
|
|
|
total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
|
|
|
+ /* crashkernel_low=YM */
|
|
|
ret = parse_crashkernel_low(boot_command_line, total_low_mem,
|
|
|
&low_size, &base);
|
|
|
if (ret != 0) {
|
|
@@ -569,14 +573,22 @@ static void __init reserve_crashkernel(void)
|
|
|
const unsigned long long alignment = 16<<20; /* 16M */
|
|
|
unsigned long long total_mem;
|
|
|
unsigned long long crash_size, crash_base;
|
|
|
+ bool high = false;
|
|
|
int ret;
|
|
|
|
|
|
total_mem = memblock_phys_mem_size();
|
|
|
|
|
|
+ /* crashkernel=XM */
|
|
|
ret = parse_crashkernel(boot_command_line, total_mem,
|
|
|
&crash_size, &crash_base);
|
|
|
- if (ret != 0 || crash_size <= 0)
|
|
|
- return;
|
|
|
+ if (ret != 0 || crash_size <= 0) {
|
|
|
+ /* crashkernel_high=XM */
|
|
|
+ ret = parse_crashkernel_high(boot_command_line, total_mem,
|
|
|
+ &crash_size, &crash_base);
|
|
|
+ if (ret != 0 || crash_size <= 0)
|
|
|
+ return;
|
|
|
+ high = true;
|
|
|
+ }
|
|
|
|
|
|
/* 0 means: find the address automatically */
|
|
|
if (crash_base <= 0) {
|
|
@@ -584,7 +596,9 @@ static void __init reserve_crashkernel(void)
|
|
|
* kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
|
|
|
*/
|
|
|
crash_base = memblock_find_in_range(alignment,
|
|
|
- CRASH_KERNEL_ADDR_MAX, crash_size, alignment);
|
|
|
+ high ? CRASH_KERNEL_ADDR_HIGH_MAX :
|
|
|
+ CRASH_KERNEL_ADDR_LOW_MAX,
|
|
|
+ crash_size, alignment);
|
|
|
|
|
|
if (!crash_base) {
|
|
|
pr_info("crashkernel reservation failed - No suitable area found.\n");
|