kernel: Move arches to use common unaligned access
PATCH v4 2/2 kernel: Move arches to use common unaligned access
[Andrew: I think we're getting close to something that could go into -mm]
Unaligned access is ok for the following arches:
cris, m68k, mn10300, powerpc, s390, x86
Arches that use the memmove implementation for native endian, and the byteshifting for the opposite endianness.
h8300, m32r, xtensa
Packed struct for native endian, byteshifting for other endian:
alpha, blackfin, ia64, parisc, sparc, sparc64, mips, sh
m86knommu is generic_be for Coldfire, otherwise unaligned access is ok.
frv, arm chooses endianness based on compiler settings, uses the byteshifting versions. Remove the unaligned trap handler from frv as it is now unused.
v850 is le, uses the byteshifting versions for both be and le.
Remove the now unused asm-generic implementation.
---
v4: Update to consistent #ifndef _ASM_ARCH_UNALIGNED_H tests in each header file. Remove the misaligned data access handler from FRV as we have moved it to a generic byteshifting version in all cases.
arch/frv/kernel/traps.c | 7 +- arch/frv/mm/unaligned.c | 217 ------------------------------------- include/asm-alpha/unaligned.h | 13 ++- include/asm-arm/unaligned.h | 174 +---------------------------- include/asm-avr32/unaligned.h | 13 ++- include/asm-blackfin/unaligned.h | 13 ++- include/asm-cris/unaligned.h | 17 ++-- include/asm-frv/unaligned.h | 196 ++-------------------------------- include/asm-generic/unaligned.h | 124 --------------------- include/asm-h8300/unaligned.h | 20 ++-- include/asm-ia64/unaligned.h | 7 +- include/asm-m32r/unaligned.h | 27 +++--- include/asm-m68k/unaligned.h | 17 ++-- include/asm-m68knommu/unaligned.h | 22 ++-- include/asm-mips/unaligned.h | 37 +++---- include/asm-mn10300/unaligned.h | 130 ++--------------------- include/asm-parisc/unaligned.h | 12 ++- include/asm-powerpc/unaligned.h | 11 +-- include/asm-s390/unaligned.h | 25 ++--- include/asm-sh/unaligned.h | 20 +++- include/asm-sparc/unaligned.h | 10 ++- include/asm-sparc64/unaligned.h | 10 ++- include/asm-um/unaligned.h | 6 +- include/asm-v850/unaligned.h | 124 ++-------------------- include/asm-x86/unaligned.h | 32 +----- include/asm-xtensa/unaligned.h | 35 +++--- 26 files changed, 203 insertions(+), 1116 deletions(-)
arch/frv/kernel/traps.c +2 -5
@@ -361,11 +361,8 @@ asmlinkage void memory_access_exception(unsigned long esr0,#ifdef CONFIG_MMU unsigned long fixup; -if ((esr0 & ESRx_EC) == ESRx_EC_DATA_ACCESS) -if (handle_misalignment (esr0, ear0, epcr0) ==0 ) -return ; - -if ((fixup =search_exception_table (__frame->pc)) !=0 ) { + fixup =search_exception_table (__frame->pc); +if (fixup) { __frame->pc = fixup;return ; }
arch/frv/mm/unaligned.c deleted +0 -217
217 lines not on this page · raw message
include/asm-alpha/unaligned.h +9 -4
@@ -1,6 +1,11 @@ -#ifndef __ALPHA_UNALIGNED_H -#define __ALPHA_UNALIGNED_H +#ifndef _ASM_ALPHA_UNALIGNED_H +#define _ASM_ALPHA_UNALIGNED_H -#include <asm-generic/unaligned.h> +#include <linux/unaligned/le_struct.h> +#include <linux/unaligned/be_byteshift.h> +#include <linux/unaligned/generic.h> -#endif +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le + +#endif /* _ASM_ALPHA_UNALIGNED_H */
include/asm-arm/unaligned.h +6 -168
181 lines not on this page · raw message
include/asm-avr32/unaligned.h +9 -4
@@ -1,5 +1,5 @@ -#ifndef __ASM_AVR32_UNALIGNED_H -#define __ASM_AVR32_UNALIGNED_H +#ifndef _ASM_AVR32_UNALIGNED_H +#define _ASM_AVR32_UNALIGNED_H/* * AVR32 can handle some unaligned accesses, depending on the
@@ -11,6 +11,11 @@* optimize word loads in general. */ -#include <asm-generic/unaligned.h> +#include <linux/unaligned/be_struct.h> +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/generic.h> -#endif /* __ASM_AVR32_UNALIGNED_H */ +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be + +#endif /* _ASM_AVR32_UNALIGNED_H */
include/asm-blackfin/unaligned.h +9 -4
@@ -1,6 +1,11 @@ -#ifndef __BFIN_UNALIGNED_H -#define __BFIN_UNALIGNED_H +#ifndef _ASM_BLACKFIN_UNALIGNED_H +#define _ASM_BLACKFIN_UNALIGNED_H -#include <asm-generic/unaligned.h> +#include <linux/unaligned/le_struct.h> +#include <linux/unaligned/be_byteshift.h> +#include <linux/unaligned/generic.h> -#endif /* __BFIN_UNALIGNED_H */ +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le + +#endif /* _ASM_BLACKFIN_UNALIGNED_H */
include/asm-cris/unaligned.h +7 -10
@@ -1,16 +1,13 @@ -#ifndef __CRIS_UNALIGNED_H -#define __CRIS_UNALIGNED_H +#ifndef _ASM_CRIS_UNALIGNED_H +#define _ASM_CRIS_UNALIGNED_H/* * CRIS can do unaligned accesses itself. -* -* The strange macros are there to make sure these can't -* be misused in a way that makes them not work on other -* architectures where unaligned accesses aren't as simple. */ +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> -#define get_unaligned (ptr) (*(ptr)) +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le -#define put_unaligned (val, ptr) ((void)( *(ptr) = (val) )) - -#endif +#endif /* _ASM_CRIS_UNALIGNED_H */
include/asm-frv/unaligned.h +8 -188
202 lines not on this page · raw message
include/asm-generic/unaligned.h deleted +0 -124
124 lines not on this page · raw message
include/asm-h8300/unaligned.h +8 -12
@@ -1,15 +1,11 @@ -#ifndef __H8300_UNALIGNED_H -#define __H8300_UNALIGNED_H +#ifndef _ASM_H8300_UNALIGNED_H +#define _ASM_H8300_UNALIGNED_H +#include <linux/unaligned/be_memmove.h> +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/generic.h> -/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be -#define get_unaligned (ptr) \ - ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) - -#define put_unaligned (val, ptr) \ - ({ __typeof__(*(ptr)) __tmp = (val); \ - memmove((ptr), &__tmp, sizeof(*(ptr))); \ - (void)0; }) - -#endif +#endif /* _ASM_H8300_UNALIGNED_H */
include/asm-ia64/unaligned.h +6 -1
@@ -1,6 +1,11 @@#ifndef _ASM_IA64_UNALIGNED_H#define _ASM_IA64_UNALIGNED_H -#include <asm-generic/unaligned.h> +#include <linux/unaligned/le_struct.h> +#include <linux/unaligned/be_byteshift.h> +#include <linux/unaligned/generic.h> + +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le#endif /* _ASM_IA64_UNALIGNED_H */
include/asm-m32r/unaligned.h +13 -14
@@ -1,19 +1,18 @@#ifndef _ASM_M32R_UNALIGNED_H#define _ASM_M32R_UNALIGNED_H -/* -* For the benefit of those who are trying to port Linux to another -* architecture, here are some C-language equivalents. -*/ - -#include <asm/string.h> - -#define get_unaligned (ptr) \ - ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) - -#define put_unaligned (val, ptr) \ - ({ __typeof__(*(ptr)) __tmp = (val); \ - memmove((ptr), &__tmp, sizeof(*(ptr))); \ - (void)0; }) +#if defined(__LITTLE_ENDIAN__) +# include <linux/unaligned/le_memmove.h> +# include <linux/unaligned/be_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#else +# include <linux/unaligned/be_memmove.h> +# include <linux/unaligned/le_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#endif #endif /* _ASM_M32R_UNALIGNED_H */
include/asm-m68k/unaligned.h +7 -10
@@ -1,16 +1,13 @@ -#ifndef __M68K_UNALIGNED_H -#define __M68K_UNALIGNED_H +#ifndef _ASM_M68K_UNALIGNED_H +#define _ASM_M68K_UNALIGNED_H/* * The m68k can do unaligned accesses itself. -* -* The strange macros are there to make sure these can't -* be misused in a way that makes them not work on other -* architectures where unaligned accesses aren't as simple. */ +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> -#define get_unaligned (ptr) (*(ptr)) +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be -#define put_unaligned (val, ptr) ((void)( *(ptr) = (val) )) - -#endif +#endif /* _ASM_M68K_UNALIGNED_H */
include/asm-m68knommu/unaligned.h +12 -10
@@ -1,23 +1,25 @@ -#ifndef __M68K_UNALIGNED_H -#define __M68K_UNALIGNED_H +#ifndef _ASM_M68KNOMMU_UNALIGNED_H +#define _ASM_M68KNOMMU_UNALIGNED_H#ifdef CONFIG_COLDFIRE +#include <linux/unaligned/be_struct.h> +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/generic.h> -#include <asm-generic/unaligned.h> +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be#else /* * The m68k can do unaligned accesses itself. -* -* The strange macros are there to make sure these can't -* be misused in a way that makes them not work on other -* architectures where unaligned accesses aren't as simple. */ +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> -#define get_unaligned (ptr) (*(ptr)) -#define put_unaligned (val, ptr) ((void)( *(ptr) = (val) )) +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be#endif -#endif +#endif /* _ASM_M68KNOMMU_UNALIGNED_H */
include/asm-mips/unaligned.h +18 -19
@@ -5,25 +5,24 @@* * Copyright (C) 2007 Ralf Baechle (ralf-6z/[email protected]) */ -#ifndef __ASM_GENERIC_UNALIGNED_H -#define __ASM_GENERIC_UNALIGNED_H +#ifndef _ASM_MIPS_UNALIGNED_H +#define _ASM_MIPS_UNALIGNED_H#include <linux/compiler.h> +#if defined(__MIPSEB__) +# include <linux/unaligned/be_struct.h> +# include <linux/unaligned/le_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#elif defined(__MIPSEL__) +# include <linux/unaligned/le_struct.h> +# include <linux/unaligned/be_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#else +# error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" +#endif -#define get_unaligned (ptr) \ -({ \ - struct __packed { \ - typeof(*(ptr)) __v; \ - } *__p = (void *) (ptr); \ - __p->__v; \ -}) - -#define put_unaligned (val, ptr) \ -do { \ - struct __packed { \ - typeof(*(ptr)) __v; \ - } *__p = (void *) (ptr); \ - __p->__v = (val); \ -} while(0) - -#endif /* __ASM_GENERIC_UNALIGNED_H */ +#endif /* _ASM_MIPS_UNALIGNED_H */
include/asm-mn10300/unaligned.h +7 -123
136 lines not on this page · raw message
include/asm-parisc/unaligned.h +8 -4
@@ -1,7 +1,11 @@ -#ifndef _ASM_PARISC_UNALIGNED_H_ -#define _ASM_PARISC_UNALIGNED_H_ +#ifndef _ASM_PARISC_UNALIGNED_H +#define _ASM_PARISC_UNALIGNED_H -#include <asm-generic/unaligned.h> +#include <linux/unaligned/be_struct.h> +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/generic.h> +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be#ifdef __KERNEL__struct pt_regs ;
@@ -9,4 +13,4 @@ void handle_unaligned(struct pt_regs *regs);int check_unaligned (struct pt_regs *regs);#endif -#endif /* _ASM_PARISC_UNALIGNED_H_ */ +#endif /* _ASM_PARISC_UNALIGNED_H */
include/asm-powerpc/unaligned.h +4 -7
@@ -5,15 +5,12 @@/* * The PowerPC can do unaligned accesses itself in big endian mode. -* -* The strange macros are there to make sure these can't -* be misused in a way that makes them not work on other -* architectures where unaligned accesses aren't as simple. */ +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> -#define get_unaligned (ptr) (*(ptr)) - -#define put_unaligned (val, ptr) ((void)( *(ptr) = (val) )) +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be#endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_UNALIGNED_H */
include/asm-s390/unaligned.h +7 -18
@@ -1,24 +1,13 @@ -/* -* include/asm-s390/unaligned.h -* -* S390 version -* -* Derived from "include/asm-i386/unaligned.h" -*/ - -#ifndef __S390_UNALIGNED_H -#define __S390_UNALIGNED_H +#ifndef _ASM_S390_UNALIGNED_H +#define _ASM_S390_UNALIGNED_H/* * The S390 can do unaligned accesses itself. -* -* The strange macros are there to make sure these can't -* be misused in a way that makes them not work on other -* architectures where unaligned accesses aren't as simple. */ +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> -#define get_unaligned (ptr) (*(ptr)) - -#define put_unaligned (val, ptr) ((void)( *(ptr) = (val) )) +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be -#endif +#endif /* _ASM_S390_UNALIGNED_H */
include/asm-sh/unaligned.h +16 -4
@@ -1,7 +1,19 @@ -#ifndef __ASM_SH_UNALIGNED_H -#define __ASM_SH_UNALIGNED_H +#ifndef _ASM_SH_UNALIGNED_H +#define _ASM_SH_UNALIGNED_H/* SH can't handle unaligned accesses. */ -#include <asm-generic/unaligned.h> +#ifdef __LITTLE_ENDIAN__ +# include <linux/unaligned/le_struct.h> +# include <linux/unaligned/be_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#else +# include <linux/unaligned/be_struct.h> +# include <linux/unaligned/le_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#endif -#endif /* __ASM_SH_UNALIGNED_H */ +#endif /* _ASM_SH_UNALIGNED_H */
include/asm-sparc/unaligned.h +7 -3
@@ -1,6 +1,10 @@ -#ifndef _ASM_SPARC_UNALIGNED_H_ -#define _ASM_SPARC_UNALIGNED_H_ +#ifndef _ASM_SPARC_UNALIGNED_H +#define _ASM_SPARC_UNALIGNED_H -#include <asm-generic/unaligned.h> +#include <linux/unaligned/be_struct.h> +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/generic.h> +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be#endif /* _ASM_SPARC_UNALIGNED_H */
include/asm-sparc64/unaligned.h +7 -3
@@ -1,6 +1,10 @@ -#ifndef _ASM_SPARC64_UNALIGNED_H_ -#define _ASM_SPARC64_UNALIGNED_H_ +#ifndef _ASM_SPARC64_UNALIGNED_H +#define _ASM_SPARC64_UNALIGNED_H -#include <asm-generic/unaligned.h> +#include <linux/unaligned/be_struct.h> +#include <linux/unaligned/le_byteshift.h> +#include <linux/unaligned/generic.h> +#define get_unaligned __get_unaligned_be +#define put_unaligned __put_unaligned_be#endif /* _ASM_SPARC64_UNALIGNED_H */
include/asm-um/unaligned.h +3 -3
@@ -1,6 +1,6 @@ -#ifndef __UM_UNALIGNED_H -#define __UM_UNALIGNED_H +#ifndef _ASM_UM_UNALIGNED_H +#define _ASM_UM_UNALIGNED_H#include "asm/arch/unaligned.h" -#endif +#endif /* _ASM_UM_UNALIGNED_H */
include/asm-v850/unaligned.h +8 -116
137 lines not on this page · raw message
include/asm-x86/unaligned.h +4 -28
@@ -3,35 +3,11 @@/* * The x86 can do unaligned accesses itself. -* -* The strange macros are there to make sure these can't -* be misused in a way that makes them not work on other -* architectures where unaligned accesses aren't as simple. */ +#include <linux/unaligned/access_ok.h> +#include <linux/unaligned/generic.h> -/** -* get_unaligned - get value from possibly mis-aligned location -* @ptr: pointer to value -* -* This macro should be used for accessing values larger in size than -* single bytes at locations that are expected to be improperly aligned, -* e.g. retrieving a u16 value from a location not u16-aligned. -* -* Note that unaligned accesses can be very expensive on some architectures. -*/ -#define get_unaligned (ptr) (*(ptr)) - -/** -* put_unaligned - put value to a possibly mis-aligned location -* @val: value to place -* @ptr: pointer to location -* -* This macro should be used for placing values larger in size than -* single bytes at locations that are expected to be improperly aligned, -* e.g. writing a u16 value to a location not u16-aligned. -* -* Note that unaligned accesses can be very expensive on some architectures. -*/ -#define put_unaligned (val, ptr) ((void)( *(ptr) = (val) )) +#define get_unaligned __get_unaligned_le +#define put_unaligned __put_unaligned_le#endif /* _ASM_X86_UNALIGNED_H */
include/asm-xtensa/unaligned.h +18 -17
@@ -1,6 +1,4 @@/* -* include/asm-xtensa/unaligned.h -* * Xtensa doesn't handle unaligned accesses efficiently. * * This file is subject to the terms and conditions of the GNU General Public
@@ -9,20 +7,23 @@* * Copyright (C) 2001 - 2005 Tensilica Inc. */ +#ifndef _ASM_XTENSA_UNALIGNED_H +#define _ASM_XTENSA_UNALIGNED_H -#ifndef _XTENSA_UNALIGNED_H -#define _XTENSA_UNALIGNED_H - -#include <linux/string.h> - -/* Use memmove here, so gcc does not insert a __builtin_memcpy. */ - -#define get_unaligned (ptr) \ - ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) - -#define put_unaligned (val, ptr) \ - ({ __typeof__(*(ptr)) __tmp = (val); \ - memmove((ptr), &__tmp, sizeof(*(ptr))); \ - (void)0; }) +#ifdef __XTENSA_EL__ +# include <linux/unaligned/le_memmove.h> +# include <linux/unaligned/be_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_le +# define put_unaligned __put_unaligned_le +#elif defined(__XTENSA_EB__) +# include <linux/unaligned/be_memmove.h> +# include <linux/unaligned/le_byteshift.h> +# include <linux/unaligned/generic.h> +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#else +# error processor byte order undefined! +#endif -#endif /* _XTENSA_UNALIGNED_H */ +#endif /* _ASM_XTENSA_UNALIGNED_H */
Signature · 1 line
1.5.5.144.g3e42
Quoted 2 lines · Harvey Harrison
arch/frv/kernel/traps.c | 7 +- arch/frv/mm/unaligned.c | 217 -------------------------------------
And arch/frv/mm/Makefile? It still refers to unaligned.c.
Review
Quoted 4 lines
(quoted diff) +2
-2-#ifndef _ASM_UNALIGNED_H -#define _ASM_UNALIGNED_H +#ifndef _ASM_FRV_UNALIGNED_H +#define _ASM_FRV_UNALIGNED_H
Please don't!
David
---
[PATCH] FRV: Don't refer to arch/frv/mm/unaligned.c once it has been deleted
From: David Howells <[email protected]>
arch/frv/mm/unaligned.c should not be mentioned in the local Makefile once the former has been deleted.
---
arch/frv/mm/Makefile | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/frv/mm/Makefile +1 -1
@@ -6,4 +6,4 @@ obj-y := init.o kmap.o obj-$(CONFIG_MMU) += \ pgalloc.o highmem.o fault.o extable.o cache-page.o tlb-flush.o tlb-miss.o \ - mmu-context.o dma-alloc.o unaligned.o elf-fdpic.o + mmu-context.o dma-alloc.o elf-fdpic.o
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 7 lines · David Howells
Quoted 2 lines · Harvey Harrison
arch/frv/kernel/traps.c | 7 +- arch/frv/mm/unaligned.c | 217 -------------------------------------And
arch/frv/mm/Makefile? It still refers tounaligned.c.
Missed that, thanks a lot.
Quoted 6 lines
Review
Quoted 4 lines
(quoted diff) +2
-2-#ifndef _ASM_UNALIGNED_H -#define _ASM_UNALIGNED_H +#ifndef _ASM_FRV_UNALIGNED_H +#define _ASM_FRV_UNALIGNED_HPlease don't!
Andrew, do you need an incremental patch for this, or can you take care of it on your end?
Cheers,
Harvey