2023-11-15 20:37:09

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 00/32] kmsan: Enable on s390

Hi,

This series provides the minimal support for Kernel Memory Sanitizer on
s390. Kernel Memory Sanitizer is clang-only instrumentation for finding
accesses to uninitialized memory. The clang support for s390 has already
been merged [1].

With this series, I can successfully boot s390 defconfig and
debug_defconfig with kmsan.panic=1. The tool found one real
s390-specific bug (fixed in master).

Best regards,
Ilya

[1] https://reviews.llvm.org/D148596

Ilya Leoshkevich (32):
ftrace: Unpoison ftrace_regs in ftrace_ops_list_func()
kmsan: Make the tests compatible with kmsan.panic=1
kmsan: Disable KMSAN when DEFERRED_STRUCT_PAGE_INIT is enabled
kmsan: Increase the maximum store size to 4096
kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces
kmsan: Fix kmsan_copy_to_user() on arches with overlapping address
spaces
kmsan: Remove a useless assignment from
kmsan_vmap_pages_range_noflush()
kmsan: Remove an x86-specific #include from kmsan.h
kmsan: Introduce kmsan_memmove_metadata()
kmsan: Expose kmsan_get_metadata()
kmsan: Export panic_on_kmsan
kmsan: Allow disabling KMSAN checks for the current task
kmsan: Support SLAB_POISON
kmsan: Use ALIGN_DOWN() in kmsan_get_metadata()
mm: slub: Let KMSAN access metadata
mm: kfence: Disable KMSAN when checking the canary
lib/string: Add KMSAN support to strlcpy() and strlcat()
lib/zlib: Unpoison DFLTCC output buffers
kmsan: Accept ranges starting with 0 on s390
s390: Turn off KMSAN for boot, vdso and purgatory
s390: Use a larger stack for KMSAN
s390/boot: Add the KMSAN runtime stub
s390/checksum: Add a KMSAN check
s390/cpacf: Unpoison the results of cpacf_trng()
s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler()
s390/mm: Define KMSAN metadata for vmalloc and modules
s390/string: Add KMSAN support
s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs
s390/uaccess: Add KMSAN support to put_user() and get_user()
s390/unwind: Disable KMSAN checks
s390: Implement the architecture-specific kmsan functions
kmsan: Enable on s390

Documentation/dev-tools/kmsan.rst | 4 +-
arch/s390/Kconfig | 1 +
arch/s390/Makefile | 2 +-
arch/s390/boot/Makefile | 2 +
arch/s390/boot/kmsan.c | 6 ++
arch/s390/boot/startup.c | 8 ++
arch/s390/boot/string.c | 15 ++++
arch/s390/include/asm/checksum.h | 2 +
arch/s390/include/asm/cpacf.h | 2 +
arch/s390/include/asm/kmsan.h | 36 +++++++++
arch/s390/include/asm/pgtable.h | 10 +++
arch/s390/include/asm/string.h | 49 ++++++++-----
arch/s390/include/asm/thread_info.h | 2 +-
arch/s390/include/asm/uaccess.h | 110 ++++++++++++++++++++--------
arch/s390/kernel/ftrace.c | 1 +
arch/s390/kernel/traps.c | 2 +
arch/s390/kernel/unwind_bc.c | 2 +
arch/s390/kernel/vdso32/Makefile | 1 +
arch/s390/kernel/vdso64/Makefile | 1 +
arch/s390/purgatory/Makefile | 1 +
include/linux/kmsan-checks.h | 26 +++++++
include/linux/kmsan.h | 14 ++++
include/linux/kmsan_types.h | 2 +-
kernel/trace/ftrace.c | 1 +
lib/string.c | 6 ++
lib/zlib_dfltcc/dfltcc.h | 1 +
lib/zlib_dfltcc/dfltcc_util.h | 23 ++++++
mm/Kconfig | 1 +
mm/kfence/core.c | 5 +-
mm/kmsan/core.c | 2 +-
mm/kmsan/hooks.c | 30 +++++++-
mm/kmsan/init.c | 4 +-
mm/kmsan/instrumentation.c | 11 +--
mm/kmsan/kmsan.h | 3 +-
mm/kmsan/kmsan_test.c | 5 ++
mm/kmsan/report.c | 7 +-
mm/kmsan/shadow.c | 9 +--
mm/slub.c | 5 +-
38 files changed, 331 insertions(+), 81 deletions(-)
create mode 100644 arch/s390/boot/kmsan.c
create mode 100644 arch/s390/include/asm/kmsan.h

--
2.41.0


2023-11-15 20:37:16

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 23/32] s390/checksum: Add a KMSAN check

Add a KMSAN check to the CKSM inline assembly, similar to how it was
done for ASAN in commit e42ac7789df6 ("s390/checksum: always use cksm
instruction").

Acked-by: Alexander Gordeev <[email protected]>
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/include/asm/checksum.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index 69837eec2ff5..55ba0ddd8eab 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -13,6 +13,7 @@
#define _S390_CHECKSUM_H

#include <linux/kasan-checks.h>
+#include <linux/kmsan-checks.h>
#include <linux/in6.h>

/*
@@ -35,6 +36,7 @@ static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
};

kasan_check_read(buff, len);
+ kmsan_check_memory(buff, len);
asm volatile(
"0: cksm %[sum],%[rp]\n"
" jo 0b\n"
--
2.41.0

2023-11-15 20:37:16

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 21/32] s390: Use a larger stack for KMSAN

Adjust the stack size for the KMSAN-enabled kernel like it was done
for the KASAN-enabled one in commit 7fef92ccadd7 ("s390/kasan: double
the stack size"). Both tools have similar requirements.

Reviewed-by: Alexander Gordeev <[email protected]>
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/Makefile | 2 +-
arch/s390/include/asm/thread_info.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 73873e451686..a7f5386d25ad 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -34,7 +34,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option
KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds)

UTS_MACHINE := s390x
-STACK_SIZE := $(if $(CONFIG_KASAN),65536,16384)
+STACK_SIZE := $(if $(CONFIG_KASAN),65536,$(if $(CONFIG_KMSAN),65536,16384))
CHECKFLAGS += -D__s390__ -D__s390x__

export LD_BFD
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index a674c7d25da5..d02a709717b8 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -16,7 +16,7 @@
/*
* General size of kernel stacks
*/
-#ifdef CONFIG_KASAN
+#if defined(CONFIG_KASAN) || defined(CONFIG_KMSAN)
#define THREAD_SIZE_ORDER 4
#else
#define THREAD_SIZE_ORDER 2
--
2.41.0

2023-11-15 20:37:22

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 10/32] kmsan: Expose kmsan_get_metadata()

Each s390 CPU has lowcore pages associated with it. Each CPU sees its
own lowcore at virtual address 0 through a hardware mechanism called
prefixing. Additionally, all lowcores are mapped to non-0 virtual
addresses stored in the lowcore_ptr[] array.

When lowcore is accessed through virtual address 0, one needs to
resolve metadata for lowcore_ptr[raw_smp_processor_id()].

Expose kmsan_get_metadata() to make it possible to do this from the
arch code.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
include/linux/kmsan.h | 14 ++++++++++++++
mm/kmsan/instrumentation.c | 1 +
mm/kmsan/kmsan.h | 1 -
3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
index e0c23a32cdf0..ff8fd95733fa 100644
--- a/include/linux/kmsan.h
+++ b/include/linux/kmsan.h
@@ -230,6 +230,15 @@ void kmsan_handle_urb(const struct urb *urb, bool is_out);
*/
void kmsan_unpoison_entry_regs(const struct pt_regs *regs);

+/**
+ * kmsan_get_metadata() - Return a pointer to KMSAN shadow or origins.
+ * @addr: kernel address.
+ * @is_origin: whether to return origins or shadow.
+ *
+ * Return NULL if metadata cannot be found.
+ */
+void *kmsan_get_metadata(void *addr, bool is_origin);
+
#else

static inline void kmsan_init_shadow(void)
@@ -329,6 +338,11 @@ static inline void kmsan_unpoison_entry_regs(const struct pt_regs *regs)
{
}

+static inline void *kmsan_get_metadata(void *addr, bool is_origin)
+{
+ return NULL;
+}
+
#endif

#endif /* _LINUX_KMSAN_H */
diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c
index 8a1bbbc723ab..94b49fac9d8b 100644
--- a/mm/kmsan/instrumentation.c
+++ b/mm/kmsan/instrumentation.c
@@ -14,6 +14,7 @@

#include "kmsan.h"
#include <linux/gfp.h>
+#include <linux/kmsan.h>
#include <linux/kmsan_string.h>
#include <linux/mm.h>
#include <linux/uaccess.h>
diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h
index 3c0476d8b765..2c743911a8c4 100644
--- a/mm/kmsan/kmsan.h
+++ b/mm/kmsan/kmsan.h
@@ -66,7 +66,6 @@ struct shadow_origin_ptr {

struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *addr, u64 size,
bool store);
-void *kmsan_get_metadata(void *addr, bool is_origin);
void __init kmsan_init_alloc_meta_for_range(void *start, void *end);

enum kmsan_bug_reason {
--
2.41.0

2023-11-15 20:37:22

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 14/32] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata()

Improve the readability by replacing the custom aligning logic with
ALIGN_DOWN(). Unlike other places where a similar sequence is used,
there is no size parameter that needs to be adjusted, so the standard
macro fits.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
mm/kmsan/shadow.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c
index 2d57408c78ae..9c58f081d84f 100644
--- a/mm/kmsan/shadow.c
+++ b/mm/kmsan/shadow.c
@@ -123,14 +123,12 @@ struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *address, u64 size,
*/
void *kmsan_get_metadata(void *address, bool is_origin)
{
- u64 addr = (u64)address, pad, off;
+ u64 addr = (u64)address, off;
struct page *page;
void *ret;

- if (is_origin && !IS_ALIGNED(addr, KMSAN_ORIGIN_SIZE)) {
- pad = addr % KMSAN_ORIGIN_SIZE;
- addr -= pad;
- }
+ if (is_origin)
+ addr = ALIGN_DOWN(addr, KMSAN_ORIGIN_SIZE);
address = (void *)addr;
if (kmsan_internal_is_vmalloc_addr(address) ||
kmsan_internal_is_module_addr(address))
--
2.41.0

2023-11-15 20:37:23

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 15/32] mm: slub: Let KMSAN access metadata

Building the kernel with CONFIG_SLUB_DEBUG and CONFIG_KMSAN causes
KMSAN to complain about touching redzones in kfree().

Fix by extending the existing KASAN-related metadata_access_enable()
and metadata_access_disable() functions to KMSAN.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
mm/slub.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/mm/slub.c b/mm/slub.c
index 8d9aa4d7cb7e..0b52bff99326 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -700,10 +700,12 @@ static int disable_higher_order_debug;
static inline void metadata_access_enable(void)
{
kasan_disable_current();
+ kmsan_disable_current();
}

static inline void metadata_access_disable(void)
{
+ kmsan_enable_current();
kasan_enable_current();
}

--
2.41.0

2023-11-15 20:37:26

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 25/32] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler()

s390 uses assembly code to initialize ftrace_regs and call
kprobe_ftrace_handler(). Therefore, from the KMSAN's point of view,
ftrace_regs is poisoned on kprobe_ftrace_handler() entry. This causes
KMSAN warnings when running the ftrace testsuite.

Fix by trusting the assembly code and always unpoisoning ftrace_regs in
kprobe_ftrace_handler().

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/kernel/ftrace.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index c46381ea04ec..3bad34eaa51e 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -300,6 +300,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
if (bit < 0)
return;

+ kmsan_unpoison_memory(fregs, sizeof(*fregs));
regs = ftrace_get_regs(fregs);
p = get_kprobe((kprobe_opcode_t *)ip);
if (!regs || unlikely(!p) || kprobe_disabled(p))
--
2.41.0

2023-11-15 20:37:27

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 16/32] mm: kfence: Disable KMSAN when checking the canary

KMSAN warns about check_canary() accessing the canary.

The reason is that, even though set_canary() is properly instrumented
and sets shadow, slub explicitly poisons the canary's address range
afterwards.

Unpoisoning the canary is not the right thing to do: only
check_canary() is supposed to ever touch it. Instead, disable KMSAN
checks around canary read accesses.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
mm/kfence/core.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 3872528d0963..a2ea8e5a1ad9 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -306,7 +306,7 @@ metadata_update_state(struct kfence_metadata *meta, enum kfence_object_state nex
}

/* Check canary byte at @addr. */
-static inline bool check_canary_byte(u8 *addr)
+__no_kmsan_checks static inline bool check_canary_byte(u8 *addr)
{
struct kfence_metadata *meta;
unsigned long flags;
@@ -341,7 +341,8 @@ static inline void set_canary(const struct kfence_metadata *meta)
*((u64 *)addr) = KFENCE_CANARY_PATTERN_U64;
}

-static inline void check_canary(const struct kfence_metadata *meta)
+__no_kmsan_checks static inline void
+check_canary(const struct kfence_metadata *meta)
{
const unsigned long pageaddr = ALIGN_DOWN(meta->addr, PAGE_SIZE);
unsigned long addr = pageaddr;
--
2.41.0

2023-11-15 20:37:29

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 17/32] lib/string: Add KMSAN support to strlcpy() and strlcat()

Currently KMSAN does not fully propagate metadata in strlcpy() and
strlcat(), because they are built with -ffreestanding and call
memcpy(). In this combination memcpy() calls are not instrumented.

Fix by copying the metadata manually. Add the __STDC_HOSTED__ #ifdef in
case the code is compiled with different flags in the future.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
lib/string.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/lib/string.c b/lib/string.c
index be26623953d2..e83c6dd77ec6 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -111,6 +111,9 @@ size_t strlcpy(char *dest, const char *src, size_t size)
if (size) {
size_t len = (ret >= size) ? size - 1 : ret;
__builtin_memcpy(dest, src, len);
+#if __STDC_HOSTED__ == 0
+ kmsan_memmove_metadata(dest, src, len);
+#endif
dest[len] = '\0';
}
return ret;
@@ -261,6 +264,9 @@ size_t strlcat(char *dest, const char *src, size_t count)
if (len >= count)
len = count-1;
__builtin_memcpy(dest, src, len);
+#if __STDC_HOSTED__ == 0
+ kmsan_memmove_metadata(dest, src, len);
+#endif
dest[len] = 0;
return res;
}
--
2.41.0

2023-11-15 20:37:29

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 19/32] kmsan: Accept ranges starting with 0 on s390

On s390 the virtual address 0 is valid (current CPU's lowcore is mapped
there), therefore KMSAN should not complain about it.

Disable the respective check on s390. There doesn't seem to be a
Kconfig option to describe this situation, so explicitly check for
s390.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
mm/kmsan/init.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/mm/kmsan/init.c b/mm/kmsan/init.c
index ffedf4dbc49d..14f4a432fddd 100644
--- a/mm/kmsan/init.c
+++ b/mm/kmsan/init.c
@@ -33,7 +33,9 @@ static void __init kmsan_record_future_shadow_range(void *start, void *end)
bool merged = false;

