summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/checksum.h
AgeCommit message (Collapse)AuthorFilesLines
2024-02-13MIPS: Add 'memory' clobber to csum_ipv6_magic() inline assemblerGuenter Roeck1-1/+2
After 'lib: checksum: Use aligned accesses for ip_fast_csum and csum_ipv6_magic tests' was applied, the test_csum_ipv6_magic unit test started failing for all mips platforms, both little and bit endian. Oddly enough, adding debug code into test_csum_ipv6_magic() made the problem disappear. The gcc manual says: "The "memory" clobber tells the compiler that the assembly code performs memory reads or writes to items other than those listed in the input and output operands (for example, accessing the memory pointed to by one of the input parameters) " This is definitely the case for csum_ipv6_magic(). Indeed, adding the 'memory' clobber fixes the problem. Cc: Charlie Jenkins <charlie@rivosinc.com> Cc: Palmer Dabbelt <palmer@rivosinc.com> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Charlie Jenkins <charlie@rivosinc.com> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
2022-05-23MIPS: Rewrite `csum_tcpudp_nofold' in plain CMaciej W. Rozycki1-41/+38
Recent commit 198688edbf77 ("MIPS: Fix inline asm input/output type mismatch in checksum.h used with Clang") introduced a code size and performance regression with 64-bit code emitted for `csum_tcpudp_nofold' by GCC, caused by a redundant truncation operation produced due to a data type change made to the variable associated with the inline assembly's output operand. The intent previously expressed here with operands and constraints for optimal code was to have the output operand share a register with one inputs, both of a different integer type each. This is perfectly valid with the MIPS psABI where a register can hold integer data of different types and the assembly code used here makes data stored in the output register match the data type used with the output operand, however it has turned out impossible to express this arrangement in source code such as to satisfy LLVM, apparently due to the compiler's internal limitations. There is nothing peculiar about the inline assembly `csum_tcpudp_nofold' includes however, though it does choose assembly instructions carefully. Rewrite this piece of assembly in plain C then, using corresponding C language operations, making GCC produce the same assembly instructions, possibly shuffled, in the general case and sometimes actually fewer of them where an input is constant, because the compiler does not have to reload it to a register (operand constraints could be adjusted for that, but the plain C approach is cleaner anyway). Example code size changes are as follows, for a 32-bit configuration: text data bss total filename 5920480 1347236 126592 7394308 vmlinux-old 5920480 1347236 126592 7394308 vmlinux-now 5919728 1347236 126592 7393556 vmlinux-c and for a 64-bit configuration: text data bss total filename 6024112 1790828 225728 8040668 vmlinux-old 6024128 1790828 225728 8040684 vmlinux-now 6023760 1790828 225728 8040316 vmlinux-c respectively, where "old" is with the commit referred reverted, "now" is with no change, and "c" is with this change applied. Signed-off-by: Maciej W. Rozycki <macro@orcam.me.uk> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
2021-01-27MIPS: Fix inline asm input/output type mismatch in checksum.h used with ClangTiezhu Yang1-2/+4
Fix the following build error when make M=samples/bpf used with Clang: CLANG-bpf samples/bpf/sockex2_kern.o In file included from samples/bpf/sockex2_kern.c:7: In file included from ./include/uapi/linux/if_tunnel.h:7: In file included from ./include/linux/ip.h:16: In file included from ./include/linux/skbuff.h:28: In file included from ./include/net/checksum.h:22: ./arch/mips/include/asm/checksum.h:161:9: error: unsupported inline asm: input with type 'unsigned long' matching output with type '__wsum' (aka 'unsigned int') : "0" ((__force unsigned long)daddr), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 error generated. This is a known issue on MIPS [1], the changed code can be compiled successfully by both GCC and Clang. [1] https://lore.kernel.org/linux-mips/CAG_fn=W0JHf8QyUX==+rQMp8PoULHrsQCa9Htffws31ga8k-iw@mail.gmail.com/ Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
2020-08-20mips: propagate the calling convention change down into ↵Al Viro1-20/+6
__csum_partial_copy_..._user() and turn the exception handlers into simply returning 0, which simplifies the hell out of things in csum_partial.S Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-08-20mips: __csum_partial_copy_kernel() has no users leftAl Viro1-3/+0
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-08-20mips: csum_and_copy_{to,from}_user() are never called under KERNEL_DSAl Viro1-25/+7
they are only called for iovec-backed iov_iter and under KERNEL_DS an attempt to create such a beast will yield a kvec-backed one. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-08-20saner calling conventions for csum_and_copy_..._user()Al Viro1-24/+22
All callers of these primitives will * discard anything we might've copied in case of error * ignore the csum value in case of error * always pass 0xffffffff as the initial sum, so the resulting csum value (in case of success, that is) will never be 0. That suggest the following calling conventions: * don't pass err_ptr - just return 0 on error. * don't bother with zeroing destination, etc. in case of error * don't pass the initial sum - just use 0xffffffff. This commit does the minimal conversion in the instances of csum_and_copy_...(); the changes of actual asm code behind them are done later in the series. Note that this asm code is often shared with csum_partial_copy_nocheck(); the difference is that csum_partial_copy_nocheck() passes 0 for initial sum while csum_and_copy_..._user() pass 0xffffffff. Fortunately, we are free to pass 0xffffffff in all cases and subsequent patches will use that freedom without any special comments. A part that could be split off: parisc and uml/i386 claimed to have csum_and_copy_to_user() instances of their own, but those were identical to the generic one, so we simply drop them. Not sure if it's worth a separate commit... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-08-20csum_partial_copy_nocheck(): drop the last argumentAl Viro1-2/+5
It's always 0. Note that we theoretically could use ~0U as well - result will be the same modulo 0xffff, _if_ the damn thing did the right thing for any value of initial sum; later we'll make use of that when convenient. However, unlike csum_and_copy_..._user(), there are instances that did not work for arbitrary initial sums; c6x is one such. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-08-20unify generic instances of csum_partial_copy_nocheck()Al Viro1-1/+1
quite a few architectures have the same csum_partial_copy_nocheck() - simply memcpy() the data and then return the csum of the copy. hexagon, parisc, ia64, s390, um: explicitly spelled out that way. arc, arm64, csky, h8300, m68k/nommu, microblaze, mips/GENERIC_CSUM, nds32, nios2, openrisc, riscv, unicore32: end up picking the same thing spelled out in lib/checksum.h (with varying amounts of perversions along the way). everybody else (alpha, arm, c6x, m68k/mmu, mips/!GENERIC_CSUM, powerpc, sh, sparc, x86, xtensa) have non-generic variants. For all except c6x the declaration is in their asm/checksum.h. c6x uses the wrapper from asm-generic/checksum.h that would normally lead to the lib/checksum.h instance, but in case of c6x we end up using an asm function from arch/c6x instead. Screw that mess - have architectures with private instances define _HAVE_ARCH_CSUM_AND_COPY in their asm/checksum.h and have the default one right in net/checksum.h conditional on _HAVE_ARCH_CSUM_AND_COPY *not* defined. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-06-25MIPS: checksum: fix sparse flooding on asm/checksum.hAlexander Lobakin1-2/+2
csum_fold() in MIPS' asm/checksum.h is another source of sparse flooding when building different networking source code. The thing is that only half of __wsum <--> u32 casts inside the function is forced, which is insufficient. Add all necessary forced typecasting to stop floods and simplify actual bug hunting. Signed-off-by: Alexander Lobakin <alobakin@pm.me> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
2019-01-04Remove 'type' argument from access_ok() functionLinus Torvalds1-2/+2
Nobody has actually used the type (VERIFY_READ vs VERIFY_WRITE) argument of the user address range verification function since we got rid of the old racy i386-only code to walk page tables by hand. It existed because the original 80386 would not honor the write protect bit when in kernel mode, so you had to do COW by hand before doing any user access. But we haven't supported that in a long time, and these days the 'type' argument is a purely historical artifact. A discussion about extending 'user_access_begin()' to do the range checking resulted this patch, because there is no way we're going to move the old VERIFY_xyz interface to that model. And it's best done at the end of the merge window when I've done most of my merges, so let's just get this done once and for all. This patch was mostly done with a sed-script, with manual fix-ups for the cases that weren't of the trivial 'access_ok(VERIFY_xyz' form. There were a couple of notable cases: - csky still had the old "verify_area()" name as an alias. - the iter_iov code had magical hardcoded knowledge of the actual values of VERIFY_{READ,WRITE} (not that they mattered, since nothing really used it) - microblaze used the type argument for a debug printout but other than those oddities this should be a total no-op patch. I tried to fix up all architectures, did fairly extensive grepping for access_ok() uses, and the changes are trivial, but I may have missed something. Any missed conversion should be trivially fixable, though. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-01-24MIPS: Fix trailing semicolonLuis de Bethencourt1-1/+1
The trailing semicolon is an empty statement that does no operation. Removing it since it doesn't do anything. Fixes: d0f0f63ac137 ("MIPS: Rewrite csum_fold to plain C.") Signed-off-by: Luis de Bethencourt <luisbg@kernel.org> Cc: Joe Perches <joe@perches.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/18517/ Signed-off-by: James Hogan <jhogan@kernel.org>
2017-03-28new helper: uaccess_kernel()Al Viro1-2/+2
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2017-02-17MIPS: Fix special case in 64 bit IP checksumming.Ralf Baechle1-0/+2
For certain arguments such as saddr = 0xc0a8fd60, daddr = 0xc0a8fda1, len = 80, proto = 17, sum = 0x7eae049d there will be a carry when folding the intermediate 64 bit checksum to 32 bit but the code doesn't add the carry back to the one's complement sum, thus an incorrect result will be generated. Reported-by: Mark Zhang <bomb.zhang@gmail.com> Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Reviewed-by: James Hogan <james.hogan@imgtec.com> Cc: stable@vger.kernel.org Signed-off-by: James Hogan <james.hogan@imgtec.com>
2016-12-24Replace <asm/uaccess.h> with <linux/uaccess.h> globallyLinus Torvalds1-1/+1
This was entirely automated, using the script by Al: PATT='^[[:blank:]]*#[[:blank:]]*include[[:blank:]]*<asm/uaccess.h>' sed -i -e "s!$PATT!#include <linux/uaccess.h>!" \ $(git grep -l "$PATT"|grep -v ^include/linux/uaccess.h) to do the replacement at the end of the merge window. Requested-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2016-03-14ipv6: Pass proto to csum_ipv6_magic as __u8 instead of unsigned shortAlexander Duyck1-1/+1
This patch updates csum_ipv6_magic so that it correctly recognizes that protocol is a unsigned 8 bit value. This will allow us to better understand what limitations may or may not be present in how we handle the data. For example there are a number of places that call htonl on the protocol value. This is likely not necessary and can be replaced with a multiplication by ntohl(1) which will be converted to a shift by the compiler. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2016-03-14ipv4: Update parameters for csum_tcpudp_magic to their original typesAlexander Duyck1-3/+3
This patch updates all instances of csum_tcpudp_magic and csum_tcpudp_nofold to reflect the types that are usually used as the source inputs. For example the protocol field is populated based on nexthdr which is actually an unsigned 8 bit value. The length is usually populated based on skb->len which is an unsigned integer. This addresses an issue in which the IPv6 function csum_ipv6_magic was generating a checksum using the full 32b of skb->len while csum_tcpudp_magic was only using the lower 16 bits. As a result we could run into issues when attempting to adjust the checksum as there was no protocol agnostic way to update it. With this change the value is still truncated as many architectures use "(len + proto) << 8", however this truncation only occurs for values greater than 16776960 in length and as such is unlikely to occur as we stop the inner headers at ~64K in size. I did have to make a few minor changes in the arm, mn10300, nios2, and score versions of the function in order to support these changes as they were either using things such as an OR to combine the protocol and length, or were using ntohs to convert the length which would have truncated the value. I also updated a few spots in terms of whitespace and type differences for the addresses. Most of this was just to make sure all of the definitions were in sync going forward. Signed-off-by: Alexander Duyck <aduyck@mirantis.com> Signed-off-by: David S. Miller <davem@davemloft.net>
2015-04-01MIPS: LLVMLinux: Fix an 'inline asm input/output type mismatch' error.Daniel Sanders1-2/+4
Replace incorrect matching constraint that caused the error with an alternative that still has the required constraints on the inline assembly. This is the error message reported by clang: arch/mips/include/asm/checksum.h:285:27: error: unsupported inline asm: input with type '__be32' (aka 'unsigned int') matching output with type 'unsigned short' "0" (htonl(len)), "1" (htonl(proto)), "r" (sum)); ^~~~~~~~~~~~ The changed code can be compiled successfully by both gcc and clang. Signed-off-by: Daniel Sanders <daniel.sanders@imgtec.com> Signed-off-by: Toma Tabacu <toma.tabacu@imgtec.com> Suggested-by: Maciej W. Rozycki <macro@linux-mips.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Markos Chandras <markos.chandras@imgtec.com> Cc: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Cc: linux-mips@linux-mips.org Cc: linux-kernel@vger.kernel.org Patchwork: https://patchwork.linux-mips.org/patch/9313/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2015-02-17MIPS: Use generic checksum functions for MIPS R6Markos Chandras1-0/+5
The following instructions have been removed from MIPS R6 ulw, ulh, swl, lwr, lwl, swr. However, all of them are used in the MIPS specific checksum implementation. As a result of which, we will use the generic checksum on MIPS R6 Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
2015-01-13MIPS: Use generic csum_tcpudp_magic for MIPS.Ralf Baechle1-13/+0
Its implementation is identical to MIPS. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2015-01-13MIPS: Use <asm-generic/checksum.h>Ralf Baechle1-0/+7
Right now the MIPS <asm/checksum.h> still overrides all functions. This will change in the future. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2015-01-13MIPS: Rewrite csum_fold to plain C.Ralf Baechle1-14/+8
This isn't only short and easier to read and fully portable but also shrinks a Malta kernel's by 160 bytes. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2014-03-27MIPS: asm: checksum: Add MIPS specific csum_and_copy_from_user functionLeonid Yegoshin1-0/+14
A MIPS specific csum_and_copy_from_user function is necessary because the generic one from include/net/checksum.h will not work for EVA. This is because the generic one will link to symbols from lib/checksum.c which are not EVA aware. Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
2014-03-27MIPS: asm: checksum: Split kernel and user copy operationsLeonid Yegoshin1-6/+16
In EVA mode, different instructions need to be used to read/write from kernel and userland. In non-EVA mode, there is no functional difference. The current address limit is checked to decide the type of operation that will be performed. Signed-off-by: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
2014-03-27MIPS: checksum: Split the 'copy_user' symbolMarkos Chandras1-6/+12
The 'copy_user' symbol can be used to copy from or to userland so we will use two different symbols for these operations. This makes no difference in the existing code, but when the core is operating in EVA mode, different instructions need to be used to read and write to userland address space. The old function has also been renamed to 'copy_kernel' to denote that it is suitable for copy data to and from kernel space. Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
2013-02-01MIPS: Whitespace cleanup.Ralf Baechle1-1/+1
Having received another series of whitespace patches I decided to do this once and for all rather than dealing with this kind of patches trickling in forever. Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2009-05-14MIPS: uaccess: Switch lock annotations to might_fault().Ralf Baechle1-2/+2
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
2008-10-11MIPS: Move headfiles to new location below arch/mips/includeRalf Baechle1-0/+260
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>