aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r--arch/sh/kernel/cpu/sh4/sq.c2
-rw-r--r--arch/sh/kernel/cpu/sh5/entry.S19
-rw-r--r--arch/sh/kernel/entry-common.S16
-rw-r--r--arch/sh/kernel/machine_kexec.c8
-rw-r--r--arch/sh/kernel/module.c7
-rw-r--r--arch/sh/kernel/ptrace_32.c157
-rw-r--r--arch/sh/kernel/ptrace_64.c144
-rw-r--r--arch/sh/kernel/setup.c20
-rw-r--r--arch/sh/kernel/signal_32.c22
-rw-r--r--arch/sh/kernel/signal_64.c166
10 files changed, 263 insertions, 298 deletions
diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c
index dcdf959a3d44..8a8a993f55ea 100644
--- a/arch/sh/kernel/cpu/sh4/sq.c
+++ b/arch/sh/kernel/cpu/sh4/sq.c
@@ -199,7 +199,7 @@ EXPORT_SYMBOL(sq_remap);
199 199
200/** 200/**
201 * sq_unmap - Unmap a Store Queue allocation 201 * sq_unmap - Unmap a Store Queue allocation
202 * @map: Pre-allocated Store Queue mapping. 202 * @vaddr: Pre-allocated Store Queue mapping.
203 * 203 *
204 * Unmaps the store queue allocation @map that was previously created by 204 * Unmaps the store queue allocation @map that was previously created by
205 * sq_remap(). Also frees up the pte that was previously inserted into 205 * sq_remap(). Also frees up the pte that was previously inserted into
diff --git a/arch/sh/kernel/cpu/sh5/entry.S b/arch/sh/kernel/cpu/sh5/entry.S
index ca08e7f26a3a..04c7da968146 100644
--- a/arch/sh/kernel/cpu/sh5/entry.S
+++ b/arch/sh/kernel/cpu/sh5/entry.S
@@ -987,11 +987,11 @@ work_resched:
987work_notifysig: 987work_notifysig:
988 gettr tr1, LINK 988 gettr tr1, LINK
989 989
990 movi do_signal, r6 990 movi do_notify_resume, r6
991 ptabs r6, tr0 991 ptabs r6, tr0
992 or SP, ZERO, r2 992 or SP, ZERO, r2
993 or ZERO, ZERO, r3 993 or r7, ZERO, r3
994 blink tr0, LINK /* Call do_signal(regs, 0), return here */ 994 blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */
995 995
996restore_all: 996restore_all:
997 /* Do prefetches */ 997 /* Do prefetches */
@@ -1300,18 +1300,20 @@ syscall_allowed:
1300 1300
1301 getcon KCR0, r2 1301 getcon KCR0, r2
1302 ld.l r2, TI_FLAGS, r4 1302 ld.l r2, TI_FLAGS, r4
1303 movi (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT), r6 1303 movi _TIF_WORK_SYSCALL_MASK, r6
1304 and r6, r4, r6 1304 and r6, r4, r6
1305 beq/l r6, ZERO, tr0 1305 beq/l r6, ZERO, tr0
1306 1306
1307 /* Trace it by calling syscall_trace before and after */ 1307 /* Trace it by calling syscall_trace before and after */
1308 movi syscall_trace, r4 1308 movi do_syscall_trace_enter, r4
1309 or SP, ZERO, r2 1309 or SP, ZERO, r2
1310 or ZERO, ZERO, r3
1311 ptabs r4, tr0 1310 ptabs r4, tr0
1312 blink tr0, LINK 1311 blink tr0, LINK
1313 1312
1314 /* Reload syscall number as r5 is trashed by syscall_trace */ 1313 /* Save the retval */
1314 st.q SP, FRAME_R(2), r2
1315
1316 /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
1315 ld.q SP, FRAME_S(FSYSCALL_ID), r5 1317 ld.q SP, FRAME_S(FSYSCALL_ID), r5
1316 andi r5, 0x1ff, r5 1318 andi r5, 0x1ff, r5
1317 1319
@@ -1343,9 +1345,8 @@ syscall_ret_trace:
1343 /* We get back here only if under trace */ 1345 /* We get back here only if under trace */
1344 st.q SP, FRAME_R(9), r2 /* Save return value */ 1346 st.q SP, FRAME_R(9), r2 /* Save return value */
1345 1347
1346 movi syscall_trace, LINK 1348 movi do_syscall_trace_leave, LINK
1347 or SP, ZERO, r2 1349 or SP, ZERO, r2
1348 movi 1, r3
1349 ptabs LINK, tr0 1350 ptabs LINK, tr0
1350 blink tr0, LINK 1351 blink tr0, LINK
1351 1352
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 5e0dd1933847..0bc17def55a7 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -202,7 +202,7 @@ work_resched:
202syscall_exit_work: 202syscall_exit_work:
203 ! r0: current_thread_info->flags 203 ! r0: current_thread_info->flags
204 ! r8: current_thread_info 204 ! r8: current_thread_info
205 tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP | _TIF_SYSCALL_AUDIT, r0 205 tst #_TIF_WORK_SYSCALL_MASK, r0
206 bt/s work_pending 206 bt/s work_pending
207 tst #_TIF_NEED_RESCHED, r0 207 tst #_TIF_NEED_RESCHED, r0
208#ifdef CONFIG_TRACE_IRQFLAGS 208#ifdef CONFIG_TRACE_IRQFLAGS
@@ -211,10 +211,8 @@ syscall_exit_work:
211 nop 211 nop
212#endif 212#endif
213 sti 213 sti
214 ! XXX setup arguments...
215 mov r15, r4 214 mov r15, r4
216 mov #1, r5 215 mov.l 8f, r0 ! do_syscall_trace_leave
217 mov.l 4f, r0 ! do_syscall_trace
218 jsr @r0 216 jsr @r0
219 nop 217 nop
220 bra resume_userspace 218 bra resume_userspace
@@ -223,12 +221,11 @@ syscall_exit_work:
223 .align 2 221 .align 2
224syscall_trace_entry: 222syscall_trace_entry:
225 ! Yes it is traced. 223 ! Yes it is traced.
226 ! XXX setup arguments...
227 mov r15, r4 224 mov r15, r4
228 mov #0, r5 225 mov.l 7f, r11 ! Call do_syscall_trace_enter which notifies
229 mov.l 4f, r11 ! Call do_syscall_trace which notifies
230 jsr @r11 ! superior (will chomp R[0-7]) 226 jsr @r11 ! superior (will chomp R[0-7])
231 nop 227 nop
228 mov.l r0, @(OFF_R0,r15) ! Save return value
232 ! Reload R0-R4 from kernel stack, where the 229 ! Reload R0-R4 from kernel stack, where the
233 ! parent may have modified them using 230 ! parent may have modified them using
234 ! ptrace(POKEUSR). (Note that R0-R2 are 231 ! ptrace(POKEUSR). (Note that R0-R2 are
@@ -351,7 +348,7 @@ ENTRY(system_call)
351 ! 348 !
352 get_current_thread_info r8, r10 349 get_current_thread_info r8, r10
353 mov.l @(TI_FLAGS,r8), r8 350 mov.l @(TI_FLAGS,r8), r8
354 mov #(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT), r10 351 mov #_TIF_WORK_SYSCALL_MASK, r10
355 tst r10, r8 352 tst r10, r8
356 bf syscall_trace_entry 353 bf syscall_trace_entry
357 ! 354 !
@@ -389,8 +386,9 @@ syscall_exit:
389#endif 386#endif
3902: .long NR_syscalls 3872: .long NR_syscalls
3913: .long sys_call_table 3883: .long sys_call_table
3924: .long do_syscall_trace
393#ifdef CONFIG_TRACE_IRQFLAGS 389#ifdef CONFIG_TRACE_IRQFLAGS
3945: .long trace_hardirqs_on 3905: .long trace_hardirqs_on
3956: .long trace_hardirqs_off 3916: .long trace_hardirqs_off
396#endif 392#endif
3937: .long do_syscall_trace_enter
3948: .long do_syscall_trace_leave
diff --git a/arch/sh/kernel/machine_kexec.c b/arch/sh/kernel/machine_kexec.c
index ec1eadce4aaa..4703dff174d5 100644
--- a/arch/sh/kernel/machine_kexec.c
+++ b/arch/sh/kernel/machine_kexec.c
@@ -13,6 +13,7 @@
13#include <linux/kexec.h> 13#include <linux/kexec.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16#include <linux/numa.h>
16#include <asm/pgtable.h> 17#include <asm/pgtable.h>
17#include <asm/pgalloc.h> 18#include <asm/pgalloc.h>
18#include <asm/mmu_context.h> 19#include <asm/mmu_context.h>
@@ -104,3 +105,10 @@ void machine_kexec(struct kimage *image)
104 (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); 105 (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg);
105} 106}
106 107
108void arch_crash_save_vmcoreinfo(void)
109{
110#ifdef CONFIG_NUMA
111 VMCOREINFO_SYMBOL(node_data);
112 VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
113#endif
114}
diff --git a/arch/sh/kernel/module.c b/arch/sh/kernel/module.c
index 5482e65375a9..c43081039dd5 100644
--- a/arch/sh/kernel/module.c
+++ b/arch/sh/kernel/module.c
@@ -27,6 +27,7 @@
27#include <linux/moduleloader.h> 27#include <linux/moduleloader.h>
28#include <linux/elf.h> 28#include <linux/elf.h>
29#include <linux/vmalloc.h> 29#include <linux/vmalloc.h>
30#include <linux/bug.h>
30#include <linux/fs.h> 31#include <linux/fs.h>
31#include <linux/string.h> 32#include <linux/string.h>
32#include <linux/kernel.h> 33#include <linux/kernel.h>
@@ -36,7 +37,8 @@ void *module_alloc(unsigned long size)
36{ 37{
37 if (size == 0) 38 if (size == 0)
38 return NULL; 39 return NULL;
39 return vmalloc(size); 40
41 return vmalloc_exec(size);
40} 42}
41 43
42 44
@@ -145,9 +147,10 @@ int module_finalize(const Elf_Ehdr *hdr,
145 const Elf_Shdr *sechdrs, 147 const Elf_Shdr *sechdrs,
146 struct module *me) 148 struct module *me)
147{ 149{
148 return 0; 150 return module_bug_finalize(hdr, sechdrs, me);
149} 151}
150 152
151void module_arch_cleanup(struct module *mod) 153void module_arch_cleanup(struct module *mod)
152{ 154{
155 module_bug_cleanup(mod);
153} 156}
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 2bc72def5cf8..035cb300d3dc 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -20,6 +20,8 @@
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/audit.h> 22#include <linux/audit.h>
23#include <linux/seccomp.h>
24#include <linux/tracehook.h>
23#include <asm/uaccess.h> 25#include <asm/uaccess.h>
24#include <asm/pgtable.h> 26#include <asm/pgtable.h>
25#include <asm/system.h> 27#include <asm/system.h>
@@ -57,7 +59,23 @@ static inline int put_stack_long(struct task_struct *task, int offset,
57 return 0; 59 return 0;
58} 60}
59 61
60static void ptrace_disable_singlestep(struct task_struct *child) 62void user_enable_single_step(struct task_struct *child)
63{
64 struct pt_regs *regs = task_pt_regs(child);
65 long pc;
66
67 pc = get_stack_long(child, (long)&regs->pc);
68
69 /* Next scheduling will set up UBC */
70 if (child->thread.ubc_pc == 0)
71 ubc_usercnt += 1;
72
73 child->thread.ubc_pc = pc;
74
75 set_tsk_thread_flag(child, TIF_SINGLESTEP);
76}
77
78void user_disable_single_step(struct task_struct *child)
61{ 79{
62 clear_tsk_thread_flag(child, TIF_SINGLESTEP); 80 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
63 81
@@ -81,7 +99,7 @@ static void ptrace_disable_singlestep(struct task_struct *child)
81 */ 99 */
82void ptrace_disable(struct task_struct *child) 100void ptrace_disable(struct task_struct *child)
83{ 101{
84 ptrace_disable_singlestep(child); 102 user_disable_single_step(child);
85} 103}
86 104
87long arch_ptrace(struct task_struct *child, long request, long addr, long data) 105long arch_ptrace(struct task_struct *child, long request, long addr, long data)
@@ -90,12 +108,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
90 int ret; 108 int ret;
91 109
92 switch (request) { 110 switch (request) {
93 /* when I and D space are separate, these will need to be fixed. */
94 case PTRACE_PEEKTEXT: /* read word at location addr. */
95 case PTRACE_PEEKDATA:
96 ret = generic_ptrace_peekdata(child, addr, data);
97 break;
98
99 /* read the word at location addr in the USER area. */ 111 /* read the word at location addr in the USER area. */
100 case PTRACE_PEEKUSR: { 112 case PTRACE_PEEKUSR: {
101 unsigned long tmp; 113 unsigned long tmp;
@@ -125,12 +137,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
125 break; 137 break;
126 } 138 }
127 139
128 /* when I and D space are separate, this will have to be fixed. */
129 case PTRACE_POKETEXT: /* write the word at location addr. */
130 case PTRACE_POKEDATA:
131 ret = generic_ptrace_pokedata(child, addr, data);
132 break;
133
134 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 140 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
135 ret = -EIO; 141 ret = -EIO;
136 if ((addr & 3) || addr < 0 || 142 if ((addr & 3) || addr < 0 ||
@@ -151,67 +157,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
151 } 157 }
152 break; 158 break;
153 159
154 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
155 case PTRACE_CONT: { /* restart after signal. */
156 ret = -EIO;
157 if (!valid_signal(data))
158 break;
159 if (request == PTRACE_SYSCALL)
160 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
161 else
162 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
163
164 ptrace_disable_singlestep(child);
165
166 child->exit_code = data;
167 wake_up_process(child);
168 ret = 0;
169 break;
170 }
171
172/*
173 * make the child exit. Best I can do is send it a sigkill.
174 * perhaps it should be put in the status that it wants to
175 * exit.
176 */
177 case PTRACE_KILL: {
178 ret = 0;
179 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
180 break;
181 ptrace_disable_singlestep(child);
182 child->exit_code = SIGKILL;
183 wake_up_process(child);
184 break;
185 }
186
187 case PTRACE_SINGLESTEP: { /* set the trap flag. */
188 long pc;
189 struct pt_regs *regs = NULL;
190
191 ret = -EIO;
192 if (!valid_signal(data))
193 break;
194 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
195 if ((child->ptrace & PT_DTRACE) == 0) {
196 /* Spurious delayed TF traps may occur */
197 child->ptrace |= PT_DTRACE;
198 }
199
200 pc = get_stack_long(child, (long)&regs->pc);
201
202 /* Next scheduling will set up UBC */
203 if (child->thread.ubc_pc == 0)
204 ubc_usercnt += 1;
205 child->thread.ubc_pc = pc;
206
207 set_tsk_thread_flag(child, TIF_SINGLESTEP);
208 child->exit_code = data;
209 /* give it a chance to run. */
210 wake_up_process(child);
211 ret = 0;
212 break;
213 }
214
215#ifdef CONFIG_SH_DSP 160#ifdef CONFIG_SH_DSP
216 case PTRACE_GETDSPREGS: { 161 case PTRACE_GETDSPREGS: {
217 unsigned long dp; 162 unsigned long dp;
@@ -272,39 +217,49 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
272 return ret; 217 return ret;
273} 218}
274 219
275asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) 220static inline int audit_arch(void)
276{ 221{
277 struct task_struct *tsk = current; 222 int arch = EM_SH;
278 223
279 if (unlikely(current->audit_context) && entryexit) 224#ifdef CONFIG_CPU_LITTLE_ENDIAN
280 audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]), 225 arch |= __AUDIT_ARCH_LE;
281 regs->regs[0]); 226#endif
282 227
283 if (!test_thread_flag(TIF_SYSCALL_TRACE) && 228 return arch;
284 !test_thread_flag(TIF_SINGLESTEP)) 229}
285 goto out;
286 if (!(tsk->ptrace & PT_PTRACED))
287 goto out;
288 230
289 /* the 0x80 provides a way for the tracing parent to distinguish 231asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
290 between a syscall stop and SIGTRAP delivery */ 232{
291 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) && 233 long ret = 0;
292 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
293 234
294 /* 235 secure_computing(regs->regs[0]);
295 * this isn't the same as continuing with a signal, but it will do 236
296 * for normal use. strace only continues with a signal if the 237 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
297 * stopping signal is not SIGTRAP. -brl 238 tracehook_report_syscall_entry(regs))
298 */ 239 /*
299 if (tsk->exit_code) { 240 * Tracing decided this syscall should not happen.
300 send_sig(tsk->exit_code, tsk, 1); 241 * We'll return a bogus call number to get an ENOSYS
301 tsk->exit_code = 0; 242 * error, but leave the original number in regs->regs[0].
302 } 243 */
244 ret = -1L;
303 245
304out: 246 if (unlikely(current->audit_context))
305 if (unlikely(current->audit_context) && !entryexit) 247 audit_syscall_entry(audit_arch(), regs->regs[3],
306 audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[3],
307 regs->regs[4], regs->regs[5], 248 regs->regs[4], regs->regs[5],
308 regs->regs[6], regs->regs[7]); 249 regs->regs[6], regs->regs[7]);
309 250
251 return ret ?: regs->regs[0];
252}
253
254asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
255{
256 int step;
257
258 if (unlikely(current->audit_context))
259 audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
260 regs->regs[0]);
261
262 step = test_thread_flag(TIF_SINGLESTEP);
263 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
264 tracehook_report_syscall_exit(regs, step);
310} 265}
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index d453c47dc522..5922edd416db 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -27,6 +27,8 @@
27#include <linux/signal.h> 27#include <linux/signal.h>
28#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/seccomp.h>
31#include <linux/tracehook.h>
30#include <asm/io.h> 32#include <asm/io.h>
31#include <asm/uaccess.h> 33#include <asm/uaccess.h>
32#include <asm/pgtable.h> 34#include <asm/pgtable.h>
@@ -120,18 +122,23 @@ put_fpu_long(struct task_struct *task, unsigned long addr, unsigned long data)
120 return 0; 122 return 0;
121} 123}
122 124
125void user_enable_single_step(struct task_struct *child)
126{
127 struct pt_regs *regs = child->thread.uregs;
128
129 regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
130}
131
132void user_disable_single_step(struct task_struct *child)
133{
134 regs->sr &= ~SR_SSTEP;
135}
123 136
124long arch_ptrace(struct task_struct *child, long request, long addr, long data) 137long arch_ptrace(struct task_struct *child, long request, long addr, long data)
125{ 138{
126 int ret; 139 int ret;
127 140
128 switch (request) { 141 switch (request) {
129 /* when I and D space are separate, these will need to be fixed. */
130 case PTRACE_PEEKTEXT: /* read word at location addr. */
131 case PTRACE_PEEKDATA:
132 ret = generic_ptrace_peekdata(child, addr, data);
133 break;
134
135 /* read the word at location addr in the USER area. */ 142 /* read the word at location addr in the USER area. */
136 case PTRACE_PEEKUSR: { 143 case PTRACE_PEEKUSR: {
137 unsigned long tmp; 144 unsigned long tmp;
@@ -154,12 +161,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
154 break; 161 break;
155 } 162 }
156 163
157 /* when I and D space are separate, this will have to be fixed. */
158 case PTRACE_POKETEXT: /* write the word at location addr. */
159 case PTRACE_POKEDATA:
160 ret = generic_ptrace_pokedata(child, addr, data);
161 break;
162
163 case PTRACE_POKEUSR: 164 case PTRACE_POKEUSR:
164 /* write the word at location addr in the USER area. We must 165 /* write the word at location addr in the USER area. We must
165 disallow any changes to certain SR bits or u_fpvalid, since 166 disallow any changes to certain SR bits or u_fpvalid, since
@@ -191,58 +192,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
191 } 192 }
192 break; 193 break;
193 194
194 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
195 case PTRACE_CONT: { /* restart after signal. */
196 ret = -EIO;
197 if (!valid_signal(data))
198 break;
199 if (request == PTRACE_SYSCALL)
200 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
201 else
202 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
203 child->exit_code = data;
204 wake_up_process(child);
205 ret = 0;
206 break;
207 }
208
209/*
210 * make the child exit. Best I can do is send it a sigkill.
211 * perhaps it should be put in the status that it wants to
212 * exit.
213 */
214 case PTRACE_KILL: {
215 ret = 0;
216 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
217 break;
218 child->exit_code = SIGKILL;
219 wake_up_process(child);
220 break;
221 }
222
223 case PTRACE_SINGLESTEP: { /* set the trap flag. */
224 struct pt_regs *regs;
225
226 ret = -EIO;
227 if (!valid_signal(data))
228 break;
229 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
230 if ((child->ptrace & PT_DTRACE) == 0) {
231 /* Spurious delayed TF traps may occur */
232 child->ptrace |= PT_DTRACE;
233 }
234
235 regs = child->thread.uregs;
236
237 regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
238
239 child->exit_code = data;
240 /* give it a chance to run. */
241 wake_up_process(child);
242 ret = 0;
243 break;
244 }
245
246 default: 195 default:
247 ret = ptrace_request(child, request, addr, data); 196 ret = ptrace_request(child, request, addr, data);
248 break; 197 break;
@@ -273,38 +222,51 @@ asmlinkage int sh64_ptrace(long request, long pid, long addr, long data)
273 return sys_ptrace(request, pid, addr, data); 222 return sys_ptrace(request, pid, addr, data);
274} 223}
275 224
276asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit) 225static inline int audit_arch(void)
277{ 226{
278 struct task_struct *tsk = current; 227 int arch = EM_SH;
279 228
280 if (unlikely(current->audit_context) && entryexit) 229#ifdef CONFIG_64BIT
281 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), 230 arch |= __AUDIT_ARCH_64BIT;
282 regs->regs[9]); 231#endif
232#ifdef CONFIG_CPU_LITTLE_ENDIAN
233 arch |= __AUDIT_ARCH_LE;
234#endif
283 235
284 if (!test_thread_flag(TIF_SYSCALL_TRACE) && 236 return arch;
285 !test_thread_flag(TIF_SINGLESTEP)) 237}
286 goto out;
287 if (!(tsk->ptrace & PT_PTRACED))
288 goto out;
289
290 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) &&
291 !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0));
292
293 /*
294 * this isn't the same as continuing with a signal, but it will do
295 * for normal use. strace only continues with a signal if the
296 * stopping signal is not SIGTRAP. -brl
297 */
298 if (tsk->exit_code) {
299 send_sig(tsk->exit_code, tsk, 1);
300 tsk->exit_code = 0;
301 }
302 238
303out: 239asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
304 if (unlikely(current->audit_context) && !entryexit) 240{
305 audit_syscall_entry(AUDIT_ARCH_SH, regs->regs[1], 241 long long ret = 0;
242
243 secure_computing(regs->regs[9]);
244
245 if (test_thread_flag(TIF_SYSCALL_TRACE) &&
246 tracehook_report_syscall_entry(regs))
247 /*
248 * Tracing decided this syscall should not happen.
249 * We'll return a bogus call number to get an ENOSYS
250 * error, but leave the original number in regs->regs[0].
251 */
252 ret = -1LL;
253
254 if (unlikely(current->audit_context))
255 audit_syscall_entry(audit_arch(), regs->regs[1],
306 regs->regs[2], regs->regs[3], 256 regs->regs[2], regs->regs[3],
307 regs->regs[4], regs->regs[5]); 257 regs->regs[4], regs->regs[5]);
258
259 return ret ?: regs->regs[9];
260}
261
262asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
263{
264 if (unlikely(current->audit_context))
265 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
266 regs->regs[9]);
267
268 if (test_thread_flag(TIF_SYSCALL_TRACE))
269 tracehook_report_syscall_exit(regs, 0);
308} 270}
309 271
310/* Called with interrupts disabled */ 272/* Called with interrupts disabled */
@@ -338,5 +300,5 @@ asmlinkage void do_software_break_point(unsigned long long vec,
338 */ 300 */
339void ptrace_disable(struct task_struct *child) 301void ptrace_disable(struct task_struct *child)
340{ 302{
341 /* nothing to do.. */ 303 user_disable_single_step(child);
342} 304}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 6339d0c95715..a35207655e7b 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -25,6 +25,7 @@
25#include <linux/smp.h> 25#include <linux/smp.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/debugfs.h> 27#include <linux/debugfs.h>
28#include <linux/crash_dump.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/io.h> 30#include <asm/io.h>
30#include <asm/page.h> 31#include <asm/page.h>
@@ -286,6 +287,25 @@ static void __init setup_memory(void)
286extern void __init setup_memory(void); 287extern void __init setup_memory(void);
287#endif 288#endif
288 289
290/*
291 * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
292 * is_kdump_kernel() to determine if we are booting after a panic. Hence
293 * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
294 */
295#ifdef CONFIG_CRASH_DUMP
296/* elfcorehdr= specifies the location of elf core header
297 * stored by the crashed kernel.
298 */
299static int __init parse_elfcorehdr(char *arg)
300{
301 if (!arg)
302 return -EINVAL;
303 elfcorehdr_addr = memparse(arg, &arg);
304 return 0;
305}
306early_param("elfcorehdr", parse_elfcorehdr);
307#endif
308
289void __init setup_arch(char **cmdline_p) 309void __init setup_arch(char **cmdline_p)
290{ 310{
291 enable_mmu(); 311 enable_mmu();
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 4bbbde895a53..51689d29ad45 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -24,6 +24,7 @@
24#include <linux/binfmts.h> 24#include <linux/binfmts.h>
25#include <linux/freezer.h> 25#include <linux/freezer.h>
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/tracehook.h>
27#include <asm/system.h> 28#include <asm/system.h>
28#include <asm/ucontext.h> 29#include <asm/ucontext.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
@@ -507,14 +508,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info,
507 switch (regs->regs[0]) { 508 switch (regs->regs[0]) {
508 case -ERESTART_RESTARTBLOCK: 509 case -ERESTART_RESTARTBLOCK:
509 case -ERESTARTNOHAND: 510 case -ERESTARTNOHAND:
511 no_system_call_restart:
510 regs->regs[0] = -EINTR; 512 regs->regs[0] = -EINTR;
511 break; 513 break;
512 514
513 case -ERESTARTSYS: 515 case -ERESTARTSYS:
514 if (!(ka->sa.sa_flags & SA_RESTART)) { 516 if (!(ka->sa.sa_flags & SA_RESTART))
515 regs->regs[0] = -EINTR; 517 goto no_system_call_restart;
516 break;
517 }
518 /* fallthrough */ 518 /* fallthrough */
519 case -ERESTARTNOINTR: 519 case -ERESTARTNOINTR:
520 regs->regs[0] = save_r0; 520 regs->regs[0] = save_r0;
@@ -589,12 +589,15 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
589 * clear the TIF_RESTORE_SIGMASK flag */ 589 * clear the TIF_RESTORE_SIGMASK flag */
590 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 590 if (test_thread_flag(TIF_RESTORE_SIGMASK))
591 clear_thread_flag(TIF_RESTORE_SIGMASK); 591 clear_thread_flag(TIF_RESTORE_SIGMASK);
592
593 tracehook_signal_handler(signr, &info, &ka, regs,
594 test_thread_flag(TIF_SINGLESTEP));
592 } 595 }
593 596
594 return; 597 return;
595 } 598 }
596 599
597 no_signal: 600no_signal:
598 /* Did we come from a system call? */ 601 /* Did we come from a system call? */
599 if (regs->tra >= 0) { 602 if (regs->tra >= 0) {
600 /* Restart the system call - no handlers present */ 603 /* Restart the system call - no handlers present */
@@ -618,9 +621,14 @@ static void do_signal(struct pt_regs *regs, unsigned int save_r0)
618} 621}
619 622
620asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, 623asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
621 __u32 thread_info_flags) 624 unsigned long thread_info_flags)
622{ 625{
623 /* deal with pending signal delivery */ 626 /* deal with pending signal delivery */
624 if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) 627 if (thread_info_flags & _TIF_SIGPENDING)
625 do_signal(regs, save_r0); 628 do_signal(regs, save_r0);
629
630 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
631 clear_thread_flag(TIF_NOTIFY_RESUME);
632 tracehook_notify_resume(regs);
633 }
626} 634}
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index 552eb810cd85..1d62dfef77f1 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -22,6 +22,7 @@
22#include <linux/ptrace.h> 22#include <linux/ptrace.h>
23#include <linux/unistd.h> 23#include <linux/unistd.h>
24#include <linux/stddef.h> 24#include <linux/stddef.h>
25#include <linux/tracehook.h>
25#include <asm/ucontext.h> 26#include <asm/ucontext.h>
26#include <asm/uaccess.h> 27#include <asm/uaccess.h>
27#include <asm/pgtable.h> 28#include <asm/pgtable.h>
@@ -42,7 +43,84 @@
42 43
43#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 44#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 45
45asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset); 46/*
47 * Note that 'init' is a special process: it doesn't get signals it doesn't
48 * want to handle. Thus you cannot kill init even with a SIGKILL even by
49 * mistake.
50 *
51 * Note that we go through the signals twice: once to check the signals that
52 * the kernel can handle, and then we build all the user-level signal handling
53 * stack-frames in one go after that.
54 */
55static int do_signal(struct pt_regs *regs, sigset_t *oldset)
56{
57 siginfo_t info;
58 int signr;
59 struct k_sigaction ka;
60
61 /*
62 * We want the common case to go fast, which
63 * is why we may in certain cases get here from
64 * kernel mode. Just return without doing anything
65 * if so.
66 */
67 if (!user_mode(regs))
68 return 1;
69
70 if (try_to_freeze())
71 goto no_signal;
72
73 if (test_thread_flag(TIF_RESTORE_SIGMASK))
74 oldset = &current->saved_sigmask;
75 else if (!oldset)
76 oldset = &current->blocked;
77
78 signr = get_signal_to_deliver(&info, &ka, regs, 0);
79
80 if (signr > 0) {
81 /* Whee! Actually deliver the signal. */
82 handle_signal(signr, &info, &ka, oldset, regs);
83
84 /*
85 * If a signal was successfully delivered, the saved sigmask
86 * is in its frame, and we can clear the TIF_RESTORE_SIGMASK
87 * flag.
88 */
89 if (test_thread_flag(TIF_RESTORE_SIGMASK))
90 clear_thread_flag(TIF_RESTORE_SIGMASK);
91
92 tracehook_signal_handler(signr, &info, &ka, regs, 0);
93 return 1;
94 }
95
96no_signal:
97 /* Did we come from a system call? */
98 if (regs->syscall_nr >= 0) {
99 /* Restart the system call - no handlers present */
100 switch (regs->regs[REG_RET]) {
101 case -ERESTARTNOHAND:
102 case -ERESTARTSYS:
103 case -ERESTARTNOINTR:
104 /* Decode Syscall # */
105 regs->regs[REG_RET] = regs->syscall_nr;
106 regs->pc -= 4;
107 break;
108
109 case -ERESTART_RESTARTBLOCK:
110 regs->regs[REG_RET] = __NR_restart_syscall;
111 regs->pc -= 4;
112 break;
113 }
114 }
115
116 /* No signal to deliver -- put the saved sigmask back */
117 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
118 clear_thread_flag(TIF_RESTORE_SIGMASK);
119 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
120 }
121
122 return 0;
123}
46 124
47/* 125/*
48 * Atomically swap in the new signal mask, and wait for a signal. 126 * Atomically swap in the new signal mask, and wait for a signal.
@@ -643,14 +721,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
643 switch (regs->regs[REG_RET]) { 721 switch (regs->regs[REG_RET]) {
644 case -ERESTART_RESTARTBLOCK: 722 case -ERESTART_RESTARTBLOCK:
645 case -ERESTARTNOHAND: 723 case -ERESTARTNOHAND:
724 no_system_call_restart:
646 regs->regs[REG_RET] = -EINTR; 725 regs->regs[REG_RET] = -EINTR;
647 break; 726 break;
648 727
649 case -ERESTARTSYS: 728 case -ERESTARTSYS:
650 if (!(ka->sa.sa_flags & SA_RESTART)) { 729 if (!(ka->sa.sa_flags & SA_RESTART))
651 regs->regs[REG_RET] = -EINTR; 730 goto no_system_call_restart;
652 break;
653 }
654 /* fallthrough */ 731 /* fallthrough */
655 case -ERESTARTNOINTR: 732 case -ERESTARTNOINTR:
656 /* Decode syscall # */ 733 /* Decode syscall # */
@@ -673,80 +750,13 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
673 spin_unlock_irq(&current->sighand->siglock); 750 spin_unlock_irq(&current->sighand->siglock);
674} 751}
675 752
676/* 753asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
677 * Note that 'init' is a special process: it doesn't get signals it doesn't
678 * want to handle. Thus you cannot kill init even with a SIGKILL even by
679 * mistake.
680 *
681 * Note that we go through the signals twice: once to check the signals that
682 * the kernel can handle, and then we build all the user-level signal handling
683 * stack-frames in one go after that.
684 */
685int do_signal(struct pt_regs *regs, sigset_t *oldset)
686{ 754{
687 siginfo_t info; 755 if (thread_info_flags & _TIF_SIGPENDING)
688 int signr; 756 do_signal(regs, 0);
689 struct k_sigaction ka;
690
691 /*
692 * We want the common case to go fast, which
693 * is why we may in certain cases get here from
694 * kernel mode. Just return without doing anything
695 * if so.
696 */
697 if (!user_mode(regs))
698 return 1;
699
700 if (try_to_freeze())
701 goto no_signal;
702
703 if (test_thread_flag(TIF_RESTORE_SIGMASK))
704 oldset = &current->saved_sigmask;
705 else if (!oldset)
706 oldset = &current->blocked;
707
708 signr = get_signal_to_deliver(&info, &ka, regs, 0);
709
710 if (signr > 0) {
711 /* Whee! Actually deliver the signal. */
712 handle_signal(signr, &info, &ka, oldset, regs);
713 757
714 /* 758 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
715 * If a signal was successfully delivered, the saved sigmask 759 clear_thread_flag(TIF_NOTIFY_RESUME);
716 * is in its frame, and we can clear the TIF_RESTORE_SIGMASK 760 tracehook_notify_resume(regs);
717 * flag.
718 */
719 if (test_thread_flag(TIF_RESTORE_SIGMASK))
720 clear_thread_flag(TIF_RESTORE_SIGMASK);
721
722 return 1;
723 } 761 }
724
725no_signal:
726 /* Did we come from a system call? */
727 if (regs->syscall_nr >= 0) {
728 /* Restart the system call - no handlers present */
729 switch (regs->regs[REG_RET]) {
730 case -ERESTARTNOHAND:
731 case -ERESTARTSYS:
732 case -ERESTARTNOINTR:
733 /* Decode Syscall # */
734 regs->regs[REG_RET] = regs->syscall_nr;
735 regs->pc -= 4;
736 break;
737
738 case -ERESTART_RESTARTBLOCK:
739 regs->regs[REG_RET] = __NR_restart_syscall;
740 regs->pc -= 4;
741 break;
742 }
743 }
744
745 /* No signal to deliver -- put the saved sigmask back */
746 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
747 clear_thread_flag(TIF_RESTORE_SIGMASK);
748 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
749 }
750
751 return 0;
752} 762}