]> err.no Git - linux-2.6/commitdiff
The type of sum in csum_tcpudp_nofold is "unsigned int", so when we assign
authorRalf Baechle <ralf@linux-mips.org>
Tue, 20 Sep 2005 10:56:26 +0000 (10:56 +0000)
committerRalf Baechle <ralf@linux-mips.org>
Sat, 29 Oct 2005 18:32:25 +0000 (19:32 +0100)
to it in an asm() block, and we're running on a system with 64-bit
registers, it is vitally important that we sign extend it correctly before
returning to C.  Otherwise the stray high bits will be preserved into
csum_fold, and on the SB-1 processor, 32-bit arithmetic on a non
sign-extended register will yield surprising results.

This caused incorrect checksums in some UDP packets for NFS root.  The
problem was mild when using a 10.0.1.x IP address, but severe when
using 192.168.1.x.

Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
include/asm-mips/checksum.h

index 2ff53db8c0239e5ba76d6c1b89e9c9df9bf5e329..b09f8971e95d7fd1ba8ebb1f7ae1a9b758eec826 100644 (file)
@@ -150,7 +150,7 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr,
        "       daddu   %0, %4          \n"
        "       dsll32  $1, %0, 0       \n"
        "       daddu   %0, $1          \n"
-       "       dsrl32  %0, %0, 0       \n"
+       "       dsra32  %0, %0, 0       \n"
 #endif
        "       .set    pop"
        : "=r" (sum)