Skip to content

Commit 88742dc

Browse files
committed
x86/crash: pass dm crypt keys to kdump kernel
JIRA: https://issues.redhat.com/browse/RHEL-104939 Upstream Status: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git commit 5eb3f60 Author: Coiby Xu <coxu@redhat.com> Date: Fri May 2 09:12:41 2025 +0800 x86/crash: pass dm crypt keys to kdump kernel 1st kernel will build up the kernel command parameter dmcryptkeys as similar to elfcorehdr to pass the memory address of the stored info of dm crypt key to kdump kernel. Link: https://lkml.kernel.org/r/20250502011246.99238-8-coxu@redhat.com Signed-off-by: Coiby Xu <coxu@redhat.com> Acked-by: Baoquan He <bhe@redhat.com> Cc: "Daniel P. Berrange" <berrange@redhat.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: Dave Young <dyoung@redhat.com> Cc: Jan Pazdziora <jpazdziora@redhat.com> Cc: Liu Pingfan <kernelfans@gmail.com> Cc: Milan Broz <gmazyland@gmail.com> Cc: Ondrej Kozina <okozina@redhat.com> Cc: Vitaly Kuznetsov <vkuznets@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Coiby Xu <coxu@redhat.com>
1 parent ed5be2f commit 88742dc

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

Documentation/admin-guide/kdump/kdump.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@ Write the dump file to encrypted disk volume
586586
============================================
587587

588588
CONFIG_CRASH_DM_CRYPT can be enabled to support saving the dump file to an
589-
encrypted disk volume. User space can interact with
590-
/sys/kernel/config/crash_dm_crypt_keys for setup,
589+
encrypted disk volume (only x86_64 supported for now). User space can interact
590+
with /sys/kernel/config/crash_dm_crypt_keys for setup,
591591

592592
1. Tell the first kernel what logon keys are needed to unlock the disk volumes,
593593
# Add key #1

arch/x86/kernel/crash.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
277277
unsigned long long mend)
278278
{
279279
unsigned long start, end;
280+
int ret;
280281

281282
cmem->ranges[0].start = mstart;
282283
cmem->ranges[0].end = mend;
@@ -285,22 +286,43 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
285286
/* Exclude elf header region */
286287
start = image->elf_load_addr;
287288
end = start + image->elf_headers_sz - 1;
288-
return crash_exclude_mem_range(cmem, start, end);
289+
ret = crash_exclude_mem_range(cmem, start, end);
290+
291+
if (ret)
292+
return ret;
293+
294+
/* Exclude dm crypt keys region */
295+
if (image->dm_crypt_keys_addr) {
296+
start = image->dm_crypt_keys_addr;
297+
end = start + image->dm_crypt_keys_sz - 1;
298+
return crash_exclude_mem_range(cmem, start, end);
299+
}
300+
301+
return ret;
289302
}
290303

291304
/* Prepare memory map for crash dump kernel */
292305
int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
293306
{
307+
unsigned int nr_ranges = 0;
294308
int i, ret = 0;
295309
unsigned long flags;
296310
struct e820_entry ei;
297311
struct crash_memmap_data cmd;
298312
struct crash_mem *cmem;
299313

300-
cmem = vzalloc(struct_size(cmem, ranges, 1));
314+
/*
315+
* Using random kexec_buf for passing dm crypt keys may cause a range
316+
* split. So use two slots here.
317+
*/
318+
nr_ranges = 2;
319+
cmem = vzalloc(struct_size(cmem, ranges, nr_ranges));
301320
if (!cmem)
302321
return -ENOMEM;
303322

323+
cmem->max_nr_ranges = nr_ranges;
324+
cmem->nr_ranges = 0;
325+
304326
memset(&cmd, 0, sizeof(struct crash_memmap_data));
305327
cmd.params = params;
306328

arch/x86/kernel/kexec-bzimage64.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include <asm/kexec-bzimage64.h>
2828

2929
#define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */
30+
#define MAX_DMCRYPTKEYS_STR_LEN 31 /* dmcryptkeys=0x<64bit-value> */
31+
3032

3133
/*
3234
* Defines lowest physical address for various segments. Not sure where
@@ -76,6 +78,10 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
7678
if (image->type == KEXEC_TYPE_CRASH) {
7779
len = sprintf(cmdline_ptr,
7880
"elfcorehdr=0x%lx ", image->elf_load_addr);
81+
82+
if (image->dm_crypt_keys_addr != 0)
83+
len += sprintf(cmdline_ptr + len,
84+
"dmcryptkeys=0x%lx ", image->dm_crypt_keys_addr);
7985
}
8086
memcpy(cmdline_ptr + len, cmdline, cmdline_len);
8187
cmdline_len += len;
@@ -441,6 +447,19 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
441447
ret = crash_load_segments(image);
442448
if (ret)
443449
return ERR_PTR(ret);
450+
ret = crash_load_dm_crypt_keys(image);
451+
if (ret == -ENOENT) {
452+
kexec_dprintk("No dm crypt key to load\n");
453+
} else if (ret) {
454+
pr_err("Failed to load dm crypt keys\n");
455+
return ERR_PTR(ret);
456+
}
457+
if (image->dm_crypt_keys_addr &&
458+
cmdline_len + MAX_ELFCOREHDR_STR_LEN + MAX_DMCRYPTKEYS_STR_LEN >
459+
header->cmdline_size) {
460+
pr_err("Appending dmcryptkeys=<addr> to command line exceeds maximum allowed length\n");
461+
return ERR_PTR(-EINVAL);
462+
}
444463
}
445464
#endif
446465

@@ -468,6 +487,8 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
468487
efi_map_sz = efi_get_runtime_map_size();
469488
params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
470489
MAX_ELFCOREHDR_STR_LEN;
490+
if (image->dm_crypt_keys_addr)
491+
params_cmdline_sz += MAX_DMCRYPTKEYS_STR_LEN;
471492
params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
472493
kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
473494
sizeof(struct setup_data) +

0 commit comments

Comments
 (0)