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