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.
Signed-off-by: Coiby Xu <coxu@redhat.com>
---
Documentation/admin-guide/kdump/kdump.rst | 4 ++--
arch/x86/kernel/crash.c | 26 +++++++++++++++++++++--
arch/x86/kernel/kexec-bzimage64.c | 11 ++++++++++
3 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/Documentation/admin-guide/kdump/kdump.rst b/Documentation/admin-guide/kdump/kdump.rst
index 1283f0244614..2209caf36d79 100644
--- a/Documentation/admin-guide/kdump/kdump.rst
+++ b/Documentation/admin-guide/kdump/kdump.rst
@@ -555,8 +555,8 @@ Write the dump file to encrypted disk volume
============================================
CONFIG_CRASH_DM_CRYPT can be enabled to support saving the dump file to an
-encrypted disk volume. User space can interact with
-/sys/kernel/config/crash_dm_crypt_keys for setup,
+encrypted disk volume (only x86_64 supported for now). User space can interact
+with /sys/kernel/config/crash_dm_crypt_keys for setup,
1. Tell the first kernel what keys are needed to unlock the disk volumes,
# Add key #1
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index 340af8155658..a525ee639b63 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -278,6 +278,7 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
unsigned long long mend)
{
unsigned long start, end;
+ int ret;
cmem->ranges[0].start = mstart;
cmem->ranges[0].end = mend;
@@ -286,22 +287,43 @@ static int memmap_exclude_ranges(struct kimage *image, struct crash_mem *cmem,
/* Exclude elf header region */
start = image->elf_load_addr;
end = start + image->elf_headers_sz - 1;
- return crash_exclude_mem_range(cmem, start, end);
+ ret = crash_exclude_mem_range(cmem, start, end);
+
+ if (ret)
+ return ret;
+
+ /* Exclude dm crypt keys region */
+ if (image->dm_crypt_keys_addr) {
+ start = image->dm_crypt_keys_addr;
+ end = start + image->dm_crypt_keys_sz - 1;
+ return crash_exclude_mem_range(cmem, start, end);
+ }
+
+ return ret;
}
/* Prepare memory map for crash dump kernel */
int crash_setup_memmap_entries(struct kimage *image, struct boot_params *params)
{
+ unsigned int nr_ranges = 0;
int i, ret = 0;
unsigned long flags;
struct e820_entry ei;
struct crash_memmap_data cmd;
struct crash_mem *cmem;
- cmem = vzalloc(struct_size(cmem, ranges, 1));
+ /*
+ * Using random kexec_buf for passing dm crypt keys may cause a range
+ * split. So use two slots here.
+ */
+ nr_ranges = 2;
+ cmem = vzalloc(struct_size(cmem, ranges, nr_ranges));
if (!cmem)
return -ENOMEM;
+ cmem->max_nr_ranges = nr_ranges;
+ cmem->nr_ranges = 0;
+
memset(&cmd, 0, sizeof(struct crash_memmap_data));
cmd.params = params;
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 68530fad05f7..5604a5109858 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -76,6 +76,10 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
if (image->type == KEXEC_TYPE_CRASH) {
len = sprintf(cmdline_ptr,
"elfcorehdr=0x%lx ", image->elf_load_addr);
+
+ if (image->dm_crypt_keys_addr != 0)
+ len += sprintf(cmdline_ptr + len,
+ "dmcryptkeys=0x%lx ", image->dm_crypt_keys_addr);
}
memcpy(cmdline_ptr + len, cmdline, cmdline_len);
cmdline_len += len;
@@ -441,6 +445,13 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
ret = crash_load_segments(image);
if (ret)
return ERR_PTR(ret);
+ 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");
+ return ERR_PTR(ret);
+ }
}
#endif
--
2.48.1
>diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
>index 68530fad05f7..5604a5109858 100644
>--- a/arch/x86/kernel/kexec-bzimage64.c
>+++ b/arch/x86/kernel/kexec-bzimage64.c
>@@ -76,6 +76,10 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
> if (image->type == KEXEC_TYPE_CRASH) {
> len = sprintf(cmdline_ptr,
> "elfcorehdr=0x%lx ", image->elf_load_addr);
>+
>+ if (image->dm_crypt_keys_addr != 0)
>+ len += sprintf(cmdline_ptr + len,
>+ "dmcryptkeys=0x%lx ", image->dm_crypt_keys_addr);
> }
> memcpy(cmdline_ptr + len, cmdline, cmdline_len);
> cmdline_len += len;
You are adding another kernel parameter but I believe without taking its
length into account. See the MAX_ELFCOREHDR_STR_LEN constant which is added to the
params_cmdline_sz variable for the elfcorehdr= parameter.
This will (at least during my tests) truncate the cmdline given to the crash kernel because
the next section (efi_map_offset) will have an offset starting inside the cmdline section
and it might overwrite the end of it:
kexec-bzimage64.c:480:
params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
MAX_ELFCOREHDR_STR_LEN; <<< Should have + 31 here for "dmcryptkeys=0x<ptr> "
params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
sizeof(struct setup_data) +
sizeof(struct efi_setup_data) +
sizeof(struct setup_data) +
RNG_SEED_LENGTH;
And I believe the buffer might be too small.
Also, there is another check a few lines above that needs to take the size into account:
/*
* In case of crash dump, we will append elfcorehdr=<addr> to
* command line. Make sure it does not overflow
*/
if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
pr_err("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
return ERR_PTR(-EINVAL);
}
On Wed, Apr 23, 2025 at 10:59:06PM +0200, Arnaud Lefebvre wrote:
>>diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
>>index 68530fad05f7..5604a5109858 100644
>>--- a/arch/x86/kernel/kexec-bzimage64.c
>>+++ b/arch/x86/kernel/kexec-bzimage64.c
>>@@ -76,6 +76,10 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
>> if (image->type == KEXEC_TYPE_CRASH) {
>> len = sprintf(cmdline_ptr,
>> "elfcorehdr=0x%lx ", image->elf_load_addr);
>>+
>>+ if (image->dm_crypt_keys_addr != 0)
>>+ len += sprintf(cmdline_ptr + len,
>>+ "dmcryptkeys=0x%lx ", image->dm_crypt_keys_addr);
sprintf will return the length of dmcryptkey=xxx which will be added to
len.
>> }
>> memcpy(cmdline_ptr + len, cmdline, cmdline_len);
>> cmdline_len += len;
Then cmdline_len will included the new len.
>
>You are adding another kernel parameter but I believe without taking its
>length into account. See the MAX_ELFCOREHDR_STR_LEN constant which is added to the
>params_cmdline_sz variable for the elfcorehdr= parameter.
Thanks for raising the concern! I believe this issue has already been
took care of. Please check the above two inline comments:)
>
>This will (at least during my tests) truncate the cmdline given to the crash kernel because
>the next section (efi_map_offset) will have an offset starting inside the cmdline section
>and it might overwrite the end of it:
>
>kexec-bzimage64.c:480:
>params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
> MAX_ELFCOREHDR_STR_LEN; <<< Should have + 31 here for "dmcryptkeys=0x<ptr> "
>params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
>kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
> sizeof(struct setup_data) +
> sizeof(struct efi_setup_data) +
> sizeof(struct setup_data) +
> RNG_SEED_LENGTH;
>
>And I believe the buffer might be too small.
>
>Also, there is another check a few lines above that needs to take the size into account:
>
>/*
> * In case of crash dump, we will append elfcorehdr=<addr> to
> * command line. Make sure it does not overflow
> */
>if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
> pr_err("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
> return ERR_PTR(-EINVAL);
>}
>
--
Best regards,
Coiby
On Tue, Apr 29, 2025 at 05:40:21PM +0800, Coiby Xu wrote:
>On Wed, Apr 23, 2025 at 10:59:06PM +0200, Arnaud Lefebvre wrote:
>>>diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
>>>index 68530fad05f7..5604a5109858 100644
>>>--- a/arch/x86/kernel/kexec-bzimage64.c
>>>+++ b/arch/x86/kernel/kexec-bzimage64.c
>>>@@ -76,6 +76,10 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
>>> if (image->type == KEXEC_TYPE_CRASH) {
>>> len = sprintf(cmdline_ptr,
>>> "elfcorehdr=0x%lx ", image->elf_load_addr);
>>>+
>>>+ if (image->dm_crypt_keys_addr != 0)
>>>+ len += sprintf(cmdline_ptr + len,
>>>+ "dmcryptkeys=0x%lx ", image->dm_crypt_keys_addr);
>
>sprintf will return the length of dmcryptkey=xxx which will be added to
>len.
>
>>> }
>>> memcpy(cmdline_ptr + len, cmdline, cmdline_len);
>>> cmdline_len += len;
>
>Then cmdline_len will included the new len.
Yes, the cmdline_len is correct. No issue there.
>
>>
>>You are adding another kernel parameter but I believe without taking its
>>length into account. See the MAX_ELFCOREHDR_STR_LEN constant which is added to the
>>params_cmdline_sz variable for the elfcorehdr= parameter.
>
>Thanks for raising the concern! I believe this issue has already been
>took care of. Please check the above two inline comments:)
>
I'm sorry but I don't think it is. If you look at my comments below:
>
>>
>>This will (at least during my tests) truncate the cmdline given to the crash kernel because
>>the next section (efi_map_offset) will have an offset starting inside the cmdline section
>>and it might overwrite the end of it:
>>
>>kexec-bzimage64.c:480:
>>params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
>> MAX_ELFCOREHDR_STR_LEN; <<< Should have + 31 here for "dmcryptkeys=0x<ptr> "
>>params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
>>kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
>> sizeof(struct setup_data) +
>> sizeof(struct efi_setup_data) +
>> sizeof(struct setup_data) +
>> RNG_SEED_LENGTH;
>>
>>And I believe the buffer might be too small.
>>
>>Also, there is another check a few lines above that needs to take the size into account:
>>
>>/*
>>* In case of crash dump, we will append elfcorehdr=<addr> to
>>* command line. Make sure it does not overflow
>>*/
>>if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
>> pr_err("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
>> return ERR_PTR(-EINVAL);
>>}
>>
>
To try to explain a bit more, we pass a lot of arguments to the crash kernel so
the initrd (dracut) can mount the encrypted disk. When I run kexec using
the following:
/usr/host/bin/kexec --debug --load-panic /linux-hv '--append=maxcpus=1
reset_devices rd.info rd.cc.kdump root=UUID=d039277c-2ee
3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10 rd.shell=1
rd.cc.kdump.encrypted
rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c260907a2447' --initrd
/crash-initrd
kexec debug print those logs:
<snip>
[ 53.642483] kexec-bzImage64: Loaded purgatory at 0xb6ffb000
[ 53.642828] kexec-bzImage64: Loaded boot_param, command line and misc at
0xb6ff9000 bufsz=0x12f0 memsz=0x2000
[ 53.643366] kexec-bzImage64: Loaded 64bit kernel at 0xb1000000
bufsz=0x16a5000 memsz=0x550d000
[ 53.643918] kexec-bzImage64: Loaded initrd at 0xaeb90000 bufsz=0x246f2a1
memsz=0x246f2a1
[ 53.644363] kexec-bzImage64: Final command line is: elfcorehdr=0x77000000
dmcryptkeys=0xa81fc000 maxcpus=1 reset_devices rd.info rd.cc.kdump
root=UUID=d039277c-2ee3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10
rd.shell=1 rd.cc.kdump.encrypted
rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c260907a2447
<snip>
Here, we see the full command line, as expected. But when I trigger a panic
using `echo c > /proc/sysrq-trigger`, the first two lines of the crash kernel
loading are:
[ 0.000000] Linux version 6.12.23+ (arnaud@exherbo) (gcc (GCC) 12.3.0, GNU ld
(GNU Binutils) 2.44) #4 SMP Wed Apr 30 16:11:39 CEST 2025
[ 0.000000] Command line: elfcorehdr=0x77000000 dmcryptkeys=0x9ec14000
maxcpus=1 reset_devices rd.info rd.cc.kdump
root=UUID=d039277c-2ee3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10
rd.shell=1 rd.cc.kdump.encrypted
rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c26090
You can see some of it is truncated at the end. It's missing `7a2447`. This is
because I guess it gets overridden.
My comment above explains where and why it might happen. If I add the size of
the dmcryptkeys string length to the params_cmdline_sz variable, we should
allocate enough space to have it all. With the patch below, it works fine and I
get the full cmdline when my crash kernel boots:
[ 0.000000] Linux version 6.12.23+ (arnaud@exherbo) (gcc (GCC) 12.3.0, GNU ld
(GNU Binutils) 2.44) #3 SMP Thu Apr 24 16:42:18 CEST 2025
[ 0.000000] Command line: elfcorehdr=0x77000000 dmcryptkeys=0xa81fc000
maxcpus=1 reset_devices rd.info rd.cc.kdump
root=UUID=d039277c-2ee3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10
rd.shell=1 rd.cc.kdump.encrypted
rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c260907a2447
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 5604a5109858..06fc1f412af4 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -27,6 +27,7 @@
#include <asm/kexec-bzimage64.h>
#define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */
+#define MAX_DMCRYPTKEYS_STR_LEN 31
/*
* Defines lowest physical address for various segments. Not sure where
@@ -434,7 +435,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
* In case of crash dump, we will append elfcorehdr=<addr> to
* command line. Make sure it does not overflow
*/
- if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
+ if (cmdline_len + MAX_ELFCOREHDR_STR_LEN + MAX_DMCRYPTKEYS_STR_LEN > header->cmdline_size) {
pr_err("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
return ERR_PTR(-EINVAL);
}
@@ -478,7 +479,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
*/
efi_map_sz = efi_get_runtime_map_size();
params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
- MAX_ELFCOREHDR_STR_LEN;
+ MAX_ELFCOREHDR_STR_LEN + MAX_DMCRYPTKEYS_STR_LEN;
params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
sizeof(struct setup_data) +
Let me know if it makes more sense!
On Wed, Apr 30, 2025 at 04:48:25PM +0200, Arnaud Lefebvre wrote:
>On Tue, Apr 29, 2025 at 05:40:21PM +0800, Coiby Xu wrote:
>>On Wed, Apr 23, 2025 at 10:59:06PM +0200, Arnaud Lefebvre wrote:
>>>>diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
>>>>index 68530fad05f7..5604a5109858 100644
>>>>--- a/arch/x86/kernel/kexec-bzimage64.c
>>>>+++ b/arch/x86/kernel/kexec-bzimage64.c
>>>>@@ -76,6 +76,10 @@ static int setup_cmdline(struct kimage *image, struct boot_params *params,
>>>> if (image->type == KEXEC_TYPE_CRASH) {
>>>> len = sprintf(cmdline_ptr,
>>>> "elfcorehdr=0x%lx ", image->elf_load_addr);
>>>>+
>>>>+ if (image->dm_crypt_keys_addr != 0)
>>>>+ len += sprintf(cmdline_ptr + len,
>>>>+ "dmcryptkeys=0x%lx ", image->dm_crypt_keys_addr);
>>
>>sprintf will return the length of dmcryptkey=xxx which will be added to
>>len.
>>
>>>> }
>>>> memcpy(cmdline_ptr + len, cmdline, cmdline_len);
>>>> cmdline_len += len;
>>
>>Then cmdline_len will included the new len.
>
>Yes, the cmdline_len is correct. No issue there.
Thanks for confirming it!
>
>>
>>>
>>>You are adding another kernel parameter but I believe without taking its
>>>length into account. See the MAX_ELFCOREHDR_STR_LEN constant which is added to the
>>>params_cmdline_sz variable for the elfcorehdr= parameter.
>>
>>Thanks for raising the concern! I believe this issue has already been
>>took care of. Please check the above two inline comments:)
>>
>
>I'm sorry but I don't think it is. If you look at my comments below:
>
>>
>>>
>>>This will (at least during my tests) truncate the cmdline given to the crash kernel because
>>>the next section (efi_map_offset) will have an offset starting inside the cmdline section
>>>and it might overwrite the end of it:
>>>
>>>kexec-bzimage64.c:480:
>>>params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
>>> MAX_ELFCOREHDR_STR_LEN; <<< Should have + 31 here for "dmcryptkeys=0x<ptr> "
>>>params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
>>>kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
>>> sizeof(struct setup_data) +
>>> sizeof(struct efi_setup_data) +
>>> sizeof(struct setup_data) +
>>> RNG_SEED_LENGTH;
>>>
>>>And I believe the buffer might be too small.
>>>
>>>Also, there is another check a few lines above that needs to take the size into account:
>>>
>>>/*
>>>* In case of crash dump, we will append elfcorehdr=<addr> to
>>>* command line. Make sure it does not overflow
>>>*/
>>>if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
>>> pr_err("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
>>> return ERR_PTR(-EINVAL);
>>>}
>>>
>>
>
>To try to explain a bit more, we pass a lot of arguments to the crash kernel so
>the initrd (dracut) can mount the encrypted disk. When I run kexec using
>the following:
>
>/usr/host/bin/kexec --debug --load-panic /linux-hv '--append=maxcpus=1
>reset_devices rd.info rd.cc.kdump root=UUID=d039277c-2ee
>3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10 rd.shell=1
>rd.cc.kdump.encrypted
>rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
>rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c260907a2447' --initrd
>/crash-initrd
>
>kexec debug print those logs:
>
><snip>
>[ 53.642483] kexec-bzImage64: Loaded purgatory at 0xb6ffb000
>[ 53.642828] kexec-bzImage64: Loaded boot_param, command line and misc at
>0xb6ff9000 bufsz=0x12f0 memsz=0x2000
>[ 53.643366] kexec-bzImage64: Loaded 64bit kernel at 0xb1000000
>bufsz=0x16a5000 memsz=0x550d000
>[ 53.643918] kexec-bzImage64: Loaded initrd at 0xaeb90000 bufsz=0x246f2a1
>memsz=0x246f2a1
>[ 53.644363] kexec-bzImage64: Final command line is: elfcorehdr=0x77000000
>dmcryptkeys=0xa81fc000 maxcpus=1 reset_devices rd.info rd.cc.kdump
>root=UUID=d039277c-2ee3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10
>rd.shell=1 rd.cc.kdump.encrypted
>rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
>rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c260907a2447
><snip>
>
>Here, we see the full command line, as expected. But when I trigger a panic
>using `echo c > /proc/sysrq-trigger`, the first two lines of the crash kernel
>loading are:
>
>[ 0.000000] Linux version 6.12.23+ (arnaud@exherbo) (gcc (GCC) 12.3.0, GNU ld
>(GNU Binutils) 2.44) #4 SMP Wed Apr 30 16:11:39 CEST 2025
>[ 0.000000] Command line: elfcorehdr=0x77000000 dmcryptkeys=0x9ec14000
>maxcpus=1 reset_devices rd.info rd.cc.kdump
>root=UUID=d039277c-2ee3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10
>rd.shell=1 rd.cc.kdump.encrypted
>rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
>rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c26090
>
>You can see some of it is truncated at the end. It's missing `7a2447`. This is
>because I guess it gets overridden.
>
>My comment above explains where and why it might happen. If I add the size of
>the dmcryptkeys string length to the params_cmdline_sz variable, we should
>allocate enough space to have it all. With the patch below, it works fine and I
>get the full cmdline when my crash kernel boots:
>
>[ 0.000000] Linux version 6.12.23+ (arnaud@exherbo) (gcc (GCC) 12.3.0, GNU ld
>(GNU Binutils) 2.44) #3 SMP Thu Apr 24 16:42:18 CEST 2025
>[ 0.000000] Command line: elfcorehdr=0x77000000 dmcryptkeys=0xa81fc000
>maxcpus=1 reset_devices rd.info rd.cc.kdump
>root=UUID=d039277c-2ee3-466a-85eb-db9524398135 console=ttyS0 rd.timeout=10
>rd.shell=1 rd.cc.kdump.encrypted
>rd.cc.kdump.device=UUID=908234b1-c1f3-4150-bfdf-c260907a2447
>rd.cc.kdump.keyring=cryptsetup:908234b1-c1f3-4150-bfdf-c260907a2447
>
>
>diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
>index 5604a5109858..06fc1f412af4 100644
>--- a/arch/x86/kernel/kexec-bzimage64.c
>+++ b/arch/x86/kernel/kexec-bzimage64.c
>@@ -27,6 +27,7 @@
> #include <asm/kexec-bzimage64.h>
> #define MAX_ELFCOREHDR_STR_LEN 30 /* elfcorehdr=0x<64bit-value> */
>+#define MAX_DMCRYPTKEYS_STR_LEN 31
> /*
> * Defines lowest physical address for various segments. Not sure where
>@@ -434,7 +435,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
> * In case of crash dump, we will append elfcorehdr=<addr> to
> * command line. Make sure it does not overflow
> */
>- if (cmdline_len + MAX_ELFCOREHDR_STR_LEN > header->cmdline_size) {
>+ if (cmdline_len + MAX_ELFCOREHDR_STR_LEN + MAX_DMCRYPTKEYS_STR_LEN > header->cmdline_size) {
> pr_err("Appending elfcorehdr=<addr> to command line exceeds maximum allowed length\n");
> return ERR_PTR(-EINVAL);
> }
>@@ -478,7 +479,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel,
> */
> efi_map_sz = efi_get_runtime_map_size();
> params_cmdline_sz = sizeof(struct boot_params) + cmdline_len +
>- MAX_ELFCOREHDR_STR_LEN;
>+ MAX_ELFCOREHDR_STR_LEN + MAX_DMCRYPTKEYS_STR_LEN;
> params_cmdline_sz = ALIGN(params_cmdline_sz, 16);
> kbuf.bufsz = params_cmdline_sz + ALIGN(efi_map_sz, 16) +
> sizeof(struct setup_data) +
>
>
>Let me know if it makes more sense!
Yes, thanks for providing a crystal clear explanation and also a fix! I
appreciate your elaboration to show me what the problem is! I'll fix it
in v9.
--
Best regards,
Coiby
© 2016 - 2026 Red Hat, Inc.