diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2008-02-23 00:23:48 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-02-29 22:46:48 +0000 |
commit | 94a3f78566ef98a48814d82892f28bb741624cb8 (patch) | |
tree | cb8e4904737c84c64129753e4148b9845b49afa1 | |
parent | b98d7291883f7ed27e3f4b59bc12dc963c9f72a6 (diff) | |
download | op-kernel-dev-94a3f78566ef98a48814d82892f28bb741624cb8.zip op-kernel-dev-94a3f78566ef98a48814d82892f28bb741624cb8.tar.gz |
[ARM] 4837/1: make __get_unaligned_*() return unsigned types
Eric Sandeen tracked an XFS on ARM corruption bug down to a function
under fs/xfs/ involving some get_unaligned() calls on u64 pointers.
As it turns out, calling ARM's get_unaligned() on a u64 pointer
pointing to the following byte sequence:
80 81 82 83 84 85 86 87
would return ffffffff83828180 (LE mode.) This turns out to be
because of implicit u8 -> int promotion in ARM's implementation of
various helpers for get_unaligned(), causing them to accidentally
return signed instead of unsigned values, which in turn caused the
subsequent casts to unsigned long long in __get_unaligned_8_[bl]e()
to sign-extend the lower words.
Fix by casting the return values of __get_unaligned_[24]_[bl]e()
to unsigned int.
Cc: Eric Sandeen <sandeen@sandeen.net>
Cc: Rabeeh Khoury <rabeeh@marvell.com>
Cc: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | include/asm-arm/unaligned.h | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 8431f6e..5db03cf 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h @@ -40,16 +40,16 @@ extern int __bug_unaligned_x(const void *ptr); */ #define __get_unaligned_2_le(__p) \ - (__p[0] | __p[1] << 8) + (unsigned int)(__p[0] | __p[1] << 8) #define __get_unaligned_2_be(__p) \ - (__p[0] << 8 | __p[1]) + (unsigned int)(__p[0] << 8 | __p[1]) #define __get_unaligned_4_le(__p) \ - (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) + (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) #define __get_unaligned_4_be(__p) \ - (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) + (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) #define __get_unaligned_8_le(__p) \ ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ |