aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2008-02-22 18:23:48 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-02-29 17:46:48 -0500
commit94a3f78566ef98a48814d82892f28bb741624cb8 (patch)
treecb8e4904737c84c64129753e4148b9845b49afa1
parentb98d7291883f7ed27e3f4b59bc12dc963c9f72a6 (diff)
[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.h8
1 files changed, 4 insertions, 4 deletions
diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h
index 8431f6eed5c6..5db03cf3b905 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);
40 */ 40 */
41 41
42#define __get_unaligned_2_le(__p) \ 42#define __get_unaligned_2_le(__p) \
43 (__p[0] | __p[1] << 8) 43 (unsigned int)(__p[0] | __p[1] << 8)
44 44
45#define __get_unaligned_2_be(__p) \ 45#define __get_unaligned_2_be(__p) \
46 (__p[0] << 8 | __p[1]) 46 (unsigned int)(__p[0] << 8 | __p[1])
47 47
48#define __get_unaligned_4_le(__p) \ 48#define __get_unaligned_4_le(__p) \
49 (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) 49 (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24)
50 50
51#define __get_unaligned_4_be(__p) \ 51#define __get_unaligned_4_be(__p) \
52 (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) 52 (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
53 53
54#define __get_unaligned_8_le(__p) \ 54#define __get_unaligned_8_le(__p) \
55 ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ 55 ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \