summaryrefslogtreecommitdiff
path: root/include/linux/unaligned
diff options
context:
space:
mode:
authorWill Newton <will.newton@gmail.com>2010-12-22 04:24:29 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2010-12-23 06:43:34 +0300
commit4e06fd14d5fa78826397c891654a37e5a36ee827 (patch)
tree816fc9951f6a6c1246e7974f95ffd71c7e861f76 /include/linux/unaligned
parent91facc22dec964683aef88f5620a790a6e46b98a (diff)
downloadlinux-4e06fd14d5fa78826397c891654a37e5a36ee827.tar.xz
include/linux/unaligned: pack the whole struct rather than just the field
The current packed struct implementation of unaligned access adds the packed attribute only to the field within the unaligned struct rather than to the struct as a whole. This is not sufficient to enforce proper behaviour on architectures with a default struct alignment of more than one byte. For example, the current implementation of __get_unaligned_cpu16 when compiled for arm with gcc -O1 -mstructure-size-boundary=32 assumes the struct is on a 4 byte boundary so performs the load of the 16bit packed field as if it were on a 4 byte boundary: __get_unaligned_cpu16: ldrh r0, [r0, #0] bx lr Moving the packed attribute to the struct rather than the field causes the proper unaligned access code to be generated: __get_unaligned_cpu16: ldrb r3, [r0, #0] @ zero_extendqisi2 ldrb r0, [r0, #1] @ zero_extendqisi2 orr r0, r3, r0, asl #8 bx lr Signed-off-by: Will Newton <will.newton@gmail.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/unaligned')
-rw-r--r--include/linux/unaligned/packed_struct.h6
1 files changed, 3 insertions, 3 deletions
diff --git a/include/linux/unaligned/packed_struct.h b/include/linux/unaligned/packed_struct.h
index 2498bb9fe002..c9a6abd972a1 100644
--- a/include/linux/unaligned/packed_struct.h
+++ b/include/linux/unaligned/packed_struct.h
@@ -3,9 +3,9 @@
#include <linux/kernel.h>
-struct __una_u16 { u16 x __attribute__((packed)); };
-struct __una_u32 { u32 x __attribute__((packed)); };
-struct __una_u64 { u64 x __attribute__((packed)); };
+struct __una_u16 { u16 x; } __attribute__((packed));
+struct __una_u32 { u32 x; } __attribute__((packed));
+struct __una_u64 { u64 x; } __attribute__((packed));
static inline u16 __get_unaligned_cpu16(const void *p)
{