|
@@ -938,6 +938,13 @@ static int __init init_machine_late(void)
|
|
|
late_initcall(init_machine_late);
|
|
|
|
|
|
#ifdef CONFIG_KEXEC
|
|
|
+/*
|
|
|
+ * The crash region must be aligned to 128MB to avoid
|
|
|
+ * zImage relocating below the reserved region.
|
|
|
+ */
|
|
|
+#define CRASH_ALIGN (128 << 20)
|
|
|
+#define CRASH_ADDR_MAX (PHYS_OFFSET + (512 << 20))
|
|
|
+
|
|
|
static inline unsigned long long get_total_mem(void)
|
|
|
{
|
|
|
unsigned long total;
|
|
@@ -965,6 +972,28 @@ static void __init reserve_crashkernel(void)
|
|
|
if (ret)
|
|
|
return;
|
|
|
|
|
|
+ if (crash_base <= 0) {
|
|
|
+ unsigned long long crash_max = CRASH_ADDR_MAX;
|
|
|
+ if (crash_max > (u32)~0)
|
|
|
+ crash_max = (u32)~0;
|
|
|
+ crash_base = memblock_find_in_range(CRASH_ALIGN, crash_max,
|
|
|
+ crash_size, CRASH_ALIGN);
|
|
|
+ if (!crash_base) {
|
|
|
+ pr_err("crashkernel reservation failed - No suitable area found.\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ unsigned long long start;
|
|
|
+
|
|
|
+ start = memblock_find_in_range(crash_base,
|
|
|
+ crash_base + crash_size,
|
|
|
+ crash_size, SECTION_SIZE);
|
|
|
+ if (start != crash_base) {
|
|
|
+ pr_err("crashkernel reservation failed - memory is in use.\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
ret = memblock_reserve(crash_base, crash_size);
|
|
|
if (ret < 0) {
|
|
|
pr_warn("crashkernel reservation failed - memory is in use (0x%lx)\n",
|