Commit e9728838 authored by Ralf Baechle's avatar Ralf Baechle

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: default avatarDaniel Jacobowitz <dan@codesourcery.com>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 2cce8263
...@@ -150,7 +150,7 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr, ...@@ -150,7 +150,7 @@ static inline unsigned int csum_tcpudp_nofold(unsigned long saddr,
" daddu %0, %4 \n" " daddu %0, %4 \n"
" dsll32 $1, %0, 0 \n" " dsll32 $1, %0, 0 \n"
" daddu %0, $1 \n" " daddu %0, $1 \n"
" dsrl32 %0, %0, 0 \n" " dsra32 %0, %0, 0 \n"
#endif #endif
" .set pop" " .set pop"
: "=r" (sum) : "=r" (sum)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment