diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2024-02-03 11:45:21 +0100 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2024-02-16 14:30:17 +0100 |
commit | 3a74f44de2c901e1536d227d29257cae1a6ed18f (patch) | |
tree | 3ddf7dc168688604eca4d9dfa146fca65f7bb9d2 /arch/s390 | |
parent | s390/checksum: call instrument_read() instead of kasan_check_read() (diff) | |
download | linux-3a74f44de2c901e1536d227d29257cae1a6ed18f.tar.xz linux-3a74f44de2c901e1536d227d29257cae1a6ed18f.zip |
s390/checksum: provide and use cksm() inline assembly
Convert those callers of csum_partial() to use the cksm instruction,
which are either very early or in critical paths, like panic/dump, so
they don't have to rely on a working kernel infrastructure, which will
be introduced with a subsequent patch.
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/checksum.h | 27 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/os_info.c | 6 |
3 files changed, 20 insertions, 16 deletions
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index fcef9ae433a7..414264b3ed6c 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h @@ -15,6 +15,21 @@ #include <linux/instrumented.h> #include <linux/in6.h> +static inline __wsum cksm(const void *buff, int len, __wsum sum) +{ + union register_pair rp = { + .even = (unsigned long)buff, + .odd = (unsigned long)len, + }; + + instrument_read(buff, len); + asm volatile("\n" + "0: cksm %[sum],%[rp]\n" + " jo 0b\n" + : [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory"); + return sum; +} + /* * Computes the checksum of a memory block at buff, length len, * and adds in "sum" (32-bit). @@ -29,17 +44,7 @@ */ static inline __wsum csum_partial(const void *buff, int len, __wsum sum) { - union register_pair rp = { - .even = (unsigned long) buff, - .odd = (unsigned long) len, - }; - - instrument_read(buff, len); - asm volatile( - "0: cksm %[sum],%[rp]\n" - " jo 0b\n" - : [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory"); - return sum; + return cksm(buff, len, sum); } /* diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index ba75f6bee774..1486350a4177 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -1941,8 +1941,7 @@ static void dump_reipl_run(struct shutdown_trigger *trigger) reipl_type == IPL_TYPE_UNKNOWN) os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR; os_info_entry_add(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags)); - csum = (__force unsigned int) - csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); + csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0); abs_lc = get_abs_lowcore(); abs_lc->ipib = __pa(reipl_block_actual); abs_lc->ipib_checksum = csum; diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index 6e1824141b29..a801e6bd5341 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -29,7 +29,7 @@ static struct os_info os_info __page_aligned_data; u32 os_info_csum(struct os_info *os_info) { int size = sizeof(*os_info) - offsetof(struct os_info, version_major); - return (__force u32)csum_partial(&os_info->version_major, size, 0); + return (__force u32)cksm(&os_info->version_major, size, 0); } /* @@ -49,7 +49,7 @@ void os_info_entry_add(int nr, void *ptr, u64 size) { os_info.entry[nr].addr = __pa(ptr); os_info.entry[nr].size = size; - os_info.entry[nr].csum = (__force u32)csum_partial(ptr, size, 0); + os_info.entry[nr].csum = (__force u32)cksm(ptr, size, 0); os_info.csum = os_info_csum(&os_info); } @@ -98,7 +98,7 @@ static void os_info_old_alloc(int nr, int align) msg = "copy failed"; goto fail_free; } - csum = (__force u32)csum_partial(buf_align, size, 0); + csum = (__force u32)cksm(buf_align, size, 0); if (csum != os_info_old->entry[nr].csum) { msg = "checksum failed"; goto fail_free; |