--- zzzz-none-000/linux-3.10.107/arch/mips/include/asm/checksum.h 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/mips/include/asm/checksum.h 2021-02-04 17:41:59.000000000 +0000 @@ -7,10 +7,15 @@ * Copyright (C) 1999 Silicon Graphics, Inc. * Copyright (C) 2001 Thiemo Seufer. * Copyright (C) 2002 Maciej W. Rozycki + * Copyright (C) 2014 Imagination Technologies Ltd. */ #ifndef _ASM_CHECKSUM_H #define _ASM_CHECKSUM_H +#ifdef CONFIG_GENERIC_CSUM +#include +#else + #include #include @@ -29,9 +34,13 @@ */ __wsum csum_partial(const void *buff, int len, __wsum sum); -__wsum __csum_partial_copy_user(const void *src, void *dst, - int len, __wsum sum, int *err_ptr); +__wsum __csum_partial_copy_kernel(const void *src, void *dst, + int len, __wsum sum, int *err_ptr); +__wsum __csum_partial_copy_from_user(const void *src, void *dst, + int len, __wsum sum, int *err_ptr); +__wsum __csum_partial_copy_to_user(const void *src, void *dst, + int len, __wsum sum, int *err_ptr); /* * this is a new version of the above that records errors it finds in *errp, * but continues and zeros the rest of the buffer. @@ -41,8 +50,26 @@ __wsum sum, int *err_ptr) { might_fault(); - return __csum_partial_copy_user((__force void *)src, dst, - len, sum, err_ptr); + if (segment_eq(get_fs(), get_ds())) + return __csum_partial_copy_kernel((__force void *)src, dst, + len, sum, err_ptr); + else + return __csum_partial_copy_from_user((__force void *)src, dst, + len, sum, err_ptr); +} + +#define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER +static inline +__wsum csum_and_copy_from_user(const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) +{ + if (access_ok(VERIFY_READ, src, len)) + return csum_partial_copy_from_user(src, dst, len, sum, + err_ptr); + if (len) + *err_ptr = -EFAULT; + + return sum; } /* @@ -54,9 +81,16 @@ __wsum sum, int *err_ptr) { might_fault(); - if (access_ok(VERIFY_WRITE, dst, len)) - return __csum_partial_copy_user(src, (__force void *)dst, - len, sum, err_ptr); + if (access_ok(VERIFY_WRITE, dst, len)) { + if (segment_eq(get_fs(), get_ds())) + return __csum_partial_copy_kernel(src, + (__force void *)dst, + len, sum, err_ptr); + else + return __csum_partial_copy_to_user(src, + (__force void *)dst, + len, sum, err_ptr); + } if (len) *err_ptr = -EFAULT; @@ -69,27 +103,23 @@ */ __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum); +#define csum_partial_copy_nocheck csum_partial_copy_nocheck /* * Fold a partial checksum without adding pseudo headers */ -static inline __sum16 csum_fold(__wsum sum) +static inline __sum16 csum_fold(__wsum csum) { - __asm__( - " .set push # csum_fold\n" - " .set noat \n" - " sll $1, %0, 16 \n" - " addu %0, $1 \n" - " sltu $1, %0, $1 \n" - " srl %0, %0, 16 \n" - " addu %0, $1 \n" - " xori %0, 0xffff \n" - " .set pop" - : "=r" (sum) - : "0" (sum)); + u32 sum = (__force u32)csum;; + + sum += (sum << 16); + csum = (sum < csum); + sum >>= 16; + sum += csum; - return (__force __sum16)sum; + return (__force __sum16)~sum; } +#define csum_fold csum_fold /* * This is a version of ip_compute_csum() optimized for IP headers, @@ -104,30 +134,35 @@ const unsigned int *stop = word + ihl; unsigned int csum; int carry; + unsigned int w; - csum = word[0]; - csum += word[1]; - carry = (csum < word[1]); + csum = net_hdr_word(word++); + + w = net_hdr_word(word++); + csum += w; + carry = (csum < w); csum += carry; - csum += word[2]; - carry = (csum < word[2]); + w = net_hdr_word(word++); + csum += w; + carry = (csum < w); csum += carry; - csum += word[3]; - carry = (csum < word[3]); + w = net_hdr_word(word++); + csum += w; + carry = (csum < w); csum += carry; - word += 4; do { - csum += *word; - carry = (csum < *word); + w = net_hdr_word(word++); + csum += w; + carry = (csum < w); csum += carry; - word++; } while (word != stop); return csum_fold(csum); } +#define ip_fast_csum ip_fast_csum static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, unsigned short proto, @@ -172,18 +207,7 @@ return sum; } - -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - unsigned short len, - unsigned short proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); -} +#define csum_tcpudp_nofold csum_tcpudp_nofold /* * this routine is used for miscellaneous IP-like checksums, mainly @@ -194,69 +218,7 @@ return csum_fold(csum_partial(buff, len, 0)); } -#define _HAVE_ARCH_IPV6_CSUM -static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, - const struct in6_addr *daddr, - __u32 len, unsigned short proto, - __wsum sum) -{ - __asm__( - " .set push # csum_ipv6_magic\n" - " .set noreorder \n" - " .set noat \n" - " addu %0, %5 # proto (long in network byte order)\n" - " sltu $1, %0, %5 \n" - " addu %0, $1 \n" - - " addu %0, %6 # csum\n" - " sltu $1, %0, %6 \n" - " lw %1, 0(%2) # four words source address\n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 4(%2) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 8(%2) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 12(%2) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 0(%3) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 4(%3) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 8(%3) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " lw %1, 12(%3) \n" - " addu %0, $1 \n" - " addu %0, %1 \n" - " sltu $1, %0, %1 \n" - - " addu %0, $1 # Add final carry\n" - " .set pop" - : "=r" (sum), "=r" (proto) - : "r" (saddr), "r" (daddr), - "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); - - return csum_fold(sum); -} +#include +#endif /* CONFIG_GENERIC_CSUM */ #endif /* _ASM_CHECKSUM_H */