diff options
author | Sven Schnelle <svens@linux.ibm.com> | 2021-09-23 21:22:52 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2021-10-26 15:21:31 +0200 |
commit | 5ecb2da660ab8eddafe059a6a8a708465db89ca2 (patch) | |
tree | 32c6e3e9d714f449991eb94d36ac0b86f7d24ef8 /arch/s390/kernel | |
parent | 277c8389386e2ccb8417afe4e36f67fc5dcd735d (diff) |
s390: support command lines longer than 896 bytes
Currently s390 supports a fixed maximum command line length of 896
bytes. This isn't enough as some installers are trying to pass all
configuration data via kernel command line, and even with zfcp alone
it is easy to generate really long command lines. Therefore extend
the command line to 4 kbytes.
In the parm area where the command line is stored there is no indication
of the maximum allowed length, so a new field which contains the maximum
length is added.
The parm area has always been initialized to zero, so with old kernels
this field would read zero. This is important because tools like zipl
could read this field. If it contains a number larger than zero zipl
knows the maximum length that can be stored in the parm area, otherwise
it must assume that it is booting a legacy kernel and only 896 bytes are
available.
The removing of trailing whitespace in head.S is also removed because
code to do this is already present in setup_boot_command_line().
Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/machine_kexec_file.c | 22 |
3 files changed, 20 insertions, 5 deletions
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 28177e4f52cc..8e00bb228662 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -164,5 +164,6 @@ int main(void) DEFINE(OLDMEM_BASE, PARMAREA + offsetof(struct parmarea, oldmem_base)); DEFINE(OLDMEM_SIZE, PARMAREA + offsetof(struct parmarea, oldmem_size)); DEFINE(COMMAND_LINE, PARMAREA + offsetof(struct parmarea, command_line)); + DEFINE(MAX_COMMAND_LINE_SIZE, PARMAREA + offsetof(struct parmarea, max_command_line_size)); return 0; } diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index ba3ace5ac73c..3cdf68c53614 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -280,7 +280,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; static void __init setup_boot_command_line(void) { /* copy arch command line */ - strlcpy(boot_command_line, early_command_line, ARCH_COMMAND_LINE_SIZE); + strlcpy(boot_command_line, early_command_line, COMMAND_LINE_SIZE); } static void __init check_image_bootable(void) diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c index 55382ffde9d4..528edff085d9 100644 --- a/arch/s390/kernel/machine_kexec_file.c +++ b/arch/s390/kernel/machine_kexec_file.c @@ -216,7 +216,9 @@ void *kexec_file_add_components(struct kimage *image, int (*add_kernel)(struct kimage *image, struct s390_load_data *data)) { + unsigned long max_command_line_size = LEGACY_COMMAND_LINE_SIZE; struct s390_load_data data = {0}; + unsigned long minsize; int ret; data.report = ipl_report_init(&ipl_block); @@ -227,11 +229,23 @@ void *kexec_file_add_components(struct kimage *image, if (ret) goto out; - if (image->kernel_buf_len < PARMAREA + sizeof(struct parmarea) || - image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE) { - ret = -EINVAL; + ret = -EINVAL; + minsize = PARMAREA + offsetof(struct parmarea, command_line); + if (image->kernel_buf_len < minsize) goto out; - } + + if (data.parm->max_command_line_size) + max_command_line_size = data.parm->max_command_line_size; + + if (minsize + max_command_line_size < minsize) + goto out; + + if (image->kernel_buf_len < minsize + max_command_line_size) + goto out; + + if (image->cmdline_buf_len >= max_command_line_size) + goto out; + memcpy(data.parm->command_line, image->cmdline_buf, image->cmdline_buf_len); |