KMSAN_WARN_ON(future_index == NUM_FUTURE_RANGES);
- KMSAN_WARN_ON((nstart >= nend) || !nstart || !nend);
+ KMSAN_WARN_ON((nstart >= nend) ||
+ (!IS_ENABLED(CONFIG_S390) && !nstart) ||
+ !nend);
nstart = ALIGN_DOWN(nstart, PAGE_SIZE);
nend = ALIGN(nend, PAGE_SIZE);

--
2.41.0

2023-11-15 20:37:32

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 18/32] lib/zlib: Unpoison DFLTCC output buffers

The constraints of the DFLTCC inline assembly are not precise: they
do not communicate the size of the output buffers to the compiler, so
it cannot automatically instrument it.

Add the manual kmsan_unpoison_memory() calls for the output buffers.
The logic is the same as in [1].

[1] https://github.com/zlib-ng/zlib-ng/commit/1f5ddcc009ac3511e99fc88736a9e1a6381168c5

Reported-by: Alexander Gordeev <[email protected]>
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
lib/zlib_dfltcc/dfltcc.h | 1 +
lib/zlib_dfltcc/dfltcc_util.h | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)

diff --git a/lib/zlib_dfltcc/dfltcc.h b/lib/zlib_dfltcc/dfltcc.h
index b96232bdd44d..0f2a16d7a48a 100644
--- a/lib/zlib_dfltcc/dfltcc.h
+++ b/lib/zlib_dfltcc/dfltcc.h
@@ -80,6 +80,7 @@ struct dfltcc_param_v0 {
uint8_t csb[1152];
};

+static_assert(offsetof(struct dfltcc_param_v0, csb) == 384);
static_assert(sizeof(struct dfltcc_param_v0) == 1536);

#define CVT_CRC32 0
diff --git a/lib/zlib_dfltcc/dfltcc_util.h b/lib/zlib_dfltcc/dfltcc_util.h
index 4a46b5009f0d..ce2e039a55b5 100644
--- a/lib/zlib_dfltcc/dfltcc_util.h
+++ b/lib/zlib_dfltcc/dfltcc_util.h
@@ -2,6 +2,7 @@
#ifndef DFLTCC_UTIL_H
#define DFLTCC_UTIL_H

+#include "dfltcc.h"
#include <linux/zutil.h>

/*
@@ -20,6 +21,7 @@ typedef enum {
#define DFLTCC_CMPR 2
#define DFLTCC_XPND 4
#define HBT_CIRCULAR (1 << 7)
+#define DFLTCC_FN_MASK ((1 << 7) - 1)
#define HB_BITS 15
#define HB_SIZE (1 << HB_BITS)

@@ -34,6 +36,7 @@ static inline dfltcc_cc dfltcc(
)
{
Byte *t2 = op1 ? *op1 : NULL;
+ unsigned char *orig_t2 = t2;
size_t t3 = len1 ? *len1 : 0;
const Byte *t4 = op2 ? *op2 : NULL;
size_t t5 = len2 ? *len2 : 0;
@@ -59,6 +62,26 @@ static inline dfltcc_cc dfltcc(
: "cc", "memory");
t2 = r2; t3 = r3; t4 = r4; t5 = r5;

+ switch (fn & DFLTCC_FN_MASK) {
+ case DFLTCC_QAF:
+ kmsan_unpoison_memory(param, sizeof(struct dfltcc_qaf_param));
+ break;
+ case DFLTCC_GDHT:
+ kmsan_unpoison_memory(param, offsetof(struct dfltcc_param_v0, csb));
+ break;
+ case DFLTCC_CMPR:
+ kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
+ kmsan_unpoison_memory(
+ orig_t2,
+ t2 - orig_t2 +
+ (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));
+ break;
+ case DFLTCC_XPND:
+ kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
+ kmsan_unpoison_memory(orig_t2, t2 - orig_t2);
+ break;
+ }
+
if (op1)
*op1 = t2;
if (len1)
--
2.41.0

2023-11-15 20:37:33

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 22/32] s390/boot: Add the KMSAN runtime stub

It should be possible to have inline functions in the s390 header
files, which call kmsan_unpoison_memory(). The problem is that these
header files might be included by the decompressor, which does not
contain KMSAN runtime, causing linker errors.

Not compiling these calls if __SANITIZE_MEMORY__ is not defined -
either by changing kmsan-checks.h or at the call sites - may cause
unintended side effects, since calling these functions from an
uninstrumented code that is linked into the kernel is valid use case.

One might want to explicitly distinguish between the kernel and the
decompressor. Checking for a decompressor-specific #define is quite
heavy-handed, and will have to be done at all call sites.

A more generic approach is to provide a dummy kmsan_unpoison_memory()
definition. This produces some runtime overhead, but only when building
with CONFIG_KMSAN. The benefit is that it does not disturb the existing
KMSAN build logic and call sites don't need to be changed.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/boot/Makefile | 1 +
arch/s390/boot/kmsan.c | 6 ++++++
2 files changed, 7 insertions(+)
create mode 100644 arch/s390/boot/kmsan.c

diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 5a05c927f703..826005e2e3aa 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -43,6 +43,7 @@ obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) +=
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+obj-$(CONFIG_KMSAN) += kmsan.o
obj-all := $(obj-y) piggy.o syms.o

targets := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
diff --git a/arch/s390/boot/kmsan.c b/arch/s390/boot/kmsan.c
new file mode 100644
index 000000000000..e7b3ac48143e
--- /dev/null
+++ b/arch/s390/boot/kmsan.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kmsan-checks.h>
+
+void kmsan_unpoison_memory(const void *address, size_t size)
+{
+}
--
2.41.0

2023-11-15 20:37:42

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 26/32] s390/mm: Define KMSAN metadata for vmalloc and modules

The pages for the KMSAN metadata associated with most kernel mappings
are taken from memblock by the common code. However, vmalloc and module
metadata needs to be defined by the architectures.

Be a little bit more careful than x86: allocate exactly MODULES_LEN
for the module shadow and origins, and then take 2/3 of vmalloc for
the vmalloc shadow and origins. This ensures that users passing small
vmalloc= values on the command line do not cause module metadata
collisions.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/boot/startup.c | 8 ++++++++
arch/s390/include/asm/pgtable.h | 10 ++++++++++
2 files changed, 18 insertions(+)

diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 8104e0e3d188..297c1062372a 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -253,9 +253,17 @@ static unsigned long setup_kernel_memory_layout(void)
MODULES_END = round_down(__abs_lowcore, _SEGMENT_SIZE);
MODULES_VADDR = MODULES_END - MODULES_LEN;
VMALLOC_END = MODULES_VADDR;
+#ifdef CONFIG_KMSAN
+ VMALLOC_END -= MODULES_LEN * 2;
+#endif

/* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE));
+#ifdef CONFIG_KMSAN
+ /* take 2/3 of vmalloc area for KMSAN shadow and origins */
+ vmalloc_size = round_down(vmalloc_size / 3, PAGE_SIZE);
+ VMALLOC_END -= vmalloc_size * 2;
+#endif
VMALLOC_START = VMALLOC_END - vmalloc_size;

/* split remaining virtual space between 1:1 mapping & vmemmap array */
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 601e87fa8a9a..d764abeb9e6d 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -107,6 +107,16 @@ static inline int is_module_addr(void *addr)
return 1;
}

