aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/include/asm/processor.h12
-rw-r--r--arch/sh/include/asm/processor_32.h6
-rw-r--r--arch/sh/include/asm/processor_64.h5
-rw-r--r--arch/sh/mm/alignment.c30
4 files changed, 51 insertions, 2 deletions
diff --git a/arch/sh/include/asm/processor.h b/arch/sh/include/asm/processor.h
index 87a8d1ef64e4..9605e062840f 100644
--- a/arch/sh/include/asm/processor.h
+++ b/arch/sh/include/asm/processor.h
@@ -107,6 +107,13 @@ extern unsigned int xstate_size;
107extern void free_thread_xstate(struct task_struct *); 107extern void free_thread_xstate(struct task_struct *);
108extern struct kmem_cache *task_xstate_cachep; 108extern struct kmem_cache *task_xstate_cachep;
109 109
110/* arch/sh/mm/alignment.c */
111extern int get_unalign_ctl(struct task_struct *, unsigned long addr);
112extern int set_unalign_ctl(struct task_struct *, unsigned int val);
113
114#define GET_UNALIGN_CTL(tsk, addr) get_unalign_ctl((tsk), (addr))
115#define SET_UNALIGN_CTL(tsk, val) set_unalign_ctl((tsk), (val))
116
110/* arch/sh/mm/init.c */ 117/* arch/sh/mm/init.c */
111extern unsigned int mem_init_done; 118extern unsigned int mem_init_done;
112 119
@@ -114,6 +121,11 @@ extern unsigned int mem_init_done;
114const char *get_cpu_subtype(struct sh_cpuinfo *c); 121const char *get_cpu_subtype(struct sh_cpuinfo *c);
115extern const struct seq_operations cpuinfo_op; 122extern const struct seq_operations cpuinfo_op;
116 123
124/* thread_struct flags */
125#define SH_THREAD_UAC_NOPRINT (1 << 0)
126#define SH_THREAD_UAC_SIGBUS (1 << 1)
127#define SH_THREAD_UAC_MASK (SH_THREAD_UAC_NOPRINT | SH_THREAD_UAC_SIGBUS)
128
117/* processor boot mode configuration */ 129/* processor boot mode configuration */
118#define MODE_PIN0 (1 << 0) 130#define MODE_PIN0 (1 << 0)
119#define MODE_PIN1 (1 << 1) 131#define MODE_PIN1 (1 << 1)
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 488f0a906a41..572b4eb09493 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -101,8 +101,11 @@ struct thread_struct {
101 unsigned long sp; 101 unsigned long sp;
102 unsigned long pc; 102 unsigned long pc;
103 103
104 /* Various thread flags, see SH_THREAD_xxx */
105 unsigned long flags;
106
104 /* Save middle states of ptrace breakpoints */ 107 /* Save middle states of ptrace breakpoints */
105 struct perf_event *ptrace_bps[HBP_NUM]; 108 struct perf_event *ptrace_bps[HBP_NUM];
106 109
107#ifdef CONFIG_SH_DSP 110#ifdef CONFIG_SH_DSP
108 /* Dsp status information */ 111 /* Dsp status information */
@@ -115,6 +118,7 @@ struct thread_struct {
115 118
116#define INIT_THREAD { \ 119#define INIT_THREAD { \
117 .sp = sizeof(init_stack) + (long) &init_stack, \ 120 .sp = sizeof(init_stack) + (long) &init_stack, \
121 .flags = 0, \
118} 122}
119 123
120/* Forward declaration, a strange C thing */ 124/* Forward declaration, a strange C thing */
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 7b1560f03d14..621bc4618c6b 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -108,6 +108,10 @@ union thread_xstate {
108struct thread_struct { 108struct thread_struct {
109 unsigned long sp; 109 unsigned long sp;
110 unsigned long pc; 110 unsigned long pc;
111
112 /* Various thread flags, see SH_THREAD_xxx */
113 unsigned long flags;
114
111 /* This stores the address of the pt_regs built during a context 115 /* This stores the address of the pt_regs built during a context
112 switch, or of the register save area built for a kernel mode 116 switch, or of the register save area built for a kernel mode
113 exception. It is used for backtracing the stack of a sleeping task 117 exception. It is used for backtracing the stack of a sleeping task
@@ -138,6 +142,7 @@ struct thread_struct {
138 .trap_no = 0, \ 142 .trap_no = 0, \
139 .error_code = 0, \ 143 .error_code = 0, \
140 .address = 0, \ 144 .address = 0, \
145 .flags = 0, \
141} 146}
142 147
143/* 148/*
diff --git a/arch/sh/mm/alignment.c b/arch/sh/mm/alignment.c
index 00fb9e3f057c..b2595b8548ee 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,