fadump.c (41df5928721ff4b5f83767cd5e8b77862fc62bb3) fadump.c (6abec12c65e8870d8cafe154a86240fe0bcdd4f7)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Firmware Assisted dump: A robust mechanism to get reliable kernel crash
4 * dump with assistance from firmware. This approach does not use kexec,
5 * instead firmware assists in booting the kdump kernel while preserving
6 * memory contents. The most of the code implementation has been adapted
7 * from phyp assisted dump implementation written by Linas Vepstas and
8 * Manish Ahuja

--- 324 unchanged lines hidden (view full) ---

333 pr_info("Reserved %ldMB of memory at %#016lx for saving crash dump\n",
334 (msize >> 20), mstart);
335 }
336 }
337}
338
339int __init fadump_reserve_mem(void)
340{
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Firmware Assisted dump: A robust mechanism to get reliable kernel crash
4 * dump with assistance from firmware. This approach does not use kexec,
5 * instead firmware assists in booting the kdump kernel while preserving
6 * memory contents. The most of the code implementation has been adapted
7 * from phyp assisted dump implementation written by Linas Vepstas and
8 * Manish Ahuja

--- 324 unchanged lines hidden (view full) ---

333 pr_info("Reserved %ldMB of memory at %#016lx for saving crash dump\n",
334 (msize >> 20), mstart);
335 }
336 }
337}
338
339int __init fadump_reserve_mem(void)
340{
341 unsigned long base, size, memory_boundary;
341 u64 base, size, mem_boundary;
342 int ret = 1;
342
343 if (!fw_dump.fadump_enabled)
344 return 0;
345
346 if (!fw_dump.fadump_supported) {
343
344 if (!fw_dump.fadump_enabled)
345 return 0;
346
347 if (!fw_dump.fadump_supported) {
347 printk(KERN_INFO "Firmware-assisted dump is not supported on"
348 " this hardware\n");
349 fw_dump.fadump_enabled = 0;
350 return 0;
348 pr_info("Firmware-Assisted Dump is not supported on this hardware\n");
349 goto error_out;
351 }
352 /*
353 * Initialize boot memory size
354 * If dump is active then we have already calculated the size during
355 * first kernel.
356 */
357 if (!fw_dump.dump_active) {
350 }
351 /*
352 * Initialize boot memory size
353 * If dump is active then we have already calculated the size during
354 * first kernel.
355 */
356 if (!fw_dump.dump_active) {
358 fw_dump.boot_memory_size = fadump_calculate_reserve_size();
357 fw_dump.boot_memory_size =
358 PAGE_ALIGN(fadump_calculate_reserve_size());
359#ifdef CONFIG_CMA
360 if (!fw_dump.nocma)
361 fw_dump.boot_memory_size =
362 ALIGN(fw_dump.boot_memory_size,
363 FADUMP_CMA_ALIGNMENT);
364#endif
365 }
366

--- 9 unchanged lines hidden (view full) ---

376 if ((memory_limit + size) < memblock_end_of_DRAM())
377 memory_limit += size;
378 else
379 memory_limit = memblock_end_of_DRAM();
380 printk(KERN_INFO "Adjusted memory_limit for firmware-assisted"
381 " dump, now %#016llx\n", memory_limit);
382 }
383 if (memory_limit)
359#ifdef CONFIG_CMA
360 if (!fw_dump.nocma)
361 fw_dump.boot_memory_size =
362 ALIGN(fw_dump.boot_memory_size,
363 FADUMP_CMA_ALIGNMENT);
364#endif
365 }
366

--- 9 unchanged lines hidden (view full) ---