+#ifdef CONFIG_KMSAN
+#define KMSAN_VMALLOC_SIZE (VMALLOC_END - VMALLOC_START)
+#define KMSAN_VMALLOC_SHADOW_START VMALLOC_END
+#define KMSAN_VMALLOC_ORIGIN_START (KMSAN_VMALLOC_SHADOW_START + \
+ KMSAN_VMALLOC_SIZE)
+#define KMSAN_MODULES_SHADOW_START (KMSAN_VMALLOC_ORIGIN_START + \
+ KMSAN_VMALLOC_SIZE)
+#define KMSAN_MODULES_ORIGIN_START (KMSAN_MODULES_SHADOW_START + MODULES_LEN)
+#endif
+
/*
* A 64 bit pagetable entry of S390 has following format:
* | PFRA |0IPC| OS |
--
2.41.0

2023-11-15 20:37:46

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 27/32] s390/string: Add KMSAN support

Add KMSAN support for the s390 implementations of the string functions.
Do this similar to how it's already done for KASAN, except that the
optimized memset{16,32,64}() functions need to be disabled: it's
important for KMSAN to know that they initialized something.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/boot/string.c | 15 +++++++++++
arch/s390/include/asm/string.h | 49 ++++++++++++++++++++--------------
2 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index faccb33b462c..6d886c84075b 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -4,8 +4,14 @@
#include <linux/errno.h>
#undef CONFIG_KASAN
#undef CONFIG_KASAN_GENERIC
+#undef CONFIG_KMSAN
#include "../lib/string.c"

+/*
+ * Duplicate some functions from the common lib/string.c
+ * instead of fully including it.
+ */
+
int strncmp(const char *cs, const char *ct, size_t count)
{
unsigned char c1, c2;
@@ -22,6 +28,15 @@ int strncmp(const char *cs, const char *ct, size_t count)
return 0;
}

+void *memset64(uint64_t *s, uint64_t v, size_t count)
+{
+ uint64_t *xs = s;
+
+ while (count--)
+ *xs++ = v;
+ return s;
+}
+
char *skip_spaces(const char *str)
{
while (isspace(*str))
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index 351685de53d2..94925024cb26 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -15,15 +15,12 @@
#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
#define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */
#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
-#define __HAVE_ARCH_MEMSET16 /* arch function */
-#define __HAVE_ARCH_MEMSET32 /* arch function */
-#define __HAVE_ARCH_MEMSET64 /* arch function */

void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
void *memmove(void *dest, const void *src, size_t n);

-#ifndef CONFIG_KASAN
+#if !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN)
#define __HAVE_ARCH_MEMCHR /* inline & arch function */
#define __HAVE_ARCH_MEMCMP /* arch function */
#define __HAVE_ARCH_MEMSCAN /* inline & arch function */
@@ -36,6 +33,9 @@ void *memmove(void *dest, const void *src, size_t n);
#define __HAVE_ARCH_STRNCPY /* arch function */
#define __HAVE_ARCH_STRNLEN /* inline & arch function */
#define __HAVE_ARCH_STRSTR /* arch function */
+#define __HAVE_ARCH_MEMSET16 /* arch function */
+#define __HAVE_ARCH_MEMSET32 /* arch function */
+#define __HAVE_ARCH_MEMSET64 /* arch function */

/* Prototypes for non-inlined arch strings functions. */
int memcmp(const void *s1, const void *s2, size_t n);
@@ -44,7 +44,7 @@ size_t strlcat(char *dest, const char *src, size_t n);
char *strncat(char *dest, const char *src, size_t n);
char *strncpy(char *dest, const char *src, size_t n);
char *strstr(const char *s1, const char *s2);
-#endif /* !CONFIG_KASAN */
+#endif /* !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN) */

#undef __HAVE_ARCH_STRCHR
#undef __HAVE_ARCH_STRNCHR
@@ -74,21 +74,6 @@ void *__memset16(uint16_t *s, uint16_t v, size_t count);
void *__memset32(uint32_t *s, uint32_t v, size_t count);
void *__memset64(uint64_t *s, uint64_t v, size_t count);

-static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
-{
- return __memset16(s, v, count * sizeof(v));
-}
-
-static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
-{
- return __memset32(s, v, count * sizeof(v));
-}
-
-static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
-{
- return __memset64(s, v, count * sizeof(v));
-}
-
#if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))

#ifdef __HAVE_ARCH_MEMCHR
@@ -194,6 +179,27 @@ static inline size_t strnlen(const char * s, size_t n)
return end - s;
}
#endif
+
+#ifdef __HAVE_ARCH_MEMSET16
+static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
+{
+ return __memset16(s, v, count * sizeof(v));
+}
+#endif
+
+#ifdef __HAVE_ARCH_MEMSET32
+static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
+{
+ return __memset32(s, v, count * sizeof(v));
+}
+#endif
+
+#ifdef __HAVE_ARCH_MEMSET64
+static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
+{
+ return __memset64(s, v, count * sizeof(v));
+}
+#endif
#else /* IN_ARCH_STRING_C */
void *memchr(const void * s, int c, size_t n);
void *memscan(void *s, int c, size_t n);
@@ -201,6 +207,9 @@ char *strcat(char *dst, const char *src);
char *strcpy(char *dst, const char *src);
size_t strlen(const char *s);
size_t strnlen(const char * s, size_t n);
+void *memset16(uint16_t *s, uint16_t v, size_t count);
+void *memset32(uint32_t *s, uint32_t v, size_t count);
+void *memset64(uint64_t *s, uint64_t v, size_t count);
#endif /* !IN_ARCH_STRING_C */

#endif /* __S390_STRING_H_ */
--
2.41.0

2023-11-15 20:37:46

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 32/32] kmsan: Enable on s390

Now that everything else is in place, enable KMSAN in Kconfig.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/Kconfig | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 3bec98d20283..160ad2220c53 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -153,6 +153,7 @@ config S390
select HAVE_ARCH_KASAN
select HAVE_ARCH_KASAN_VMALLOC
select HAVE_ARCH_KCSAN
+ select HAVE_ARCH_KMSAN
select HAVE_ARCH_KFENCE
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP_FILTER
--
2.41.0

2023-11-15 20:37:46

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 30/32] s390/unwind: Disable KMSAN checks

The unwind code can read uninitialized frames. Furthermore, even in
the good case, KMSAN does not emit shadow for backchains. Therefore
disable it for the unwinding functions.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/kernel/unwind_bc.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c
index 0ece156fdd7c..7ecaab24783f 100644
--- a/arch/s390/kernel/unwind_bc.c
+++ b/arch/s390/kernel/unwind_bc.c
@@ -49,6 +49,7 @@ static inline bool is_final_pt_regs(struct unwind_state *state,
READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
}

+__no_kmsan_checks
bool unwind_next_frame(struct unwind_state *state)
{
struct stack_info *info = &state->stack_info;
@@ -118,6 +119,7 @@ bool unwind_next_frame(struct unwind_state *state)
}
EXPORT_SYMBOL_GPL(unwind_next_frame);

+__no_kmsan_checks
void __unwind_start(struct unwind_state *state, struct task_struct *task,
struct pt_regs *regs, unsigned long first_frame)
{
--
2.41.0

2023-11-15 20:37:55

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 29/32] s390/uaccess: Add KMSAN support to put_user() and get_user()

put_user() uses inline assembly with precise constraints, so Clang is
in principle capable of instrumenting it automatically. Unfortunately,
one of the constraints contains a dereferenced user pointer, and Clang
does not currently distinguish user and kernel pointers. Therefore
KMSAN attempts to access shadow for user pointers, which is not a right
thing to do.

An obvious fix to add __no_sanitize_memory to __put_user_fn() does not
work, since it's __always_inline. And __always_inline cannot be removed
due to the __put_user_bad() trick.

A different obvious fix of using the "a" instead of the "+Q" constraint
degrades the code quality, which is very important here, since it's a
hot path.

Instead, repurpose the __put_user_asm() macro to define
__put_user_{char,short,int,long}_noinstr() functions and mark them with
__no_sanitize_memory. For the non-KMSAN builds make them
__always_inline in order to keep the generated code quality. Also
define __put_user_{char,short,int,long}() functions, which call the
aforementioned ones and which *are* instrumented, because they call
KMSAN hooks, which may be implemented as macros.

The same applies to get_user() as well.

Acked-by: Heiko Carstens <[email protected]>
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/include/asm/uaccess.h | 110 ++++++++++++++++++++++----------
1 file changed, 78 insertions(+), 32 deletions(-)

diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 81ae8a98e7ec..b0715b88b55a 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -78,13 +78,23 @@ union oac {

int __noreturn __put_user_bad(void);

-#define __put_user_asm(to, from, size) \
-({ \
+#ifdef CONFIG_KMSAN
+#define GET_PUT_USER_NOINSTR_ATTRIBUTES inline __no_sanitize_memory
+#else
+#define GET_PUT_USER_NOINSTR_ATTRIBUTES __always_inline
+#endif
+
+#define DEFINE_PUT_USER(type) \
+static GET_PUT_USER_NOINSTR_ATTRIBUTES int \
+__put_user_##type##_noinstr(unsigned type __user *to, \
+ unsigned type *from, \
+ unsigned long size) \
+{ \
union oac __oac_spec = { \
.oac1.as = PSW_BITS_AS_SECONDARY, \
.oac1.a = 1, \
}; \
- int __rc; \
+ int rc; \
\
asm volatile( \
" lr 0,%[spec]\n" \
@@ -93,12 +103,28 @@ int __noreturn __put_user_bad(void);
"2:\n" \
EX_TABLE_UA_STORE(0b, 2b, %[rc]) \
EX_TABLE_UA_STORE(1b, 2b, %[rc]) \
- : [rc] "=&d" (__rc), [_to] "+Q" (*(to)) \
+ : [rc] "=&d" (rc), [_to] "+Q" (*(to)) \
: [_size] "d" (size), [_from] "Q" (*(from)), \
[spec] "d" (__oac_spec.val) \
: "cc", "0"); \
- __rc; \
-})
+ return rc; \
+} \
+ \
+static __always_inline int \
+__put_user_##type(unsigned type __user *to, unsigned type *from, \
+ unsigned long size) \
+{ \
+ int rc; \
+ \
+ rc = __put_user_##type##_noinstr(to, from, size); \
+ instrument_put_user(*from, to, size); \
+ return rc; \
+}
+
+DEFINE_PUT_USER(char);
+DEFINE_PUT_USER(short);
+DEFINE_PUT_USER(int);
+DEFINE_PUT_USER(long);

static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
{
@@ -106,24 +132,24 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon

switch (size) {
case 1:
- rc = __put_user_asm((unsigned char __user *)ptr,
- (unsigned char *)x,
- size);
+ rc = __put_user_char((unsigned char __user *)ptr,
+ (unsigned char *)x,
+ size);
break;
case 2:
- rc = __put_user_asm((unsigned short __user *)ptr,
- (unsigned short *)x,
- size);
+ rc = __put_user_short((unsigned short __user *)ptr,
+ (unsigned short *)x,
+ size);
break;
case 4:
- rc = __put_user_asm((unsigned int __user *)ptr,
+ rc = __put_user_int((unsigned int __user *)ptr,
(unsigned int *)x,
size);
break;
case 8:
- rc = __put_user_asm((unsigned long __user *)ptr,
- (unsigned long *)x,
- size);
+ rc = __put_user_long((unsigned long __user *)ptr,
+ (unsigned long *)x,
+ size);
break;
default:
__put_user_bad();
@@ -134,13 +160,17 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon

int __noreturn __get_user_bad(void);

-#define __get_user_asm(to, from, size) \
-({ \
+#define DEFINE_GET_USER(type) \
+static GET_PUT_USER_NOINSTR_ATTRIBUTES int \
+__get_user_##type##_noinstr(unsigned type *to, \
+ unsigned type __user *from, \
+ unsigned long size) \
+{ \
union oac __oac_spec = { \
.oac2.as = PSW_BITS_AS_SECONDARY, \
.oac2.a = 1, \
}; \
- int __rc; \
+ int rc; \
\
asm volatile( \
" lr 0,%[spec]\n" \
@@ -149,13 +179,29 @@ int __noreturn __get_user_bad(void);
"2:\n" \
EX_TABLE_UA_LOAD_MEM(0b, 2b, %[rc], %[_to], %[_ksize]) \
EX_TABLE_UA_LOAD_MEM(1b, 2b, %[rc], %[_to], %[_ksize]) \
- : [rc] "=&d" (__rc), "=Q" (*(to)) \
+ : [rc] "=&d" (rc), "=Q" (*(to)) \
: [_size] "d" (size), [_from] "Q" (*(from)), \
[spec] "d" (__oac_spec.val), [_to] "a" (to), \
[_ksize] "K" (size) \
: "cc", "0"); \
- __rc; \
-})
+ return rc; \
+} \
+ \
+static __always_inline int \
+__get_user_##type(unsigned type *to, unsigned type __user *from, \
+ unsigned long size) \
+{ \
+ int rc; \
+ \
+ rc = __get_user_##type##_noinstr(to, from, size); \
+ instrument_get_user(*to); \
+ return rc; \
+}
+
+DEFINE_GET_USER(char);
+DEFINE_GET_USER(short);
+DEFINE_GET_USER(int);
+DEFINE_GET_USER(long);

static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
{
@@ -163,24 +209,24 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign

switch (size) {
case 1:
- rc = __get_user_asm((unsigned char *)x,
- (unsigned char __user *)ptr,
- size);
+ rc = __get_user_char((unsigned char *)x,
+ (unsigned char __user *)ptr,
+ size);
break;
case 2:
- rc = __get_user_asm((unsigned short *)x,
- (unsigned short __user *)ptr,
- size);
+ rc = __get_user_short((unsigned short *)x,
+ (unsigned short __user *)ptr,
+ size);
break;
case 4:
- rc = __get_user_asm((unsigned int *)x,
+ rc = __get_user_int((unsigned int *)x,
(unsigned int __user *)ptr,
size);
break;
case 8:
- rc = __get_user_asm((unsigned long *)x,
- (unsigned long __user *)ptr,
- size);
+ rc = __get_user_long((unsigned long *)x,
+ (unsigned long __user *)ptr,
+ size);
break;
default:
__get_user_bad();
--
2.41.0

2023-11-15 20:39:24

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 28/32] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs

This is normally done by the generic entry code, but the
kernel_stack_overflow() flow bypasses it.

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/kernel/traps.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 1d2aa448d103..dd7362806dbb 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -27,6 +27,7 @@
#include <linux/uaccess.h>
#include <linux/cpu.h>
#include <linux/entry-common.h>
+#include <linux/kmsan.h>
#include <asm/asm-extable.h>
#include <asm/fpu/api.h>
#include <asm/vtime.h>
@@ -260,6 +261,7 @@ static void monitor_event_exception(struct pt_regs *regs)

void kernel_stack_overflow(struct pt_regs *regs)
{
+ kmsan_unpoison_entry_regs(regs);
bust_spinlocks(1);
printk("Kernel stack overflow.\n");
show_regs(regs);
--
2.41.0

2023-11-15 20:39:27

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 20/32] s390: Turn off KMSAN for boot, vdso and purgatory

All other sanitizers are disabled for these components as well.

Reviewed-by: Alexander Gordeev <[email protected]>
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/boot/Makefile | 1 +
arch/s390/kernel/vdso32/Makefile | 1 +
arch/s390/kernel/vdso64/Makefile | 1 +
arch/s390/purgatory/Makefile | 1 +
4 files changed, 4 insertions(+)

diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index c7c81e5f9218..5a05c927f703 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -8,6 +8,7 @@ GCOV_PROFILE := n
UBSAN_SANITIZE := n
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n

KBUILD_AFLAGS := $(KBUILD_AFLAGS_DECOMPRESSOR)
KBUILD_CFLAGS := $(KBUILD_CFLAGS_DECOMPRESSOR)
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index caec7db6f966..8911c55a7f07 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -37,6 +37,7 @@ GCOV_PROFILE := n
UBSAN_SANITIZE := n
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n

# Force dependency (incbin is bad)
$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index e3c9085f8fa7..f4f75c334d59 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -41,6 +41,7 @@ GCOV_PROFILE := n
UBSAN_SANITIZE := n
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n

# Force dependency (incbin is bad)
$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile
index 4e930f566878..e8402287b0cd 100644
--- a/arch/s390/purgatory/Makefile
+++ b/arch/s390/purgatory/Makefile
@@ -20,6 +20,7 @@ GCOV_PROFILE := n
UBSAN_SANITIZE := n
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n

KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
--
2.41.0

2023-11-15 20:39:28

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 24/32] s390/cpacf: Unpoison the results of cpacf_trng()

Prevent KMSAN from complaining about buffers filled by cpacf_trng()
being uninitialized.

Tested-by: Alexander Gordeev <[email protected]>
Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/include/asm/cpacf.h | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h
index b378e2b57ad8..a72b92770c4b 100644
--- a/arch/s390/include/asm/cpacf.h
+++ b/arch/s390/include/asm/cpacf.h
@@ -473,6 +473,8 @@ static inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
: [ucbuf] "+&d" (u.pair), [cbuf] "+&d" (c.pair)
: [fc] "K" (CPACF_PRNO_TRNG), [opc] "i" (CPACF_PRNO)
: "cc", "memory", "0");
+ kmsan_unpoison_memory(ucbuf, ucbuf_len);
+ kmsan_unpoison_memory(cbuf, cbuf_len);
}

