diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-12-12 12:00:02 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-12 12:00:14 +0100 |
commit | 92bf73e90a35d40ebc1446488218f03833b36f86 (patch) | |
tree | 8aaae58fcb7f3e06e63a5214f910acf47f4cc9d6 /arch/arm/mm/alignment.c | |
parent | 447557ac7ce120306b4a31d6003faef39cb1bf14 (diff) | |
parent | 915b0d0104b72fd36af088ba4b11b5690bc96a6c (diff) | |
download | op-kernel-dev-92bf73e90a35d40ebc1446488218f03833b36f86.zip op-kernel-dev-92bf73e90a35d40ebc1446488218f03833b36f86.tar.gz |
Merge branch 'x86/irq' into perfcounters/core
( with manual semantic merge of arch/x86/kernel/cpu/perf_counter.c )
Diffstat (limited to 'arch/arm/mm/alignment.c')
-rw-r--r-- | arch/arm/mm/alignment.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 133e65d..2d5884c 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -70,6 +70,10 @@ static unsigned long ai_dword; static unsigned long ai_multi; static int ai_usermode; +#define UM_WARN (1 << 0) +#define UM_FIXUP (1 << 1) +#define UM_SIGNAL (1 << 2) + #ifdef CONFIG_PROC_FS static const char *usermode_action[] = { "ignored", @@ -754,7 +758,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) user: ai_user += 1; - if (ai_usermode & 1) + if (ai_usermode & UM_WARN) printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx " "Address=0x%08lx FSR 0x%03x\n", current->comm, task_pid_nr(current), instrptr, @@ -762,10 +766,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) thumb_mode(regs) ? tinstr : instr, addr, fsr); - if (ai_usermode & 2) + if (ai_usermode & UM_FIXUP) goto fixup; - if (ai_usermode & 4) + if (ai_usermode & UM_SIGNAL) force_sig(SIGBUS, current); else set_cr(cr_no_alignment); @@ -796,6 +800,22 @@ static int __init alignment_init(void) res->write_proc = proc_alignment_write; #endif + /* + * ARMv6 and later CPUs can perform unaligned accesses for + * most single load and store instructions up to word size. + * LDM, STM, LDRD and STRD still need to be handled. + * + * Ignoring the alignment fault is not an option on these + * CPUs since we spin re-faulting the instruction without + * making any progress. + */ + if (cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U)) { + cr_alignment &= ~CR_A; + cr_no_alignment &= ~CR_A; + set_cr(cr_alignment); + ai_usermode = UM_FIXUP; + } + hook_fault_code(1, do_alignment, SIGILL, "alignment exception"); hook_fault_code(3, do_alignment, SIGILL, "alignment exception"); |