s390/checksum: provide and use cksm() inline assembly
authorHeiko Carstens <hca@linux.ibm.com>
Sat, 3 Feb 2024 10:45:21 +0000 (11:45 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Fri, 16 Feb 2024 13:30:17 +0000 (14:30 +0100)
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>
arch/s390/include/asm/checksum.h
arch/s390/kernel/ipl.c
arch/s390/kernel/os_info.c

index fcef9ae433a7ae2495dd2ec27824c62e5f7a396b..414264b3ed6c0a1edff888b921fd3ab0e8bc16c3 100644 (file)
 #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).
  */
 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);
 }
 
 /*
index ba75f6bee77423be0f9a54e0afdaa88cbb342728..1486350a417751736b9bc934bd424fa9efc3de15 100644 (file)
@@ -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;
index 6e1824141b29eafc8d5b4adc56728c48b1af89ec..a801e6bd534178ce04bf161e3f2ff6e954d75e91 100644 (file)
@@ -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;