aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/mm
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2010-02-22 22:56:30 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-02-22 22:56:30 -0500
commit94ea5e449ae834af058ef005d16a8ad44fcf13d6 (patch)
tree4152e5cc7cd5535452b2cd074b6ba041abc7c301 /arch/sh/mm
parent7c1b2c6890a1a033dde4f6991c0a1fcd69cf58ce (diff)
sh: wire up SET/GET_UNALIGN_CTL.
This hooks up the SET/GET_UNALIGN_CTL knobs cribbing the bulk of it from the PPC and ia64 implementations. The thread flags happen to be the logical inverse of what the global fault mode is set to, so this works out pretty cleanly. By default the global fault mode is used, with tasks now being able to override their own settings via prctl(). Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/mm')
-rw-r--r--arch/sh/mm/alignment.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c
index 00fb9e3f057..b2595b8548e 100644
--- a/arch/sh/mm/alignment.c
+++ b/arch/sh/mm/alignment.c
@@ -14,6 +14,7 @@
14#include <linux/proc_fs.h> 14#include <linux/proc_fs.h>
15#include <linux/uaccess.h> 15#include <linux/uaccess.h>
16#include <asm/alignment.h> 16#include <asm/alignment.h>
17#include <asm/processor.h>
17 18
18static unsigned long se_user; 19static unsigned long se_user;
19static unsigned long se_sys; 20static unsigned long se_sys;
@@ -59,9 +60,36 @@ void inc_unaligned_kernel_access(void)
59 se_sys++; 60 se_sys++;
60} 61}
61 62
63/*
64 * This defaults to the global policy which can be set from the command
65 * line, while processes can overload their preferences via prctl().
66 */
62unsigned int unaligned_user_action(void) 67unsigned int unaligned_user_action(void)
63{ 68{
64 return se_usermode; 69 unsigned int action = se_usermode;
70
71 if (current->thread.flags & SH_THREAD_UAC_SIGBUS) {
72 action &= ~UM_FIXUP;
73 action |= UM_SIGNAL;
74 }
75
76 if (current->thread.flags & SH_THREAD_UAC_NOPRINT)
77 action &= ~UM_WARN;
78
79 return action;
80}
81
82int get_unalign_ctl(struct task_struct *tsk, unsigned long addr)
83{
84 return put_user(tsk->thread.flags & SH_THREAD_UAC_MASK,
85 (unsigned int __user *)addr);
86}
87
88int set_unalign_ctl(struct task_struct *tsk, unsigned int val)
89{
90 tsk->thread.flags = (tsk->thread.flags & ~SH_THREAD_UAC_MASK) |
91 (val & SH_THREAD_UAC_MASK);
92 return 0;
65} 93}
66 94
67void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn, 95void unaligned_fixups_notify(struct task_struct *tsk, insn_size_t insn,