Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 262729
b: refs/heads/master
c: 088c01f
h: refs/heads/master
i:
  262727: fcde40a
v: v3
  • Loading branch information
Dave Martin authored and Russell King committed Aug 9, 2011
1 parent 164eae9 commit 8b3d88a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: bf912d99e94cd1f43a7decce2e9b79a3ca7f2418
refs/heads/master: 088c01f1e39dbe93a13e0b00f4532ed8b79d35f4
42 changes: 30 additions & 12 deletions trunk/arch/arm/mm/alignment.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,33 @@ static const char *usermode_action[] = {
"signal+warn"
};

/* Return true if and only if the ARMv6 unaligned access model is in use. */
static bool cpu_is_v6_unaligned(void)
{
return cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U);
}

static int safe_usermode(int new_usermode, bool warn)
{
/*
* 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_is_v6_unaligned() && !(new_usermode & (UM_FIXUP | UM_SIGNAL))) {
new_usermode |= UM_FIXUP;

if (warn)
printk(KERN_WARNING "alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n");
}

return new_usermode;
}

static int alignment_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "User:\t\t%lu\n", ai_user);
Expand Down Expand Up @@ -125,7 +152,7 @@ static ssize_t alignment_proc_write(struct file *file, const char __user *buffer
if (get_user(mode, buffer))
return -EFAULT;
if (mode >= '0' && mode <= '5')
ai_usermode = mode - '0';
ai_usermode = safe_usermode(mode - '0', true);
}
return count;
}
Expand Down Expand Up @@ -926,20 +953,11 @@ static int __init alignment_init(void)
return -ENOMEM;
#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)) {
if (cpu_is_v6_unaligned()) {
cr_alignment &= ~CR_A;
cr_no_alignment &= ~CR_A;
set_cr(cr_alignment);
ai_usermode = UM_FIXUP;
ai_usermode = safe_usermode(ai_usermode, false);
}

hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN,
Expand Down

0 comments on commit 8b3d88a

Please sign in to comment.