Skip to content

Commit 5ecb2da

Browse files
svens-s390Vasily Gorbik
authored andcommitted
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 <[email protected]> Reviewed-by: Heiko Carstens <[email protected]> Signed-off-by: Vasily Gorbik <[email protected]>
1 parent 277c838 commit 5ecb2da

File tree

7 files changed

+39
-34
lines changed

7 files changed

+39
-34
lines changed

arch/s390/boot/head.S

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -184,35 +184,23 @@ iplstart:
184184
bas %r14,.Lloader # load parameter file
185185
ltr %r2,%r2 # got anything ?
186186
bz .Lnopf
187-
chi %r2,895
188-
bnh .Lnotrunc
189-
la %r2,895
187+
l %r3,MAX_COMMAND_LINE_SIZE+ARCH_OFFSET-PARMAREA(%r12)
188+
ahi %r3,-1
189+
clr %r2,%r3
190+
bl .Lnotrunc
191+
lr %r2,%r3
190192
.Lnotrunc:
191193
l %r4,.Linitrd
192194
clc 0(3,%r4),.L_hdr # if it is HDRx
193195
bz .Lagain1 # skip dataset header
194196
clc 0(3,%r4),.L_eof # if it is EOFx
195197
bz .Lagain1 # skip dateset trailer
196-
la %r5,0(%r4,%r2)
197-
lr %r3,%r2
198-
la %r3,COMMAND_LINE-PARMAREA(%r12) # load adr. of command line
199-
mvc 0(256,%r3),0(%r4)
200-
mvc 256(256,%r3),256(%r4)
201-
mvc 512(256,%r3),512(%r4)
202-
mvc 768(122,%r3),768(%r4)
203-
slr %r0,%r0
204-
b .Lcntlp
205-
.Ldelspc:
206-
ic %r0,0(%r2,%r3)
207-
chi %r0,0x20 # is it a space ?
208-
be .Lcntlp
209-
ahi %r2,1
210-
b .Leolp
211-
.Lcntlp:
212-
brct %r2,.Ldelspc
213-
.Leolp:
214-
slr %r0,%r0
215-
stc %r0,0(%r2,%r3) # terminate buffer
198+
199+
lr %r5,%r2
200+
la %r6,COMMAND_LINE-PARMAREA(%r12)
201+
lr %r7,%r2
202+
ahi %r7,1
203+
mvcl %r6,%r4
216204
.Lnopf:
217205

218206
#
@@ -394,6 +382,7 @@ SYM_DATA_START(parmarea)
394382
.quad 0 # OLDMEM_BASE
395383
.quad 0 # OLDMEM_SIZE
396384
.quad kernel_version # points to kernel version string
385+
.quad COMMAND_LINE_SIZE
397386

398387
.org COMMAND_LINE
399388
.byte "root=/dev/ram0 ro"

arch/s390/boot/ipl_parm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,10 @@ static inline int has_ebcdic_char(const char *str)
170170

171171
void setup_boot_command_line(void)
172172
{
173-
parmarea.command_line[ARCH_COMMAND_LINE_SIZE - 1] = 0;
173+
parmarea.command_line[COMMAND_LINE_SIZE - 1] = 0;
174174
/* convert arch command line to ascii if necessary */
175175
if (has_ebcdic_char(parmarea.command_line))
176-
EBCASC(parmarea.command_line, ARCH_COMMAND_LINE_SIZE);
176+
EBCASC(parmarea.command_line, COMMAND_LINE_SIZE);
177177
/* copy arch command line */
178178
strcpy(early_command_line, strim(parmarea.command_line));
179179

arch/s390/include/asm/setup.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#define STARTUP_NORMAL_OFFSET 0x10000
4343
#define STARTUP_KDUMP_OFFSET 0x10010
4444

45+
#define LEGACY_COMMAND_LINE_SIZE 896
46+
4547
#ifndef __ASSEMBLY__
4648

4749
#include <asm/lowcore.h>
@@ -54,8 +56,9 @@ struct parmarea {
5456
unsigned long oldmem_base; /* 0x10418 */
5557
unsigned long oldmem_size; /* 0x10420 */
5658
unsigned long kernel_version; /* 0x10428 */
57-
char pad1[0x10480 - 0x10430]; /* 0x10430 - 0x10480 */
58-
char command_line[ARCH_COMMAND_LINE_SIZE]; /* 0x10480 */
59+
unsigned long max_command_line_size; /* 0x10430 */
60+
char pad1[0x10480-0x10438]; /* 0x10438 - 0x10480 */
61+
char command_line[COMMAND_LINE_SIZE]; /* 0x10480 */
5962
};
6063

6164
extern struct parmarea parmarea;

arch/s390/include/uapi/asm/setup.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,4 @@
99

1010
#define COMMAND_LINE_SIZE 4096
1111

12-
#define ARCH_COMMAND_LINE_SIZE 896
13-
1412
#endif /* _UAPI_ASM_S390_SETUP_H */

arch/s390/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,5 +164,6 @@ int main(void)
164164
DEFINE(OLDMEM_BASE, PARMAREA + offsetof(struct parmarea, oldmem_base));
165165
DEFINE(OLDMEM_SIZE, PARMAREA + offsetof(struct parmarea, oldmem_size));
166166
DEFINE(COMMAND_LINE, PARMAREA + offsetof(struct parmarea, command_line));
167+
DEFINE(MAX_COMMAND_LINE_SIZE, PARMAREA + offsetof(struct parmarea, max_command_line_size));
167168
return 0;
168169
}

arch/s390/kernel/early.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
280280
static void __init setup_boot_command_line(void)
281281
{
282282
/* copy arch command line */
283-
strlcpy(boot_command_line, early_command_line, ARCH_COMMAND_LINE_SIZE);
283+
strlcpy(boot_command_line, early_command_line, COMMAND_LINE_SIZE);
284284
}
285285

286286
static void __init check_image_bootable(void)

arch/s390/kernel/machine_kexec_file.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,9 @@ void *kexec_file_add_components(struct kimage *image,
216216
int (*add_kernel)(struct kimage *image,
217217
struct s390_load_data *data))
218218
{
219+
unsigned long max_command_line_size = LEGACY_COMMAND_LINE_SIZE;
219220
struct s390_load_data data = {0};
221+
unsigned long minsize;
220222
int ret;
221223

222224
data.report = ipl_report_init(&ipl_block);
@@ -227,11 +229,23 @@ void *kexec_file_add_components(struct kimage *image,
227229
if (ret)
228230
goto out;
229231

230-
if (image->kernel_buf_len < PARMAREA + sizeof(struct parmarea) ||
231-
image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE) {
232-
ret = -EINVAL;
232+
ret = -EINVAL;
233+
minsize = PARMAREA + offsetof(struct parmarea, command_line);
234+
if (image->kernel_buf_len < minsize)
233235
goto out;
234-
}
236+
237+
if (data.parm->max_command_line_size)
238+
max_command_line_size = data.parm->max_command_line_size;
239+
240+
if (minsize + max_command_line_size < minsize)
241+
goto out;
242+
243+
if (image->kernel_buf_len < minsize + max_command_line_size)
244+
goto out;
245+
246+
if (image->cmdline_buf_len >= max_command_line_size)
247+
goto out;
248+
235249
memcpy(data.parm->command_line, image->cmdline_buf,
236250
image->cmdline_buf_len);
237251

0 commit comments

Comments
 (0)