Skip to content

Commit 5eb3f60

Browse files
coibyakpm00
authored andcommitted
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/[email protected] Signed-off-by: Coiby Xu <[email protected]> Acked-by: Baoquan He <[email protected]> Cc: "Daniel P. Berrange" <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Dave Young <[email protected]> Cc: Jan Pazdziora <[email protected]> Cc: Liu Pingfan <[email protected]> Cc: Milan Broz <[email protected]> Cc: Ondrej Kozina <[email protected]> Cc: Vitaly Kuznetsov <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent e1e6cd0 commit 5eb3f60

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
@@ -551,8 +551,8 @@ Write the dump file to encrypted disk volume
551551
============================================
552552

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

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

arch/x86/kernel/crash.c

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

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

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

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

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

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)