hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/s390/include/asm/checksum.h
....@@ -13,21 +13,21 @@
1313 #define _S390_CHECKSUM_H
1414
1515 #include <linux/uaccess.h>
16
+#include <linux/in6.h>
1617
1718 /*
18
- * computes the checksum of a memory block at buff, length len,
19
- * and adds in "sum" (32-bit)
19
+ * Computes the checksum of a memory block at buff, length len,
20
+ * and adds in "sum" (32-bit).
2021 *
21
- * returns a 32-bit number suitable for feeding into itself
22
- * or csum_tcpudp_magic
22
+ * Returns a 32-bit number suitable for feeding into itself
23
+ * or csum_tcpudp_magic.
2324 *
24
- * this function must be called with even lengths, except
25
- * for the last fragment, which may be odd
25
+ * This function must be called with even lengths, except
26
+ * for the last fragment, which may be odd.
2627 *
27
- * it's best to have buff aligned on a 32-bit boundary
28
+ * It's best to have buff aligned on a 32-bit boundary.
2829 */
29
-static inline __wsum
30
-csum_partial(const void *buff, int len, __wsum sum)
30
+static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
3131 {
3232 register unsigned long reg2 asm("2") = (unsigned long) buff;
3333 register unsigned long reg3 asm("3") = (unsigned long) len;
....@@ -40,100 +40,91 @@
4040 }
4141
4242 /*
43
- * the same as csum_partial_copy, but copies from user space.
44
- *
45
- * here even more important to align src and dst on a 32-bit (or even
46
- * better 64-bit) boundary
47
- *
48
- * Copy from userspace and compute checksum.
49
- */
50
-static inline __wsum
51
-csum_partial_copy_from_user(const void __user *src, void *dst,
52
- int len, __wsum sum,
53
- int *err_ptr)
54
-{
55
- if (unlikely(copy_from_user(dst, src, len)))
56
- *err_ptr = -EFAULT;
57
- return csum_partial(dst, len, sum);
58
-}
59
-
60
-
61
-static inline __wsum
62
-csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum)
63
-{
64
- memcpy(dst,src,len);
65
- return csum_partial(dst, len, sum);
66
-}
67
-
68
-/*
69
- * Fold a partial checksum without adding pseudo headers
43
+ * Fold a partial checksum without adding pseudo headers.
7044 */
7145 static inline __sum16 csum_fold(__wsum sum)
7246 {
7347 u32 csum = (__force u32) sum;
7448
75
- csum += (csum >> 16) + (csum << 16);
49
+ csum += (csum >> 16) | (csum << 16);
7650 csum >>= 16;
7751 return (__force __sum16) ~csum;
7852 }
7953
8054 /*
81
- * This is a version of ip_compute_csum() optimized for IP headers,
82
- * which always checksum on 4 octet boundaries.
83
- *
55
+ * This is a version of ip_compute_csum() optimized for IP headers,
56
+ * which always checksums on 4 octet boundaries.
8457 */
8558 static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
8659 {
87
- return csum_fold(csum_partial(iph, ihl*4, 0));
60
+ __u64 csum = 0;
61
+ __u32 *ptr = (u32 *)iph;
62
+
63
+ csum += *ptr++;
64
+ csum += *ptr++;
65
+ csum += *ptr++;
66
+ csum += *ptr++;
67
+ ihl -= 4;
68
+ while (ihl--)
69
+ csum += *ptr++;
70
+ csum += (csum >> 32) | (csum << 32);
71
+ return csum_fold((__force __wsum)(csum >> 32));
8872 }
8973
9074 /*
91
- * computes the checksum of the TCP/UDP pseudo-header
92
- * returns a 32-bit checksum
75
+ * Computes the checksum of the TCP/UDP pseudo-header.
76
+ * Returns a 32-bit checksum.
9377 */
94
-static inline __wsum
95
-csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto,
96
- __wsum sum)
78
+static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
79
+ __u8 proto, __wsum sum)
9780 {
98
- __u32 csum = (__force __u32)sum;
81
+ __u64 csum = (__force __u64)sum;
9982
10083 csum += (__force __u32)saddr;
101
- if (csum < (__force __u32)saddr)
102
- csum++;
103
-
10484 csum += (__force __u32)daddr;
105
- if (csum < (__force __u32)daddr)
106
- csum++;
107
-
108
- csum += len + proto;
109
- if (csum < len + proto)
110
- csum++;
111
-
112
- return (__force __wsum)csum;
85
+ csum += len;
86
+ csum += proto;
87
+ csum += (csum >> 32) | (csum << 32);
88
+ return (__force __wsum)(csum >> 32);
11389 }
11490
11591 /*
116
- * computes the checksum of the TCP/UDP pseudo-header
117
- * returns a 16-bit checksum, already complemented
92
+ * Computes the checksum of the TCP/UDP pseudo-header.
93
+ * Returns a 16-bit checksum, already complemented.
11894 */
119
-
120
-static inline __sum16
121
-csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len, __u8 proto,
122
- __wsum sum)
95
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
96
+ __u8 proto, __wsum sum)
12397 {
124
- return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
98
+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
12599 }
126100
127101 /*
128
- * this routine is used for miscellaneous IP-like checksums, mainly
129
- * in icmp.c
102
+ * Used for miscellaneous IP-like checksums, mainly icmp.
130103 */
131
-
132104 static inline __sum16 ip_compute_csum(const void *buff, int len)
133105 {
134106 return csum_fold(csum_partial(buff, len, 0));
135107 }
136108
109
+#define _HAVE_ARCH_IPV6_CSUM
110
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
111
+ const struct in6_addr *daddr,
112
+ __u32 len, __u8 proto, __wsum csum)
113
+{
114
+ __u64 sum = (__force __u64)csum;
115
+
116
+ sum += (__force __u32)saddr->s6_addr32[0];
117
+ sum += (__force __u32)saddr->s6_addr32[1];
118
+ sum += (__force __u32)saddr->s6_addr32[2];
119
+ sum += (__force __u32)saddr->s6_addr32[3];
120
+ sum += (__force __u32)daddr->s6_addr32[0];
121
+ sum += (__force __u32)daddr->s6_addr32[1];
122
+ sum += (__force __u32)daddr->s6_addr32[2];
123
+ sum += (__force __u32)daddr->s6_addr32[3];
124
+ sum += len;
125
+ sum += proto;
126
+ sum += (sum >> 32) | (sum << 32);
127
+ return csum_fold((__force __wsum)(sum >> 32));
128
+}
129
+
137130 #endif /* _S390_CHECKSUM_H */
138
-
139
-