History

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().

Sven Schnelle committed 5 years ago

Commit 5ecb2da1 parent 277c8387 files · +39 −34Browse files

Unified · Split

7 files
  1. arch/s390/boot/head.S +12 −23
  2. arch/s390/boot/ipl_parm.c +2 −2
  3. arch/s390/include/asm/setup.h +5 −2
  4. arch/s390/include/uapi/asm/setup.h +0 −2
  5. arch/s390/kernel/asm-offsets.c +1 −0
  6. arch/s390/kernel/early.c +1 −1
  7. arch/s390/kernel/machine_kexec_file.c +18 −4
arch/s390/boot/head.S+12−23
@@ -184,35 +184,23 @@ iplstart: · 183 unmodified lines
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) · 175 unmodified lines
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+2−2
@@ -170,10 +170,10 @@ static inline int has_ebcdic_char(const char *str) · 169 unmodified lines
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+5−2
@@ -42,6 +42,8 @@ · 41 unmodified lines
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 { · 6 unmodified lines
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+0−2
@@ -9,6 +9,4 @@ · 8 unmodified lines
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+1−0
@@ -164,5 +164,6 @@ int main(void) · 163 unmodified lines
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+1−1
@@ -280,7 +280,7 @@ char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; · 279 unmodified lines
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+18−4
@@ -216,7 +216,9 @@ void *kexec_file_add_components(struct kimage *image, · 215 unmodified lines
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, · 4 unmodified lines
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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t