CONFIG_CRASH_DM_CRYPT has been introduced to support LUKS-encrypted device dump target by addressing two challenges [1], - Kdump kernel may not be able to decrypt the LUKS partition. For some machines, a system administrator may not have a chance to enter the password to decrypt the device in kdump initramfs after the 1st kernel crashes
- LUKS2 by default use the memory-hard Argon2 key derivation function which is quite memory-consuming compared to the limited memory reserved for kdump. To also enable this feature for ARM64, we only need to add device tree property dmcryptkeys [2] as similar to elfcorehdr to pass the memory address of the stored info of dm-crypt keys to the kdump kernel. [1] https://lore.kernel.org/all/[email protected]/ [2] https://github.com/devicetree-org/dt-schema/pull/181 Cc: Arnaud Lefebvre <[email protected]> Cc: Baoquan he <[email protected]> Cc: Dave Young <[email protected]> Cc: Kairui Song <[email protected]> Cc: Pingfan Liu <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Krzysztof Kozlowski <[email protected]> Signed-off-by: Coiby Xu <[email protected]> --- v2 - Krzysztof - Use imperative mood for commit message - Add dt-schema ABI Documentation - Don't print dm-crypt keys address via pr_debug arch/arm64/kernel/machine_kexec_file.c | 9 +++++++++ drivers/of/fdt.c | 17 +++++++++++++++++ drivers/of/kexec.c | 19 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 410060ebd86d..5f3bad8ca96d 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -134,6 +134,15 @@ int load_other_segments(struct kimage *image, kexec_dprintk("Loaded elf core header at 0x%lx bufsz=0x%lx memsz=0x%lx\n", image->elf_load_addr, kbuf.bufsz, kbuf.memsz); + + ret = crash_load_dm_crypt_keys(image); + + if (ret == -ENOENT) { + kexec_dprintk("No dm crypt key to load\n"); + } else if (ret) { + pr_err("Failed to load dm crypt keys\n"); + goto out_err; + } } #endif diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 331646d667b9..9b6a6a402cb7 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -866,6 +866,22 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node) elfcorehdr_addr, elfcorehdr_size); } +static void __init early_init_dt_check_for_dmcryptkeys(unsigned long node) +{ + const __be32 *prop; + + if (!IS_ENABLED(CONFIG_CRASH_DM_CRYPT)) + return; + + pr_debug("Looking for dmcryptkeys property... "); + + prop = of_get_flat_dt_prop(node, "linux,dmcryptkeys", NULL); + if (!prop) + return; + + dm_crypt_keys_addr = dt_mem_next_cell(dt_root_addr_cells, &prop); +} + static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND; /* @@ -1097,6 +1113,7 @@ int __init early_init_dt_scan_chosen(char *cmdline) early_init_dt_check_for_initrd(node); early_init_dt_check_for_elfcorehdr(node); + early_init_dt_check_for_dmcryptkeys(node); rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l); if (rng_seed && l > 0) { diff --git a/drivers/of/kexec.c b/drivers/of/kexec.c index 1ee2d31816ae..4bfb1ea5744e 100644 --- a/drivers/of/kexec.c +++ b/drivers/of/kexec.c @@ -432,6 +432,25 @@ void *of_kexec_alloc_and_setup_fdt(const struct kimage *image, if (ret) goto out; + if (image->dm_crypt_keys_addr != 0) { + ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, + "linux,dmcryptkeys", + image->dm_crypt_keys_addr, + image->dm_crypt_keys_sz); + + if (ret) + goto out; + + /* + * Avoid dmcryptkeys from being stomped on in kdump kernel by + * setting up memory reserve map. + */ + ret = fdt_add_mem_rsv(fdt, image->dm_crypt_keys_addr, + image->dm_crypt_keys_sz); + if (ret) + goto out; + } + #ifdef CONFIG_CRASH_DUMP /* add linux,usable-memory-range */ ret = fdt_appendprop_addrrange(fdt, 0, chosen_node, base-commit: ccd1cdca5cd433c8a5dff78b69a79b31d9b77ee1 -- 2.52.0
