memmove broken on alpha - was Re: NFS oddity (2.4.0test13pre4ac2 server, 2.0.36/2.2.14 clients)

From: Neil Brown (neilb@cse.unsw.edu.au)
Date: Fri Dec 29 2000 - 21:02:44 EST


[ extra detail included because I have added linux-alpha and lins to
the cc list]

It appears that memmove is broken on the alpha architecture.

memmove is used by net/sunrpc/xdr.c:xdr_decode_string
to move a string 4 bytes down in memory.
memmove(X-4, X, 8) should change
    
 X: 00 00 00 08 67 69 6c 62 65 72 74 64
to
 X: 67 69 6c 62 65 72 74 64 65 72 74 64

Instead it changes it to

 X: 65 72 74 64 65 72 74 64 65 72 74 64

This is my first time in alpha assembler, but it looks fairly readable
and the comments help....

Working from
  arch/alpha/lib/memmove.S

As the two regions overlap, it doesn't fall back on memcpy,
As the two regions are not co-aligned so it jumps to $misaligned.

Now the code in $misaligned, like all the code in memmove.S seems to
move a block of memory starting at the top, and moving downwards.
But in this example, we need to start at the bottom and move upwards.

Currently the code falls back on memcpy :

 if (dest+n <= src || dest >= src + n)

However if should also fall back on memcpy:
 
 if (dest <= src)

So the test should be:

  if (dest <= src || dest >= src + n)

which I think translates to the following patch:

--- arch/alpha/lib/memmove.S 2000/12/30 01:59:28 1.1
+++ arch/alpha/lib/memmove.S 2000/12/30 01:59:49
@@ -17,7 +17,7 @@
 memmove:
         addq $16,$18,$4
         addq $17,$18,$5
- cmpule $4,$17,$1 /* dest + n <= src */
+ cmpule $16,$17,$1 /* dest <= src */
         cmpule $5,$16,$2 /* dest >= src + n */
 
         bis $1,$2,$1

NeilBrown
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Dec 31 2000 - 21:00:13 EST