Loading arch/arm/mm/Kconfig +15 −0 Original line number Diff line number Diff line Loading @@ -675,6 +675,21 @@ config SWP_EMULATE If unsure, say Y. config FORCE_INSTRUCTION_ALIGNMENT bool "Force instructions address alignment" depends on CPU_V7 && ALIGNMENT_TRAP help Branching to an address in ARM state which is not word aligned, where this is defined to be UNPREDICTABLE, can cause one of the following two behaviours: 1. The unaligned location is forced to be aligned. 2. Using the unaligned address generates a Prefetch Abort on the first instruction using the unaligned PC value. To be consistant for the user space binaries, the unaligned location is forced aligned with this config. If unsure, say Y. config CPU_BIG_ENDIAN bool "Build big-endian kernel" depends on ARCH_SUPPORTS_BIG_ENDIAN Loading arch/arm/mm/alignment.c +35 −0 Original line number Diff line number Diff line Loading @@ -742,6 +742,36 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, return NULL; } #ifdef CONFIG_FORCE_INSTRUCTION_ALIGNMENT static int do_ialignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { /* * Branching to an address in ARM state which is not word aligned, * where this is defined to be UNPREDICTABLE, * can cause one of the following two behaviours: * 1. The unaligned location is forced to be aligned. * 2. Using the unaligned address generates a Prefetch Abort on * the first instruction using the unaligned PC value. */ int isize = 4; if (user_mode(regs) && !thumb_mode(regs)) { ai_sys += 1; /* * Force align the instruction in software to be following * a single behaviour for the unpredicatable cases. */ instruction_pointer(regs) &= ~(isize + (-1UL)); return 0; } ai_skipped += 1; return 1; } #endif static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { Loading Loading @@ -973,6 +1003,11 @@ static int __init alignment_init(void) hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN, "alignment exception"); #ifdef CONFIG_FORCE_INSTRUCTION_ALIGNMENT hook_ifault_code(FAULT_CODE_ALIGNMENT, do_ialignment, SIGBUS, BUS_ADRALN, "alignment exception"); #endif /* * ARMv6K and ARMv7 use fault status 3 (0b00011) as Access Flag section * fault, not as alignment error. Loading Loading
arch/arm/mm/Kconfig +15 −0 Original line number Diff line number Diff line Loading @@ -675,6 +675,21 @@ config SWP_EMULATE If unsure, say Y. config FORCE_INSTRUCTION_ALIGNMENT bool "Force instructions address alignment" depends on CPU_V7 && ALIGNMENT_TRAP help Branching to an address in ARM state which is not word aligned, where this is defined to be UNPREDICTABLE, can cause one of the following two behaviours: 1. The unaligned location is forced to be aligned. 2. Using the unaligned address generates a Prefetch Abort on the first instruction using the unaligned PC value. To be consistant for the user space binaries, the unaligned location is forced aligned with this config. If unsure, say Y. config CPU_BIG_ENDIAN bool "Build big-endian kernel" depends on ARCH_SUPPORTS_BIG_ENDIAN Loading
arch/arm/mm/alignment.c +35 −0 Original line number Diff line number Diff line Loading @@ -742,6 +742,36 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs, return NULL; } #ifdef CONFIG_FORCE_INSTRUCTION_ALIGNMENT static int do_ialignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { /* * Branching to an address in ARM state which is not word aligned, * where this is defined to be UNPREDICTABLE, * can cause one of the following two behaviours: * 1. The unaligned location is forced to be aligned. * 2. Using the unaligned address generates a Prefetch Abort on * the first instruction using the unaligned PC value. */ int isize = 4; if (user_mode(regs) && !thumb_mode(regs)) { ai_sys += 1; /* * Force align the instruction in software to be following * a single behaviour for the unpredicatable cases. */ instruction_pointer(regs) &= ~(isize + (-1UL)); return 0; } ai_skipped += 1; return 1; } #endif static int do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { Loading Loading @@ -973,6 +1003,11 @@ static int __init alignment_init(void) hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN, "alignment exception"); #ifdef CONFIG_FORCE_INSTRUCTION_ALIGNMENT hook_ifault_code(FAULT_CODE_ALIGNMENT, do_ialignment, SIGBUS, BUS_ADRALN, "alignment exception"); #endif /* * ARMv6K and ARMv7 use fault status 3 (0b00011) as Access Flag section * fault, not as alignment error. Loading