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 --- |