diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-09-20 06:56:26 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2005-10-29 14:32:25 -0400 |
commit | e97288386a316e3960b758a60ae7cd17b3ee10e7 (patch) | |
tree | 5a40713cc8ceec43a9ed0d2f02373a1e5a2d648f /include/asm-mips | |
parent | 2cce8263228ac8926d675cfa19e50ca0af9e05e4 (diff) |
The type of sum in csum_tcpudp_nofold is "unsigned int", so when we assign
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>
Diffstat (limited to 'include/asm-mips')
-rw-r--r-- | include/asm-mips/checksum.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h index 2ff53db8c023..b09f8971e95d 100644 --- a/include/asm-mips/checksum.h +++ b/include/asm-mips/checksum.h | |||
@@ -150,7 +150,7 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr, | |||
150 | " daddu %0, %4 \n" | 150 | " daddu %0, %4 \n" |
151 | " dsll32 $1, %0, 0 \n" | 151 | " dsll32 $1, %0, 0 \n" |
152 | " daddu %0, $1 \n" | 152 | " daddu %0, $1 \n" |
153 | " dsrl32 %0, %0, 0 \n" | 153 | " dsra32 %0, %0, 0 \n" |
154 | #endif | 154 | #endif |
155 | " .set pop" | 155 | " .set pop" |
156 | : "=r" (sum) | 156 | : "=r" (sum) |