From: Philippe Gerum <[email protected]>

Since v5.9-rc1, csum_partial_copy_nocheck() forces a zero seed as its
last argument to csum_partial(). According to #cc44c17baf7f3, passing
a non-zero value would not even yield the proper result on some
architectures.

Nevertheless, the current ICMP code does expect a non-zero csum seed
to be used in the next computation, so let's wrap net_csum_copy() to
csum_partial_copy_nocheck() for pre-5.9 kernels, and open code it for
later kernels so that we still feed csum_partial() with the user-given
csum. We still expect the x86, ARM and arm64 implementations of
csum_partial() to do the right thing.

Signed-off-by: Philippe Gerum <[email protected]>
---
 .../include/asm-generic/xenomai/wrappers.h     | 11 +++++++++++
 kernel/drivers/net/stack/ipv4/icmp.c           | 18 +++++++++---------
 kernel/drivers/net/stack/rtskb.c               |  3 +--
 3 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h 
b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
index cc0cb0896..cfd28fc47 100644
--- a/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
+++ b/kernel/cobalt/include/asm-generic/xenomai/wrappers.h
@@ -209,4 +209,15 @@ devm_hwmon_device_register_with_groups(struct device *dev, 
const char *name,
 #define vmalloc_kernel(__size, __flags)        __vmalloc(__size, 
GFP_KERNEL|__flags)
 #endif
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5,9,0)
+#define net_csum_copy(__src, __dst, __len, __csum)     \
+       csum_partial_copy_nocheck(__src, __dst, __len, __csum)
+#else
+#define net_csum_copy(__src, __dst, __len, __csum)                     \
+       ({                                                              \
+               memcpy(__dst, __src, __len);                            \
+               csum_partial(__dst, __len, (__force __wsum)__csum);     \
+       })
+#endif
+
 #endif /* _COBALT_ASM_GENERIC_WRAPPERS_H */
diff --git a/kernel/drivers/net/stack/ipv4/icmp.c 
b/kernel/drivers/net/stack/ipv4/icmp.c
index b723040aa..0671cbc93 100644
--- a/kernel/drivers/net/stack/ipv4/icmp.c
+++ b/kernel/drivers/net/stack/ipv4/icmp.c
@@ -142,9 +142,9 @@ static int rt_icmp_glue_reply_bits(const void *p, unsigned 
char *to,
        if (offset != 0)
                return -EMSGSIZE;
 
-       csum = csum_partial_copy_nocheck((void *)&icmp_param->head, to,
-                                        icmp_param->head_len,
-                                        icmp_param->csum);
+       csum = net_csum_copy((void *)&icmp_param->head, to,
+                            icmp_param->head_len,
+                            icmp_param->csum);
 
        csum = rtskb_copy_and_csum_bits(icmp_param->data.skb,
                                        icmp_param->offset,
@@ -259,13 +259,13 @@ static int rt_icmp_glue_request_bits(const void *p, 
unsigned char *to,
                            __FUNCTION__);
                return -1;);
 
-       csum = csum_partial_copy_nocheck((void *)&icmp_param->head, to,
-                                        icmp_param->head_len,
-                                        icmp_param->csum);
+       csum = net_csum_copy((void *)&icmp_param->head, to,
+                            icmp_param->head_len,
+                            icmp_param->csum);
 
-       csum = csum_partial_copy_nocheck(icmp_param->data.buf,
-                                        to + icmp_param->head_len,
-                                        fraglen - icmp_param->head_len, csum);
+       csum = net_csum_copy(icmp_param->data.buf,
+                            to + icmp_param->head_len,
+                            fraglen - icmp_param->head_len, csum);
 
        icmph = (struct icmphdr *)to;
 
diff --git a/kernel/drivers/net/stack/rtskb.c b/kernel/drivers/net/stack/rtskb.c
index 84d021d24..0d0c66e58 100644
--- a/kernel/drivers/net/stack/rtskb.c
+++ b/kernel/drivers/net/stack/rtskb.c
@@ -69,8 +69,7 @@ unsigned int rtskb_copy_and_csum_bits(const struct rtskb 
*skb, int offset,
        if ((copy = skb->len - offset) > 0) {
                if (copy > len)
                        copy = len;
-               csum = csum_partial_copy_nocheck(skb->data + offset, to, copy,
-                                                csum);
+               csum = net_csum_copy(skb->data + offset, to, copy, csum);
                if ((len -= copy) == 0)
                        return csum;
                offset += copy;
-- 
2.29.2


Reply via email to