summaryrefslogtreecommitdiff
path: root/arch/arm/mm/alignment.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2010-10-15 13:03:09 -0700
committerJoel Becker <joel.becker@oracle.com>2010-10-15 13:03:09 -0700
commitfc3718918f13ad72827d62d36ea0f5fb55090644 (patch)
tree4f9551256e02d08be37bab137f3d94182a67504c /arch/arm/mm/alignment.c
parent7bdb0d18bfd381cc5491eb95973ec5604b356c7e (diff)
parentd4396eafe402b710a8535137b3bf2abe6c059a15 (diff)
Merge branch 'globalheartbeat-2' of git://oss.oracle.com/git/smushran/linux-2.6 into ocfs2-merge-window
Conflicts: fs/ocfs2/ocfs2.h
Diffstat (limited to 'arch/arm/mm/alignment.c')
-rw-r--r--arch/arm/mm/alignment.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index d073b64ae87e..724ba3bce72c 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -885,8 +885,23 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
if (ai_usermode & UM_SIGNAL)
force_sig(SIGBUS, current);
- else
- set_cr(cr_no_alignment);
+ else {
+ /*
+ * We're about to disable the alignment trap and return to
+ * user space. But if an interrupt occurs before actually
+ * reaching user space, then the IRQ vector entry code will
+ * notice that we were still in kernel space and therefore
+ * the alignment trap won't be re-enabled in that case as it
+ * is presumed to be always on from kernel space.
+ * Let's prevent that race by disabling interrupts here (they
+ * are disabled on the way back to user space anyway in
+ * entry-common.S) and disable the alignment trap only if
+ * there is no work pending for this thread.
+ */
+ raw_local_irq_disable();
+ if (!(current_thread_info()->flags & _TIF_WORK_MASK))
+ set_cr(cr_no_alignment);
+ }
return 0;
}