14 Jan, 2011

1 commit


23 Dec, 2010

1 commit

  • 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
    Cc: Arnd Bergmann
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Will Newton
     

24 Sep, 2009

1 commit

  • When unaligned accesses are required for uncompressing a kernel (such as
    for LZO decompression on ARM in a patch that follows), including
    causes issues as it brings in a lot of things that are
    not available in the decompression environment.

    linux/kernel.h brings at least:
    extern int console_printk[];
    extern const char hex_asc[];
    which causes errors at link-time as they are not available when
    compiling the pre-boot environement. There are also a few others:

    arch/arm/boot/compressed/misc.o: In function `valid_user_regs':
    arch/arm/include/asm/ptrace.h:158: undefined reference to `elf_hwcap'
    arch/arm/boot/compressed/misc.o: In function `console_silent':
    include/linux/kernel.h:292: undefined reference to `console_printk'
    arch/arm/boot/compressed/misc.o: In function `console_verbose':
    include/linux/kernel.h:297: undefined reference to `console_printk'
    arch/arm/boot/compressed/misc.o: In function `pack_hex_byte':
    include/linux/kernel.h:360: undefined reference to `hex_asc'
    arch/arm/boot/compressed/misc.o: In function `hweight_long':
    include/linux/bitops.h:45: undefined reference to `hweight32'
    arch/arm/boot/compressed/misc.o: In function `__cmpxchg_local_generic':
    include/asm-generic/cmpxchg-local.h:21: undefined reference to `wrong_size_cmpxchg'
    include/asm-generic/cmpxchg-local.h:42: undefined reference to `wrong_size_cmpxchg'
    arch/arm/boot/compressed/misc.o: In function `__xchg':
    arch/arm/include/asm/system.h:309: undefined reference to `__bad_xchg'

    However, those files apparently use nothing from , all
    they need is the declaration of types such as u32 or u64, so
    should be enough

    Signed-off-by: Albin Tonnerre
    Cc: Sam Ravnborg
    Cc: Russell King
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: "H. Peter Anvin"
    Cc: Phillip Lougher
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Albin Tonnerre
     

29 Apr, 2008

1 commit

  • Create a linux/unaligned directory similar in spirit to the linux/byteorder
    folder to hold generic implementations collected from various arches.

    Currently there are five implementations:
    1) packed_struct.h: C-struct based, from asm-generic/unaligned.h
    2) le_byteshift.h: Open coded byte-swapping, heavily based on asm-arm
    3) be_byteshift.h: Open coded byte-swapping, heavily based on asm-arm
    4) memmove.h: taken from multiple implementations in tree
    5) access_ok.h: taken from x86 and others, unaligned access is ok.

    All of the new implementations checks for sizes not equal to 1,2,4,8
    and will fail to link.

    API additions:

    get_unaligned_{le16|le32|le64|be16|be32|be64}(p) which is meant to replace
    code of the form:
    le16_to_cpu(get_unaligned((__le16 *)p));

    put_unaligned_{le16|le32|le64|be16|be32|be64}(val, pointer) which is meant to
    replace code of the form:
    put_unaligned(cpu_to_le16(val), (__le16 *)p);

    The headers that arches should include from their asm/unaligned.h:

    access_ok.h : Wrappers of the byteswapping functions in asm/byteorder

    Choose a particular implementation for little-endian access:
    le_byteshift.h
    le_memmove.h (arch must be LE)
    le_struct.h (arch must be LE)

    Choose a particular implementation for big-endian access:
    be_byteshift.h
    be_memmove.h (arch must be BE)
    be_struct.h (arch must be BE)

    After including as needed from the above, include unaligned/generic.h and
    define your arch's get/put_unaligned as (for LE):

    Signed-off-by: Harvey Harrison
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Harvey Harrison