summaryrefslogtreecommitdiff
path: root/arch/s390
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2024-02-03 13:45:21 +0300
committerHeiko Carstens <hca@linux.ibm.com>2024-02-16 16:30:17 +0300
commit3a74f44de2c901e1536d227d29257cae1a6ed18f (patch)
tree3ddf7dc168688604eca4d9dfa146fca65f7bb9d2 /arch/s390
parent4ce69fcf17d067112f754414aa563e0cd74cc49d (diff)
downloadlinux-3a74f44de2c901e1536d227d29257cae1a6ed18f.tar.xz
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.h27
-rw-r--r--arch/s390/kernel/ipl.c3
-rw-r--r--arch/s390/kernel/os_info.c6
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;