[GIT PULL] s390 fixes for 6.2-rc7

From: Heiko Carstens
Date: Thu Feb 02 2023 - 15:09:19 EST


Hello Linus,

please pull a couple of s390 fixes.

Thanks,
Heiko

The following changes since commit 41e1992665a2701fa025a8b76970c43b4148446f:

s390: workaround invalid gcc-11 out of bounds read warning (2023-01-17 19:00:59 +0100)

are available in the Git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git tags/s390-6.2-4

for you to fetch changes up to 7ab41c2c08a32132ba8c14624910e2fe8ce4ba4b:

s390/decompressor: specify __decompress() buf len to avoid overflow (2023-01-31 18:54:21 +0100)

----------------------------------------------------------------
s390 fixes for 6.2-rc7

- With CONFIG_VMAP_STACK enabled it is not possible to load the s390
specific diag288_wdt watchdog module. 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 2aa14b1ab2c4
("zstd: import usptream v1.5.2").

----------------------------------------------------------------
Alexander Egorenkov (2):
watchdog: diag288_wdt: do not use stack buffers for hardware data
watchdog: diag288_wdt: fix __diag288() inline assembly

Vasily Gorbik (1):
s390/decompressor: specify __decompress() buf len to avoid overflow

arch/s390/boot/decompressor.c | 2 +-
drivers/watchdog/diag288_wdt.c | 15 ++++++++++++---
2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/s390/boot/decompressor.c b/arch/s390/boot/decompressor.c
index 8dcd7af2911a..b519a1f045d8 100644
--- a/arch/s390/boot/decompressor.c
+++ b/arch/s390/boot/decompressor.c
@@ -80,6 +80,6 @@ void *decompress_kernel(void)
void *output = (void *)decompress_offset;

__decompress(_compressed_start, _compressed_end - _compressed_start,
- NULL, NULL, output, 0, NULL, error);
+ NULL, NULL, output, vmlinux.image_size, NULL, error);
return output;
}
diff --git a/drivers/watchdog/diag288_wdt.c b/drivers/watchdog/diag288_wdt.c
index 4cb10877017c..6ca5d9515d85 100644
--- a/drivers/watchdog/diag288_wdt.c
+++ b/drivers/watchdog/diag288_wdt.c
@@ -86,7 +86,7 @@ static int __diag288(unsigned int func, unsigned int timeout,
"1:\n"
EX_TABLE(0b, 1b)
: "+d" (err) : "d"(__func), "d"(__timeout),
- "d"(__action), "d"(__len) : "1", "cc");
+ "d"(__action), "d"(__len) : "1", "cc", "memory");
return err;
}

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

watchdog_set_nowayout(&wdt_dev, nowayout_info);

if (MACHINE_IS_VM) {
- if (__diag288_vm(WDT_FUNC_INIT, 15,
- ebc_begin, sizeof(ebc_begin)) != 0) {
+ ebc_cmd = kmalloc(sizeof(ebc_begin), GFP_KERNEL);
+ if (!ebc_cmd) {
+ pr_err("The watchdog cannot be initialized\n");
+ return -ENOMEM;
+ }
+ memcpy(ebc_cmd, ebc_begin, sizeof(ebc_begin));
+ ret = __diag288_vm(WDT_FUNC_INIT, 15,
+ ebc_cmd, sizeof(ebc_begin));
+ kfree(ebc_cmd);
+ if (ret != 0) {
pr_err("The watchdog cannot be initialized\n");
return -EINVAL;
}