Skip to content

Commit

Permalink
Merge branch 'for-next/kdump' into for-next/core
Browse files Browse the repository at this point in the history
* for-next/kdump:
  arm64: kdump: Support crashkernel=X fall back to reserve region above DMA zones
  arm64: kdump: Provide default size when crashkernel=Y,low is not specified
  • Loading branch information
willdeacon committed Dec 6, 2022
2 parents d864e90 + a9ae89d commit 926939c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 12 deletions.
15 changes: 6 additions & 9 deletions Documentation/admin-guide/kernel-parameters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,7 @@
memory region [offset, offset + size] for that kernel
image. If '@offset' is omitted, then a suitable offset
is selected automatically.
[KNL, X86-64] Select a region under 4G first, and
[KNL, X86-64, ARM64] Select a region under 4G first, and
fall back to reserve region above 4G when '@offset'
hasn't been specified.
See Documentation/admin-guide/kdump/kdump.rst for further details.
Expand All @@ -851,26 +851,23 @@
available.
It will be ignored if crashkernel=X is specified.
crashkernel=size[KMG],low
[KNL, X86-64] range under 4G. When crashkernel=X,high
[KNL, X86-64, ARM64] range under 4G. When crashkernel=X,high
is passed, kernel could allocate physical memory region
above 4G, that cause second kernel crash on system
that require some amount of low memory, e.g. swiotlb
requires at least 64M+32K low memory, also enough extra
low memory is needed to make sure DMA buffers for 32-bit
devices won't run out. Kernel would try to allocate
at least 256M below 4G automatically.
default size of memory below 4G automatically. The default
size is platform dependent.
--> x86: max(swiotlb_size_or_default() + 8MiB, 256MiB)
--> arm64: 128MiB
This one lets the user specify own low range under 4G
for second kernel instead.
0: to disable low allocation.
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.

[KNL, ARM64] range in low memory.
This one lets the user specify a low range in the
DMA zone for the crash dump kernel.
It will be ignored when crashkernel=X,high is not used
or memory reserved is located in the DMA zones.

cryptomgr.notests
[KNL] Disable crypto self-tests

Expand Down
25 changes: 22 additions & 3 deletions arch/arm64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ phys_addr_t __ro_after_init arm64_dma_phys_limit = PHYS_MASK + 1;
#define CRASH_ADDR_LOW_MAX arm64_dma_phys_limit
#define CRASH_ADDR_HIGH_MAX (PHYS_MASK + 1)

#define DEFAULT_CRASH_KERNEL_LOW_SIZE (128UL << 20)

static int __init reserve_crashkernel_low(unsigned long long low_size)
{
unsigned long long low_base;
Expand Down Expand Up @@ -130,6 +132,7 @@ static void __init reserve_crashkernel(void)
unsigned long long crash_max = CRASH_ADDR_LOW_MAX;
char *cmdline = boot_command_line;
int ret;
bool fixed_base = false;

if (!IS_ENABLED(CONFIG_KEXEC_CORE))
return;
Expand All @@ -147,7 +150,9 @@ static void __init reserve_crashkernel(void)
* is not allowed.
*/
ret = parse_crashkernel_low(cmdline, 0, &crash_low_size, &crash_base);
if (ret && (ret != -ENOENT))
if (ret == -ENOENT)
crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
else if (ret)
return;

crash_max = CRASH_ADDR_HIGH_MAX;
Expand All @@ -159,18 +164,32 @@ static void __init reserve_crashkernel(void)
crash_size = PAGE_ALIGN(crash_size);

/* User specifies base address explicitly. */
if (crash_base)
if (crash_base) {
fixed_base = true;
crash_max = crash_base + crash_size;
}

retry:
crash_base = memblock_phys_alloc_range(crash_size, CRASH_ALIGN,
crash_base, crash_max);
if (!crash_base) {
/*
* If the first attempt was for low memory, fall back to
* high memory, the minimum required low memory will be
* reserved later.
*/
if (!fixed_base && (crash_max == CRASH_ADDR_LOW_MAX)) {
crash_max = CRASH_ADDR_HIGH_MAX;
crash_low_size = DEFAULT_CRASH_KERNEL_LOW_SIZE;
goto retry;
}

pr_warn("cannot allocate crashkernel (size:0x%llx)\n",
crash_size);
return;
}

if ((crash_base >= CRASH_ADDR_LOW_MAX) &&
if ((crash_base > CRASH_ADDR_LOW_MAX - crash_low_size) &&
crash_low_size && reserve_crashkernel_low(crash_low_size)) {
memblock_phys_free(crash_base, crash_size);
return;
Expand Down

0 comments on commit 926939c

Please sign in to comment.