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>
This commit is contained in:
parent
277c838938
commit
5ecb2da660
@ -184,35 +184,23 @@ iplstart:
|
|||||||
bas %r14,.Lloader # load parameter file
|
bas %r14,.Lloader # load parameter file
|
||||||
ltr %r2,%r2 # got anything ?
|
ltr %r2,%r2 # got anything ?
|
||||||
bz .Lnopf
|
bz .Lnopf
|
||||||
chi %r2,895
|
l %r3,MAX_COMMAND_LINE_SIZE+ARCH_OFFSET-PARMAREA(%r12)
|
||||||
bnh .Lnotrunc
|
ahi %r3,-1
|
||||||
la %r2,895
|
clr %r2,%r3
|
||||||
|
bl .Lnotrunc
|
||||||
|
lr %r2,%r3
|
||||||
.Lnotrunc:
|
.Lnotrunc:
|
||||||
l %r4,.Linitrd
|
l %r4,.Linitrd
|
||||||
clc 0(3,%r4),.L_hdr # if it is HDRx
|
clc 0(3,%r4),.L_hdr # if it is HDRx
|
||||||
bz .Lagain1 # skip dataset header
|
bz .Lagain1 # skip dataset header
|
||||||
clc 0(3,%r4),.L_eof # if it is EOFx
|
clc 0(3,%r4),.L_eof # if it is EOFx
|
||||||
bz .Lagain1 # skip dateset trailer
|
bz .Lagain1 # skip dateset trailer
|
||||||
la %r5,0(%r4,%r2)
|
|
||||||
lr %r3,%r2
|
lr %r5,%r2
|
||||||
la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
|
la %r6,COMMAND_LINE-PARMAREA(%r12)
|
||||||
mvc 0(256,%r3),0(%r4)
|
lr %r7,%r2
|
||||||
mvc 256(256,%r3),256(%r4)
|
ahi %r7,1
|
||||||
mvc 512(256,%r3),512(%r4)
|
mvcl %r6,%r4
|
||||||
mvc 768(122,%r3),768(%r4)
|
|
||||||
slr %r0,%r0
|
|
||||||
b .Lcntlp
|
|
||||||
.Ldelspc:
|
|
||||||
ic %r0,0(%r2,%r3)
|
|
||||||
chi %r0,0x20 # is it a space ?
|
|
||||||
be .Lcntlp
|
|
||||||
ahi %r2,1
|
|
||||||
b .Leolp
|
|
||||||
.Lcntlp:
|
|
||||||
brct %r2,.Ldelspc
|
|
||||||
.Leolp:
|
|
||||||
slr %r0,%r0
|
|
||||||
stc %r0,0(%r2,%r3) # terminate buffer
|
|
||||||
.Lnopf:
|
.Lnopf:
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -394,6 +382,7 @@ SYM_DATA_START(parmarea)
|
|||||||
.quad 0 # OLDMEM_BASE
|
.quad 0 # OLDMEM_BASE
|
||||||
.quad 0 # OLDMEM_SIZE
|
.quad 0 # OLDMEM_SIZE
|
||||||
.quad kernel_version # points to kernel version string
|
.quad kernel_version # points to kernel version string
|
||||||
|
.quad COMMAND_LINE_SIZE
|
||||||
|
|
||||||
.org COMMAND_LINE
|
.org COMMAND_LINE
|
||||||
.byte "root=/dev/ram0 ro"
|
.byte "root=/dev/ram0 ro"
|
||||||
|
@ -170,10 +170,10 @@ static inline int has_ebcdic_char(const char *str)
|
|||||||
|
|
||||||
void setup_boot_command_line(void)
|
void setup_boot_command_line(void)
|
||||||
{
|
{
|
||||||
parmarea.command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0;
|
parmarea.command_line[COMMAND_LINE_SIZE - 1] = 0;
|
||||||
/* convert arch command line to ascii if necessary */
|
/* convert arch command line to ascii if necessary */
|
||||||
if (has_ebcdic_char(parmarea.command_line))
|
if (has_ebcdic_char(parmarea.command_line))
|
||||||
EBCASC(parmarea.command_line, ARCH_COMMAND_LINE_SIZE);
|
EBCASC(parmarea.command_line, COMMAND_LINE_SIZE);
|
||||||
/* copy arch command line */
|
/* copy arch command line */
|
||||||
strcpy(early_command_line, strim(parmarea.command_line));
|
strcpy(early_command_line, strim(parmarea.command_line));
|
||||||
|
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
#define STARTUP_NORMAL_OFFSET 0x10000
|
#define STARTUP_NORMAL_OFFSET 0x10000
|
||||||
#define STARTUP_KDUMP_OFFSET 0x10010
|
#define STARTUP_KDUMP_OFFSET 0x10010
|
||||||
|
|
||||||
|
#define LEGACY_COMMAND_LINE_SIZE 896
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <asm/lowcore.h>
|
#include <asm/lowcore.h>
|
||||||
@ -54,8 +56,9 @@ struct parmarea {
|
|||||||
unsigned long oldmem_base; /* 0x10418 */
|
unsigned long oldmem_base; /* 0x10418 */
|
||||||
unsigned long oldmem_size; /* 0x10420 */
|
unsigned long oldmem_size; /* 0x10420 */
|
||||||
unsigned long kernel_version; /* 0x10428 */
|
unsigned long kernel_version; /* 0x10428 */
|
||||||
char pad1[0x10480 - 0x10430]; /* 0x10430 - 0x10480 */
|
unsigned long max_command_line_size; /* 0x10430 */
|
||||||
char command_line[ARCH_COMMAND_LINE_SIZE]; /* 0x10480 */
|
char pad1[0x10480-0x10438]; /* 0x10438 - 0x10480 */
|
||||||
|
char command_line[COMMAND_LINE_SIZE]; /* 0x10480 */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct parmarea parmarea;
|
extern struct parmarea parmarea;
|
||||||
|
@ -9,6 +9,4 @@
|
|||||||
|
|
||||||
#define COMMAND_LINE_SIZE 4096
|
#define COMMAND_LINE_SIZE 4096
|
||||||
|
|
||||||
#define ARCH_COMMAND_LINE_SIZE 896
|
|
||||||
|
|
||||||
#endif /* _UAPI_ASM_S390_SETUP_H */
|
#endif /* _UAPI_ASM_S390_SETUP_H */
|
||||||
|
@ -164,5 +164,6 @@ int main(void)
|
|||||||
DEFINE(OLDMEM_BASE, PARMAREA + offsetof(struct parmarea, oldmem_base));
|
DEFINE(OLDMEM_BASE, PARMAREA + offsetof(struct parmarea, oldmem_base));
|
||||||
DEFINE(OLDMEM_SIZE, PARMAREA + offsetof(struct parmarea, oldmem_size));
|
DEFINE(OLDMEM_SIZE, PARMAREA + offsetof(struct parmarea, oldmem_size));
|
||||||
DEFINE(COMMAND_LINE, PARMAREA + offsetof(struct parmarea, command_line));
|
DEFINE(COMMAND_LINE, PARMAREA + offsetof(struct parmarea, command_line));
|
||||||
|
DEFINE(MAX_COMMAND_LINE_SIZE, PARMAREA + offsetof(struct parmarea, max_command_line_size));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +280,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
|
|||||||
static void __init setup_boot_command_line(void)
|
static void __init setup_boot_command_line(void)
|
||||||
{
|
{
|
||||||
/* copy arch command line */
|
/* 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)
|
static void __init check_image_bootable(void)
|
||||||
|
@ -216,7 +216,9 @@ void *kexec_file_add_components(struct kimage *image,
|
|||||||
int (*add_kernel)(struct kimage *image,
|
int (*add_kernel)(struct kimage *image,
|
||||||
struct s390_load_data *data))
|
struct s390_load_data *data))
|
||||||
{
|
{
|
||||||
|
unsigned long max_command_line_size = LEGACY_COMMAND_LINE_SIZE;
|
||||||
struct s390_load_data data = {0};
|
struct s390_load_data data = {0};
|
||||||
|
unsigned long minsize;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
data.report = ipl_report_init(&ipl_block);
|
data.report = ipl_report_init(&ipl_block);
|
||||||
@ -227,11 +229,23 @@ void *kexec_file_add_components(struct kimage *image,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (image->kernel_buf_len < PARMAREA + sizeof(struct parmarea) ||
|
ret = -EINVAL;
|
||||||
image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE) {
|
minsize = PARMAREA + offsetof(struct parmarea, command_line);
|
||||||
ret = -EINVAL;
|
if (image->kernel_buf_len < minsize)
|
||||||
goto out;
|
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,
|
memcpy(data.parm->command_line, image->cmdline_buf,
|
||||||
image->cmdline_buf_len);
|
image->cmdline_buf_len);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user