Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+20 -16
+16 -11
arch/s390/include/asm/checksum.h
··· 15 15 #include <linux/instrumented.h> 16 16 #include <linux/in6.h> 17 17 18 + static inline __wsum cksm(const void *buff, int len, __wsum sum) 19 + { 20 + union register_pair rp = { 21 + .even = (unsigned long)buff, 22 + .odd = (unsigned long)len, 23 + }; 24 + 25 + instrument_read(buff, len); 26 + asm volatile("\n" 27 + "0: cksm %[sum],%[rp]\n" 28 + " jo 0b\n" 29 + : [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory"); 30 + return sum; 31 + } 32 + 18 33 /* 19 34 * Computes the checksum of a memory block at buff, length len, 20 35 * and adds in "sum" (32-bit). ··· 44 29 */ 45 30 static inline __wsum csum_partial(const void *buff, int len, __wsum sum) 46 31 { 47 - union register_pair rp = { 48 - .even = (unsigned long) buff, 49 - .odd = (unsigned long) len, 50 - }; 51 - 52 - instrument_read(buff, len); 53 - asm volatile( 54 - "0: cksm %[sum],%[rp]\n" 55 - " jo 0b\n" 56 - : [sum] "+&d" (sum), [rp] "+&d" (rp.pair) : : "cc", "memory"); 57 - return sum; 32 + return cksm(buff, len, sum); 58 33 } 59 34 60 35 /*
+1 -2
arch/s390/kernel/ipl.c
··· 1941 1941 reipl_type == IPL_TYPE_UNKNOWN) 1942 1942 os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR; 1943 1943 os_info_entry_add(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags)); 1944 - csum = (__force unsigned int) 1945 - csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0); 1944 + csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0); 1946 1945 abs_lc = get_abs_lowcore(); 1947 1946 abs_lc->ipib = __pa(reipl_block_actual); 1948 1947 abs_lc->ipib_checksum = csum;
+3 -3
arch/s390/kernel/os_info.c
··· 29 29 u32 os_info_csum(struct os_info *os_info) 30 30 { 31 31 int size = sizeof(*os_info) - offsetof(struct os_info, version_major); 32 - return (__force u32)csum_partial(&os_info->version_major, size, 0); 32 + return (__force u32)cksm(&os_info->version_major, size, 0); 33 33 } 34 34 35 35 /* ··· 49 49 { 50 50 os_info.entry[nr].addr = __pa(ptr); 51 51 os_info.entry[nr].size = size; 52 - os_info.entry[nr].csum = (__force u32)csum_partial(ptr, size, 0); 52 + os_info.entry[nr].csum = (__force u32)cksm(ptr, size, 0); 53 53 os_info.csum = os_info_csum(&os_info); 54 54 } 55 55 ··· 98 98 msg = "copy failed"; 99 99 goto fail_free; 100 100 } 101 - csum = (__force u32)csum_partial(buf_align, size, 0); 101 + csum = (__force u32)cksm(buf_align, size, 0); 102 102 if (csum != os_info_old->entry[nr].csum) { 103 103 msg = "checksum failed"; 104 104 goto fail_free;