/**
--
2.41.0

2023-11-15 20:40:00

by Ilya Leoshkevich

[permalink] [raw]
Subject: [PATCH 31/32] s390: Implement the architecture-specific kmsan functions

arch_kmsan_get_meta_or_null() finds the lowcore shadow by querying the
prefix and calling kmsan_get_metadata() again.

kmsan_virt_addr_valid() delegates to virt_addr_valid().

Signed-off-by: Ilya Leoshkevich <[email protected]>
---
arch/s390/include/asm/kmsan.h | 36 +++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100644 arch/s390/include/asm/kmsan.h

diff --git a/arch/s390/include/asm/kmsan.h b/arch/s390/include/asm/kmsan.h
new file mode 100644
index 000000000000..afec71e9e9ac
--- /dev/null
+++ b/arch/s390/include/asm/kmsan.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_KMSAN_H
+#define _ASM_S390_KMSAN_H
+
+#include <asm/lowcore.h>
+#include <asm/page.h>
+#include <linux/kmsan.h>
+#include <linux/mmzone.h>
+#include <linux/stddef.h>
+
+#ifndef MODULE
+
+static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
+{
+ if (addr >= (void *)&S390_lowcore &&
+ addr < (void *)(&S390_lowcore + 1)) {
+ /*
+ * Different lowcores accessed via S390_lowcore are described
+ * by the same struct page. Resolve the prefix manually in
+ * order to get a distinct struct page.
+ */
+ addr += (void *)lowcore_ptr[raw_smp_processor_id()] -
+ (void *)&S390_lowcore;
+ return kmsan_get_metadata(addr, is_origin);
+ }
+ return NULL;
+}
+
+static inline bool kmsan_virt_addr_valid(void *addr)
+{
+ return virt_addr_valid(addr);
+}
+
+#endif /* !MODULE */
+
+#endif /* _ASM_S390_KMSAN_H */
--
2.41.0

2023-11-16 08:43:28

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 00/32] kmsan: Enable on s390

On Wed, Nov 15, 2023 at 9:34 PM Ilya Leoshkevich <[email protected]> wrote:
>
> Hi,
>
> This series provides the minimal support for Kernel Memory Sanitizer on
> s390. Kernel Memory Sanitizer is clang-only instrumentation for finding
> accesses to uninitialized memory. The clang support for s390 has already
> been merged [1].
>
> With this series, I can successfully boot s390 defconfig and
> debug_defconfig with kmsan.panic=1. The tool found one real
> s390-specific bug (fixed in master).
>
> Best regards,
> Ilya

Hi Ilya,

This is really impressive!
Can you please share some instructions on how to run KMSAN in QEMU?
I've never touched s390, but I'm assuming it should be possible?

2023-11-16 09:06:07

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 30/32] s390/unwind: Disable KMSAN checks

On Wed, Nov 15, 2023 at 9:35 PM Ilya Leoshkevich <[email protected]> wrote:
>
> The unwind code can read uninitialized frames. Furthermore, even in
> the good case, KMSAN does not emit shadow for backchains. Therefore
> disable it for the unwinding functions.
>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
> ---
> arch/s390/kernel/unwind_bc.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c
> index 0ece156fdd7c..7ecaab24783f 100644
> --- a/arch/s390/kernel/unwind_bc.c
> +++ b/arch/s390/kernel/unwind_bc.c
> @@ -49,6 +49,7 @@ static inline bool is_final_pt_regs(struct unwind_state *state,
> READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
> }
>
> +__no_kmsan_checks

Please add some comments to the source file to back this annotation,
so that the intent is not lost in git history.

2023-11-16 09:06:38

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 30/32] s390/unwind: Disable KMSAN checks

On Thu, Nov 16, 2023 at 10:04 AM Alexander Potapenko <[email protected]> wrote:
>
> On Wed, Nov 15, 2023 at 9:35 PM Ilya Leoshkevich <[email protected]> wrote:
> >
> > The unwind code can read uninitialized frames. Furthermore, even in
> > the good case, KMSAN does not emit shadow for backchains. Therefore
> > disable it for the unwinding functions.
> >
> > Signed-off-by: Ilya Leoshkevich <[email protected]>
> > ---
> > arch/s390/kernel/unwind_bc.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c
> > index 0ece156fdd7c..7ecaab24783f 100644
> > --- a/arch/s390/kernel/unwind_bc.c
> > +++ b/arch/s390/kernel/unwind_bc.c
> > @@ -49,6 +49,7 @@ static inline bool is_final_pt_regs(struct unwind_state *state,
> > READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
> > }
> >
> > +__no_kmsan_checks
>
> Please add some comments to the source file to back this annotation,
> so that the intent is not lost in git history.

Apart from that,

Reviewed-by: Alexander Potapenko <[email protected]>


--
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Liana Sebastian
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

2023-11-16 09:21:32

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 20/32] s390: Turn off KMSAN for boot, vdso and purgatory

On Wed, Nov 15, 2023 at 9:34 PM Ilya Leoshkevich <[email protected]> wrote:
>
> All other sanitizers are disabled for these components as well.
>
> Reviewed-by: Alexander Gordeev <[email protected]>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>
(see a nit below)

> ---
> arch/s390/boot/Makefile | 1 +
> arch/s390/kernel/vdso32/Makefile | 1 +
> arch/s390/kernel/vdso64/Makefile | 1 +
> arch/s390/purgatory/Makefile | 1 +
> 4 files changed, 4 insertions(+)
>
> diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
> index c7c81e5f9218..5a05c927f703 100644
> --- a/arch/s390/boot/Makefile
> +++ b/arch/s390/boot/Makefile
> @@ -8,6 +8,7 @@ GCOV_PROFILE := n
> UBSAN_SANITIZE := n
> KASAN_SANITIZE := n
> KCSAN_SANITIZE := n
> +KMSAN_SANITIZE := n

Nit: I think having even a one-line comment before this block
(something similar to
https://elixir.bootlin.com/linux/latest/source/arch/x86/boot/Makefile#L12)
will make it more clear.

But given that the comment wasn't there before, leaving this up to you.

2023-11-16 09:47:26

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 21/32] s390: Use a larger stack for KMSAN

