Skip to content

Commit addfba1

Browse files
committed
Merge tag 's390-6.2-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Heiko Carstens: - With CONFIG_VMAP_STACK enabled it is not possible to load the s390 specific diag288_wdt watchdog module. The reason is that a pointer to a string is passed to an inline assembly; this string however is located on the stack, while the instruction within the inline assembly expects a physicial address. Fix this by copying the string to a kmalloc'ed buffer. - The diag288_wdt watchdog module does not indicate that it accesses memory from an inline assembly, which it does. Add "memory" to the clobber list to prevent the compiler from optimizing code incorrectly away. - Pass size of the uncompressed kernel image to __decompress() call. Otherwise the kernel image decompressor may corrupt/overwrite an initrd. This was reported to happen on s390 after commit 2aa14b1 ("zstd: import usptream v1.5.2"). * tag 's390-6.2-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/decompressor: specify __decompress() buf len to avoid overflow watchdog: diag288_wdt: fix __diag288() inline assembly watchdog: diag288_wdt: do not use stack buffers for hardware data
2 parents 870bb76 + 7ab41c2 commit addfba1

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

arch/s390/boot/decompressor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,6 @@ void *decompress_kernel(void)
8080
void *output = (void *)decompress_offset;
8181

8282
__decompress(_compressed_start, _compressed_end - _compressed_start,
83-
NULL, NULL, output, 0, NULL, error);
83+
NULL, NULL, output, vmlinux.image_size, NULL, error);
8484
return output;
8585
}

drivers/watchdog/diag288_wdt.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static int __diag288(unsigned int func, unsigned int timeout,
8686
"1:\n"
8787
EX_TABLE(0b, 1b)
8888
: "+d" (err) : "d"(__func), "d"(__timeout),
89-
"d"(__action), "d"(__len) : "1", "cc");
89+
"d"(__action), "d"(__len) : "1", "cc", "memory");
9090
return err;
9191
}
9292

@@ -268,12 +268,21 @@ static int __init diag288_init(void)
268268
char ebc_begin[] = {
269269
194, 197, 199, 201, 213
270270
};
271+
char *ebc_cmd;
271272

272273
watchdog_set_nowayout(&wdt_dev, nowayout_info);
273274

274275
if (MACHINE_IS_VM) {
275-
if (__diag288_vm(WDT_FUNC_INIT, 15,
276-
ebc_begin, sizeof(ebc_begin)) != 0) {
276+
ebc_cmd = kmalloc(sizeof(ebc_begin), GFP_KERNEL);
277+
if (!ebc_cmd) {
278+
pr_err("The watchdog cannot be initialized\n");
279+
return -ENOMEM;
280+
}
281+
memcpy(ebc_cmd, ebc_begin, sizeof(ebc_begin));
282+
ret = __diag288_vm(WDT_FUNC_INIT, 15,
283+
ebc_cmd, sizeof(ebc_begin));
284+
kfree(ebc_cmd);
285+
if (ret != 0) {
277286
pr_err("The watchdog cannot be initialized\n");
278287
return -EINVAL;
279288
}

0 commit comments

Comments
 (0)