376 if ((memory_limit + size) < memblock_end_of_DRAM())
377 memory_limit += size;
378 else
379 memory_limit = memblock_end_of_DRAM();
380 printk(KERN_INFO "Adjusted memory_limit for firmware-assisted"
381 " dump, now %#016llx\n", memory_limit);
382 }
383 if (memory_limit)
384 memory_boundary = memory_limit;
384 mem_boundary = memory_limit;
385 else
385 else
386 memory_boundary = memblock_end_of_DRAM();
386 mem_boundary = memblock_end_of_DRAM();
387
387
388 base = fw_dump.boot_memory_size;
388 size = get_fadump_area_size();
389 fw_dump.reserve_dump_area_size = size;
390 if (fw_dump.dump_active) {
391 pr_info("Firmware-assisted dump is active.\n");
392
393#ifdef CONFIG_HUGETLB_PAGE
394 /*
395 * FADump capture kernel doesn't care much about hugepages.
396 * In fact, handling hugepages in capture kernel is asking for
397 * trouble. So, disable HugeTLB support when fadump is active.
398 */
399 hugetlb_disabled = true;
400#endif
401 /*
402 * If last boot has crashed then reserve all the memory
403 * above boot_memory_size so that we don't touch it until
404 * dump is written to disk by userspace tool. This memory
405 * will be released for general use once the dump is saved.
406 */
389 size = get_fadump_area_size();
390 fw_dump.reserve_dump_area_size = size;
391 if (fw_dump.dump_active) {
392 pr_info("Firmware-assisted dump is active.\n");
393
394#ifdef CONFIG_HUGETLB_PAGE
395 /*
396 * FADump capture kernel doesn't care much about hugepages.
397 * In fact, handling hugepages in capture kernel is asking for
398 * trouble. So, disable HugeTLB support when fadump is active.
399 */
400 hugetlb_disabled = true;
401#endif
402 /*
403 * If last boot has crashed then reserve all the memory
404 * above boot_memory_size so that we don't touch it until
405 * dump is written to disk by userspace tool. This memory
406 * will be released for general use once the dump is saved.
407 */
407 base = fw_dump.boot_memory_size;
408 size = memory_boundary - base;
408 size = mem_boundary - base;
409 fadump_reserve_crash_area(base, size);
410
411 pr_debug("fadumphdr_addr = %#016lx\n", fw_dump.fadumphdr_addr);
412 pr_debug("Reserve dump area start address: 0x%lx\n",
413 fw_dump.reserve_dump_area_start);
414 } else {
415 /*
416 * Reserve memory at an offset closer to bottom of the RAM to
417 * minimize the impact of memory hot-remove operation. We can't
418 * use memblock_find_in_range() here since it doesn't allocate
419 * from bottom to top.
420 */
409 fadump_reserve_crash_area(base, size);
410
411 pr_debug("fadumphdr_addr = %#016lx\n", fw_dump.fadumphdr_addr);
412 pr_debug("Reserve dump area start address: 0x%lx\n",
413 fw_dump.reserve_dump_area_start);
414 } else {
415 /*
416 * Reserve memory at an offset closer to bottom of the RAM to
417 * minimize the impact of memory hot-remove operation. We can't
418 * use memblock_find_in_range() here since it doesn't allocate
419 * from bottom to top.
420 */
421 for (base = fw_dump.boot_memory_size;
422 base <= (memory_boundary - size);
423 base += size) {
421 while (base <= (mem_boundary - size)) {
424 if (memblock_is_region_memory(base, size) &&
425 !memblock_is_region_reserved(base, size))
426 break;
422 if (memblock_is_region_memory(base, size) &&
423 !memblock_is_region_reserved(base, size))
424 break;
425
426 base += size;
427 }
427 }
428 if ((base > (memory_boundary - size)) ||
428
429 if ((base > (mem_boundary - size)) ||
429 memblock_reserve(base, size)) {
430 memblock_reserve(base, size)) {
430 pr_err("Failed to reserve memory\n");
431 return 0;
431 pr_err("Failed to reserve memory!\n");
432 goto error_out;
432 }
433
433 }
434
434 pr_info("Reserved %ldMB of memory at %ldMB for firmware-"
435 "assisted dump (System RAM: %ldMB)\n",
436 (unsigned long)(size >> 20),
437 (unsigned long)(base >> 20),
438 (unsigned long)(memblock_phys_mem_size() >> 20));
435 pr_info("Reserved %lldMB of memory at %#016llx (System RAM: %lldMB)\n",
436 (size >> 20), base, (memblock_phys_mem_size() >> 20));
439
440 fw_dump.reserve_dump_area_start = base;
437
438 fw_dump.reserve_dump_area_start = base;
441 return fadump_cma_init();
439 ret = fadump_cma_init();
442 }
440 }
443 return 1;
441
442 return ret;
443error_out:
444 fw_dump.fadump_enabled = 0;
445 return 0;
444}
445
446unsigned long __init arch_reserved_kernel_pages(void)
447{
448 return memblock_reserved_size() / PAGE_SIZE;
449}
450
451/* Look for fadump= cmdline option. */

--- 767 unchanged lines hidden ---
446}
447
448unsigned long __init arch_reserved_kernel_pages(void)
449{
450 return memblock_reserved_size() / PAGE_SIZE;
451}
452
453/* Look for fadump= cmdline option. */

--- 767 unchanged lines hidden ---