On Wed, Nov 15, 2023 at 9:34 PM Ilya Leoshkevich <[email protected]> wrote:
>
> Adjust the stack size for the KMSAN-enabled kernel like it was done
> for the KASAN-enabled one in commit 7fef92ccadd7 ("s390/kasan: double
> the stack size"). Both tools have similar requirements.
>
> Reviewed-by: Alexander Gordeev <[email protected]>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>

2023-11-16 09:56:26

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 14/32] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata()

On Wed, Nov 15, 2023 at 9:34 PM Ilya Leoshkevich <[email protected]> wrote:
>
> Improve the readability by replacing the custom aligning logic with
> ALIGN_DOWN(). Unlike other places where a similar sequence is used,
> there is no size parameter that needs to be adjusted, so the standard
> macro fits.

Good catch, thank you!

> Signed-off-by: Ilya Leoshkevich <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>

2023-11-16 10:14:54

by Ilya Leoshkevich

[permalink] [raw]
Subject: Re: [PATCH 00/32] kmsan: Enable on s390

On Thu, 2023-11-16 at 09:42 +0100, Alexander Potapenko wrote:
> On Wed, Nov 15, 2023 at 9:34 PM Ilya Leoshkevich <[email protected]>
> wrote:
> >
> > Hi,
> >
> > This series provides the minimal support for Kernel Memory
> > Sanitizer on
> > s390. Kernel Memory Sanitizer is clang-only instrumentation for
> > finding
> > accesses to uninitialized memory. The clang support for s390 has
> > already
> > been merged [1].
> >
> > With this series, I can successfully boot s390 defconfig and
> > debug_defconfig with kmsan.panic=1. The tool found one real
> > s390-specific bug (fixed in master).
> >
> > Best regards,
> > Ilya
>
> Hi Ilya,
>
> This is really impressive!
> Can you please share some instructions on how to run KMSAN in QEMU?
> I've never touched s390, but I'm assuming it should be possible?

I developed this natively (without cross-compilation or emulation,
just KVM), but I just gave the following a try on x86_64 and had some
success:

$ make LLVM=1 ARCH=s390 O=../linux-build-s390x-cross CC=clang-18
LD=s390x-linux-gnu-ld OBJCOPY=s390x-linux-gnu-objcopy debug_defconfig

$ make LLVM=1 ARCH=s390 O=../linux-build-s390x-cross CC=clang-18
LD=s390x-linux-gnu-ld OBJCOPY=s390x-linux-gnu-objcopy menuconfig

$ make LLVM=1 ARCH=s390 O=../linux-build-s390x-cross CC=clang-18
LD=s390x-linux-gnu-ld OBJCOPY=s390x-linux-gnu-objcopy -j24

$ qemu-system-s390x -M accel=tcg -smp 2 -m 4G -kernel ../linux-build-
s390x-cross/arch/s390/boot/bzImage -nographic -append 'root=/dev/vda1
rw console=ttyS1 nokaslr earlyprintk cio_ignore=all kmsan.panic=1' -
object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-
ccw,rng=rng0

It's also possible to get a free s390 machine at [1].

[1] https://linuxone.cloud.marist.edu/oss

2023-11-16 10:23:41

by Christian Borntraeger

[permalink] [raw]
Subject: Re: [PATCH 00/32] kmsan: Enable on s390



Am 16.11.23 um 11:13 schrieb Ilya Leoshkevich:
> It's also possible to get a free s390 machine at [1].
>
> [1] https://linuxone.cloud.marist.edu/oss

I think the URL for registration is this one
https://linuxone.cloud.marist.edu/#/register?flag=VM

2023-11-16 10:34:28

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 19/32] kmsan: Accept ranges starting with 0 on s390

On Wed, Nov 15, 2023 at 9:34 PM Ilya Leoshkevich <[email protected]> wrote:
>
> On s390 the virtual address 0 is valid (current CPU's lowcore is mapped
> there), therefore KMSAN should not complain about it.
>
> Disable the respective check on s390. There doesn't seem to be a
> Kconfig option to describe this situation, so explicitly check for
> s390.
>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>
(see the nit below)

> ---
> mm/kmsan/init.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/mm/kmsan/init.c b/mm/kmsan/init.c
> index ffedf4dbc49d..14f4a432fddd 100644
> --- a/mm/kmsan/init.c
> +++ b/mm/kmsan/init.c
> @@ -33,7 +33,9 @@ static void __init kmsan_record_future_shadow_range(void *start, void *end)
> bool merged = false;
>
> KMSAN_WARN_ON(future_index == NUM_FUTURE_RANGES);
> - KMSAN_WARN_ON((nstart >= nend) || !nstart || !nend);
> + KMSAN_WARN_ON((nstart >= nend) ||
> + (!IS_ENABLED(CONFIG_S390) && !nstart) ||
Please add a comment explaining this bit.

> + !nend);
> nstart = ALIGN_DOWN(nstart, PAGE_SIZE);
> nend = ALIGN(nend, PAGE_SIZE);
>
> --
> 2.41.0
>

2023-11-16 15:04:24

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 26/32] s390/mm: Define KMSAN metadata for vmalloc and modules

On Wed, Nov 15, 2023 at 9:35 PM Ilya Leoshkevich <[email protected]> wrote:
>
> The pages for the KMSAN metadata associated with most kernel mappings
> are taken from memblock by the common code. However, vmalloc and module
> metadata needs to be defined by the architectures.
>
> Be a little bit more careful than x86: allocate exactly MODULES_LEN
> for the module shadow and origins, and then take 2/3 of vmalloc for
> the vmalloc shadow and origins. This ensures that users passing small
> vmalloc= values on the command line do not cause module metadata
> collisions.
>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
> ---
> arch/s390/boot/startup.c | 8 ++++++++
> arch/s390/include/asm/pgtable.h | 10 ++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
> index 8104e0e3d188..297c1062372a 100644
> --- a/arch/s390/boot/startup.c
> +++ b/arch/s390/boot/startup.c
> @@ -253,9 +253,17 @@ static unsigned long setup_kernel_memory_layout(void)
> MODULES_END = round_down(__abs_lowcore, _SEGMENT_SIZE);
> MODULES_VADDR = MODULES_END - MODULES_LEN;
> VMALLOC_END = MODULES_VADDR;
> +#ifdef CONFIG_KMSAN
> + VMALLOC_END -= MODULES_LEN * 2;
> +#endif
>
> /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
> vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE));
> +#ifdef CONFIG_KMSAN
> + /* take 2/3 of vmalloc area for KMSAN shadow and origins */
> + vmalloc_size = round_down(vmalloc_size / 3, PAGE_SIZE);
Is it okay that vmalloc_size is only aligned on PAGE_SIZE?
E.g. above the alignment is _REGION3_SIZE.

2023-11-16 15:33:35

by Alexander Potapenko

[permalink] [raw]
Subject: Re: [PATCH 28/32] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs

On Wed, Nov 15, 2023 at 9:35 PM Ilya Leoshkevich <[email protected]> wrote:
>
> This is normally done by the generic entry code, but the
> kernel_stack_overflow() flow bypasses it.
>
> Signed-off-by: Ilya Leoshkevich <[email protected]>
Reviewed-by: Alexander Potapenko <[email protected]>

> ---
> arch/s390/kernel/traps.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
> index 1d2aa448d103..dd7362806dbb 100644
> --- a/arch/s390/kernel/traps.c
> +++ b/arch/s390/kernel/traps.c
> @@ -27,6 +27,7 @@
> #include <linux/uaccess.h>
> #include <linux/cpu.h>
> #include <linux/entry-common.h>
> +#include <linux/kmsan.h>
> #include <asm/asm-extable.h>
> #include <asm/fpu/api.h>
> #include <asm/vtime.h>
> @@ -260,6 +261,7 @@ static void monitor_event_exception(struct pt_regs *regs)
>
> void kernel_stack_overflow(struct pt_regs *regs)
> {
> + kmsan_unpoison_entry_regs(regs);

I suggest adding a comment here.

2023-11-16 21:44:19

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 27/32] s390/string: Add KMSAN support

