aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/alignment.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/alignment.c')
-rw-r--r--arch/arm/mm/alignment.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index 924036473b16..b8cb1a2688a0 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -28,6 +28,7 @@
28#include <asm/opcodes.h> 28#include <asm/opcodes.h>
29 29
30#include "fault.h" 30#include "fault.h"
31#include "mm.h"
31 32
32/* 33/*
33 * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998 34 * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
@@ -81,6 +82,7 @@ static unsigned long ai_word;
81static unsigned long ai_dword; 82static unsigned long ai_dword;
82static unsigned long ai_multi; 83static unsigned long ai_multi;
83static int ai_usermode; 84static int ai_usermode;
85static unsigned long cr_no_alignment;
84 86
85core_param(alignment, ai_usermode, int, 0600); 87core_param(alignment, ai_usermode, int, 0600);
86 88
@@ -91,7 +93,7 @@ core_param(alignment, ai_usermode, int, 0600);
91/* Return true if and only if the ARMv6 unaligned access model is in use. */ 93/* Return true if and only if the ARMv6 unaligned access model is in use. */
92static bool cpu_is_v6_unaligned(void) 94static bool cpu_is_v6_unaligned(void)
93{ 95{
94 return cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U); 96 return cpu_architecture() >= CPU_ARCH_ARMv6 && get_cr() & CR_U;
95} 97}
96 98
97static int safe_usermode(int new_usermode, bool warn) 99static int safe_usermode(int new_usermode, bool warn)
@@ -949,6 +951,13 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
949 return 0; 951 return 0;
950} 952}
951 953
954static int __init noalign_setup(char *__unused)
955{
956 set_cr(__clear_cr(CR_A));
957 return 1;
958}
959__setup("noalign", noalign_setup);
960
952/* 961/*
953 * This needs to be done after sysctl_init, otherwise sys/ will be 962 * This needs to be done after sysctl_init, otherwise sys/ will be
954 * overwritten. Actually, this shouldn't be in sys/ at all since 963 * overwritten. Actually, this shouldn't be in sys/ at all since
@@ -966,14 +975,12 @@ static int __init alignment_init(void)
966 return -ENOMEM; 975 return -ENOMEM;
967#endif 976#endif
968 977
969#ifdef CONFIG_CPU_CP15
970 if (cpu_is_v6_unaligned()) { 978 if (cpu_is_v6_unaligned()) {
971 cr_alignment &= ~CR_A; 979 set_cr(__clear_cr(CR_A));
972 cr_no_alignment &= ~CR_A;
973 set_cr(cr_alignment);
974 ai_usermode = safe_usermode(ai_usermode, false); 980 ai_usermode = safe_usermode(ai_usermode, false);
975 } 981 }
976#endif 982
983 cr_no_alignment = get_cr() & ~CR_A;
977 984
978 hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN, 985 hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
979 "alignment exception"); 986 "alignment exception");