aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/setup.c')
-rw-r--r--arch/x86/kernel/setup.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 90d8cc930f5e..fae9134a2de9 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -507,11 +507,14 @@ static void __init memblock_x86_reserve_range_setup_data(void)
507/* 507/*
508 * Keep the crash kernel below this limit. On 32 bits earlier kernels 508 * Keep the crash kernel below this limit. On 32 bits earlier kernels
509 * would limit the kernel to the low 512 MiB due to mapping restrictions. 509 * would limit the kernel to the low 512 MiB due to mapping restrictions.
510 * On 64bit, old kexec-tools need to under 896MiB.
510 */ 511 */
511#ifdef CONFIG_X86_32 512#ifdef CONFIG_X86_32
512# define CRASH_KERNEL_ADDR_MAX (512 << 20) 513# define CRASH_KERNEL_ADDR_LOW_MAX (512 << 20)
514# define CRASH_KERNEL_ADDR_HIGH_MAX (512 << 20)
513#else 515#else
514# define CRASH_KERNEL_ADDR_MAX MAXMEM 516# define CRASH_KERNEL_ADDR_LOW_MAX (896UL<<20)
517# define CRASH_KERNEL_ADDR_HIGH_MAX MAXMEM
515#endif 518#endif
516 519
517static void __init reserve_crashkernel_low(void) 520static void __init reserve_crashkernel_low(void)
@@ -521,19 +524,35 @@ static void __init reserve_crashkernel_low(void)
521 unsigned long long low_base = 0, low_size = 0; 524 unsigned long long low_base = 0, low_size = 0;
522 unsigned long total_low_mem; 525 unsigned long total_low_mem;
523 unsigned long long base; 526 unsigned long long base;
527 bool auto_set = false;
524 int ret; 528 int ret;
525 529
526 total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT)); 530 total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
531 /* crashkernel=Y,low */
527 ret = parse_crashkernel_low(boot_command_line, total_low_mem, 532 ret = parse_crashkernel_low(boot_command_line, total_low_mem,
528 &low_size, &base); 533 &low_size, &base);
529 if (ret != 0 || low_size <= 0) 534 if (ret != 0) {
530 return; 535 /*
536 * two parts from lib/swiotlb.c:
537 * swiotlb size: user specified with swiotlb= or default.
538 * swiotlb overflow buffer: now is hardcoded to 32k.
539 * We round it to 8M for other buffers that
540 * may need to stay low too.
541 */
542 low_size = swiotlb_size_or_default() + (8UL<<20);
543 auto_set = true;
544 } else {
545 /* passed with crashkernel=0,low ? */
546 if (!low_size)
547 return;
548 }
531 549
532 low_base = memblock_find_in_range(low_size, (1ULL<<32), 550 low_base = memblock_find_in_range(low_size, (1ULL<<32),
533 low_size, alignment); 551 low_size, alignment);
534 552
535 if (!low_base) { 553 if (!low_base) {
536 pr_info("crashkernel low reservation failed - No suitable area found.\n"); 554 if (!auto_set)
555 pr_info("crashkernel low reservation failed - No suitable area found.\n");
537 556
538 return; 557 return;
539 } 558 }
@@ -554,14 +573,22 @@ static void __init reserve_crashkernel(void)
554 const unsigned long long alignment = 16<<20; /* 16M */ 573 const unsigned long long alignment = 16<<20; /* 16M */
555 unsigned long long total_mem; 574 unsigned long long total_mem;
556 unsigned long long crash_size, crash_base; 575 unsigned long long crash_size, crash_base;
576 bool high = false;
557 int ret; 577 int ret;
558 578
559 total_mem = memblock_phys_mem_size(); 579 total_mem = memblock_phys_mem_size();
560 580
581 /* crashkernel=XM */
561 ret = parse_crashkernel(boot_command_line, total_mem, 582 ret = parse_crashkernel(boot_command_line, total_mem,
562 &crash_size, &crash_base); 583 &crash_size, &crash_base);
563 if (ret != 0 || crash_size <= 0) 584 if (ret != 0 || crash_size <= 0) {
564 return; 585 /* crashkernel=X,high */
586 ret = parse_crashkernel_high(boot_command_line, total_mem,
587 &crash_size, &crash_base);
588 if (ret != 0 || crash_size <= 0)
589 return;
590 high = true;
591 }
565 592
566 /* 0 means: find the address automatically */ 593 /* 0 means: find the address automatically */
567 if (crash_base <= 0) { 594 if (crash_base <= 0) {
@@ -569,7 +596,9 @@ static void __init reserve_crashkernel(void)
569 * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX 596 * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
570 */ 597 */
571 crash_base = memblock_find_in_range(alignment, 598 crash_base = memblock_find_in_range(alignment,
572 CRASH_KERNEL_ADDR_MAX, crash_size, alignment); 599 high ? CRASH_KERNEL_ADDR_HIGH_MAX :
600 CRASH_KERNEL_ADDR_LOW_MAX,
601 crash_size, alignment);
573 602
574 if (!crash_base) { 603 if (!crash_base) {
575 pr_info("crashkernel reservation failed - No suitable area found.\n"); 604 pr_info("crashkernel reservation failed - No suitable area found.\n");