Hi Ilya,

kernel test robot noticed the following build errors:

[auto build test ERROR on s390/features]
[also build test ERROR on akpm-mm/mm-everything linus/master vbabka-slab/for-next v6.7-rc1 next-20231116]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ilya-Leoshkevich/ftrace-Unpoison-ftrace_regs-in-ftrace_ops_list_func/20231116-045608
base: https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git features
patch link: https://lore.kernel.org/r/20231115203401.2495875-28-iii%40linux.ibm.com
patch subject: [PATCH 27/32] s390/string: Add KMSAN support
config: s390-debug_defconfig (https://download.01.org/0day-ci/archive/20231117/[email protected]/config)
compiler: s390-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231117/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

s390-linux-ld: arch/s390/mm/vmem.o: in function `crst_table_init':
>> arch/s390/include/asm/pgalloc.h:33:(.text+0x1ba): undefined reference to `memset64'
s390-linux-ld: arch/s390/mm/vmem.o: in function `vmem_pte_alloc':
>> arch/s390/mm/vmem.c:68:(.ref.text+0x1ec): undefined reference to `memset64'
s390-linux-ld: arch/s390/mm/pgalloc.o: in function `base_pgt_alloc':
>> arch/s390/mm/pgalloc.c:241:(.text+0x184): undefined reference to `memset64'
s390-linux-ld: arch/s390/mm/pgalloc.o: in function `crst_table_init':
arch/s390/include/asm/pgalloc.h:33:(.text+0x3e8): undefined reference to `memset64'
>> s390-linux-ld: arch/s390/include/asm/pgalloc.h:33:(.text+0x568): undefined reference to `memset64'
s390-linux-ld: arch/s390/mm/pgalloc.o:arch/s390/include/asm/pgalloc.h:33: more undefined references to `memset64' follow
s390-linux-ld: lib/test_string.o: in function `memset16_selftest':
>> lib/test_string.c:19:(.init.text+0x94): undefined reference to `memset16'
s390-linux-ld: lib/test_string.o: in function `memset32_selftest':
>> lib/test_string.c:55:(.init.text+0x234): undefined reference to `memset32'
s390-linux-ld: lib/test_string.o: in function `memset64_selftest':
>> lib/test_string.c:91:(.init.text+0x3c2): undefined reference to `memset64'
s390-linux-ld: drivers/video/fbdev/core/fbcon.o: in function `scr_memsetw':
>> include/linux/vt_buffer.h:36:(.text+0x30f6): undefined reference to `memset16'
>> s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x320a): undefined reference to `memset16'
s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x32c4): undefined reference to `memset16'
s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x33b8): undefined reference to `memset16'
s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x4f60): undefined reference to `memset16'
s390-linux-ld: drivers/video/fbdev/core/fbcon.o:include/linux/vt_buffer.h:36: more undefined references to `memset16' follow
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_copy_area':
>> drivers/tty/vt/vt.c:464:(.text+0x107e): undefined reference to `memset32'
>> s390-linux-ld: drivers/tty/vt/vt.c:471:(.text+0x1104): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:471:(.text+0x1118): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:471:(.text+0x1140): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_insert':
drivers/tty/vt/vt.c:374:(.text+0x13a4): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o:drivers/tty/vt/vt.c:385: more undefined references to `memset32' follow
s390-linux-ld: drivers/tty/vt/vt.o: in function `scr_memsetw':
include/linux/vt_buffer.h:36:(.text+0x2844): undefined reference to `memset16'
s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x2932): undefined reference to `memset16'
s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x2fe8): undefined reference to `memset16'
s390-linux-ld: include/linux/vt_buffer.h:36:(.text+0x319c): undefined reference to `memset16'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_line':
drivers/tty/vt/vt.c:393:(.text+0x3f78): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_lines':
drivers/tty/vt/vt.c:401:(.text+0x3fb8): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:401:(.text+0x3fe2): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `scr_memsetw':
include/linux/vt_buffer.h:36:(.text+0x4018): undefined reference to `memset16'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_lines':
drivers/tty/vt/vt.c:401:(.text+0x40de): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:401:(.text+0x4114): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:401:(.text+0x4134): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_line':
drivers/tty/vt/vt.c:393:(.text+0x417c): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_lines':
drivers/tty/vt/vt.c:401:(.text+0x41d6): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o:drivers/tty/vt/vt.c:401: more undefined references to `memset32' follow
s390-linux-ld: drivers/tty/vt/vt.o: in function `scr_memsetw':
include/linux/vt_buffer.h:36:(.text+0x46d2): undefined reference to `memset16'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_lines':
drivers/tty/vt/vt.c:401:(.text+0x4736): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:401:(.text+0x47b6): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:401:(.text+0x47f2): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.c:401:(.text+0x482e): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_line':
drivers/tty/vt/vt.c:393:(.text+0x7b1a): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `scr_memsetw':
include/linux/vt_buffer.h:36:(.text+0x7b30): undefined reference to `memset16'
s390-linux-ld: drivers/tty/vt/vt.o: in function `vc_uniscr_clear_line':
drivers/tty/vt/vt.c:393:(.text+0x7c7a): undefined reference to `memset32'
s390-linux-ld: drivers/tty/vt/vt.o: in function `scr_memsetw':
include/linux/vt_buffer.h:36:(.text+0x7c9c): undefined reference to `memset16'
s390-linux-ld: drivers/block/zram/zram_drv.o: in function `memset_l':
>> include/linux/string.h:168:(.text+0x1860): undefined reference to `memset64'


vim +168 include/linux/string.h

3b3c4babd89871 Matthew Wilcox 2017-09-08 161
3b3c4babd89871 Matthew Wilcox 2017-09-08 162 static inline void *memset_l(unsigned long *p, unsigned long v,
3b3c4babd89871 Matthew Wilcox 2017-09-08 163 __kernel_size_t n)
3b3c4babd89871 Matthew Wilcox 2017-09-08 164 {
3b3c4babd89871 Matthew Wilcox 2017-09-08 165 if (BITS_PER_LONG == 32)
3b3c4babd89871 Matthew Wilcox 2017-09-08 166 return memset32((uint32_t *)p, v, n);
3b3c4babd89871 Matthew Wilcox 2017-09-08 167 else
3b3c4babd89871 Matthew Wilcox 2017-09-08 @168 return memset64((uint64_t *)p, v, n);
3b3c4babd89871 Matthew Wilcox 2017-09-08 169 }
3b3c4babd89871 Matthew Wilcox 2017-09-08 170

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2023-11-17 16:42:59

by Alexander Gordeev

[permalink] [raw]
Subject: Re: [PATCH 26/32] s390/mm: Define KMSAN metadata for vmalloc and modules

On Thu, Nov 16, 2023 at 04:03:13PM +0100, Alexander Potapenko wrote:

Hi Alexander!

> > /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
> > vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE));
> > +#ifdef CONFIG_KMSAN
> > + /* take 2/3 of vmalloc area for KMSAN shadow and origins */
> > + vmalloc_size = round_down(vmalloc_size / 3, PAGE_SIZE);
> Is it okay that vmalloc_size is only aligned on PAGE_SIZE?
> E.g. above the alignment is _REGION3_SIZE.

Good question!

This patch does not break anything, although the _REGION3_SIZE
alignment would be consistent here. Yet, we might rethink this
whole code piece and the next version would reflect that.

Thanks!