diff options
Diffstat (limited to 'arch/frv/kernel')
-rw-r--r-- | arch/frv/kernel/entry.S | 13 | ||||
-rw-r--r-- | arch/frv/kernel/ptrace.c | 755 | ||||
-rw-r--r-- | arch/frv/kernel/signal.c | 10 | ||||
-rw-r--r-- | arch/frv/kernel/uaccess.c | 6 |
4 files changed, 238 insertions, 546 deletions
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 1da523b3298e..356e0e327a89 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -886,7 +886,6 @@ system_call: | |||
886 | bnc icc0,#0,__syscall_badsys | 886 | bnc icc0,#0,__syscall_badsys |
887 | 887 | ||
888 | ldi @(gr15,#TI_FLAGS),gr4 | 888 | ldi @(gr15,#TI_FLAGS),gr4 |
889 | ori gr4,#_TIF_SYSCALL_TRACE,gr4 | ||
890 | andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0 | 889 | andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0 |
891 | bne icc0,#0,__syscall_trace_entry | 890 | bne icc0,#0,__syscall_trace_entry |
892 | 891 | ||
@@ -1150,11 +1149,10 @@ __entry_work_notifysig: | |||
1150 | # perform syscall entry tracing | 1149 | # perform syscall entry tracing |
1151 | __syscall_trace_entry: | 1150 | __syscall_trace_entry: |
1152 | LEDS 0x6320 | 1151 | LEDS 0x6320 |
1153 | setlos.p #0,gr8 | 1152 | call syscall_trace_entry |
1154 | call do_syscall_trace | ||
1155 | 1153 | ||
1156 | ldi @(gr28,#REG_SYSCALLNO),gr7 | 1154 | lddi.p @(gr28,#REG_GR(8)) ,gr8 |
1157 | lddi @(gr28,#REG_GR(8)) ,gr8 | 1155 | ori gr8,#0,gr7 ; syscall_trace_entry() returned new syscallno |
1158 | lddi @(gr28,#REG_GR(10)),gr10 | 1156 | lddi @(gr28,#REG_GR(10)),gr10 |
1159 | lddi.p @(gr28,#REG_GR(12)),gr12 | 1157 | lddi.p @(gr28,#REG_GR(12)),gr12 |
1160 | 1158 | ||
@@ -1169,11 +1167,10 @@ __syscall_exit_work: | |||
1169 | beq icc0,#1,__entry_work_pending | 1167 | beq icc0,#1,__entry_work_pending |
1170 | 1168 | ||
1171 | movsg psr,gr23 | 1169 | movsg psr,gr23 |
1172 | andi gr23,#~PSR_PIL,gr23 ; could let do_syscall_trace() call schedule() | 1170 | andi gr23,#~PSR_PIL,gr23 ; could let syscall_trace_exit() call schedule() |
1173 | movgs gr23,psr | 1171 | movgs gr23,psr |
1174 | 1172 | ||
1175 | setlos.p #1,gr8 | 1173 | call syscall_trace_exit |
1176 | call do_syscall_trace | ||
1177 | bra __entry_resume_userspace | 1174 | bra __entry_resume_userspace |
1178 | 1175 | ||
1179 | __syscall_badsys: | 1176 | __syscall_badsys: |
diff --git a/arch/frv/kernel/ptrace.c b/arch/frv/kernel/ptrace.c index 5e7d401d21e7..60eeed3694c0 100644 --- a/arch/frv/kernel/ptrace.c +++ b/arch/frv/kernel/ptrace.c | |||
@@ -19,6 +19,9 @@ | |||
19 | #include <linux/user.h> | 19 | #include <linux/user.h> |
20 | #include <linux/security.h> | 20 | #include <linux/security.h> |
21 | #include <linux/signal.h> | 21 | #include <linux/signal.h> |
22 | #include <linux/regset.h> | ||
23 | #include <linux/elf.h> | ||
24 | #include <linux/tracehook.h> | ||
22 | 25 | ||
23 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
24 | #include <asm/page.h> | 27 | #include <asm/page.h> |
@@ -33,6 +36,169 @@ | |||
33 | */ | 36 | */ |
34 | 37 | ||
35 | /* | 38 | /* |
39 | * retrieve the contents of FRV userspace general registers | ||
40 | */ | ||
41 | static int genregs_get(struct task_struct *target, | ||
42 | const struct user_regset *regset, | ||
43 | unsigned int pos, unsigned int count, | ||
44 | void *kbuf, void __user *ubuf) | ||
45 | { | ||
46 | const struct user_int_regs *iregs = &target->thread.user->i; | ||
47 | int ret; | ||
48 | |||
49 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
50 | iregs, 0, sizeof(*iregs)); | ||
51 | if (ret < 0) | ||
52 | return ret; | ||
53 | |||
54 | return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, | ||
55 | sizeof(*iregs), -1); | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * update the contents of the FRV userspace general registers | ||
60 | */ | ||
61 | static int genregs_set(struct task_struct *target, | ||
62 | const struct user_regset *regset, | ||
63 | unsigned int pos, unsigned int count, | ||
64 | const void *kbuf, const void __user *ubuf) | ||
65 | { | ||
66 | struct user_int_regs *iregs = &target->thread.user->i; | ||
67 | unsigned int offs_gr0, offs_gr1; | ||
68 | int ret; | ||
69 | |||
70 | /* not allowed to set PSR or __status */ | ||
71 | if (pos < offsetof(struct user_int_regs, psr) + sizeof(long) && | ||
72 | pos + count > offsetof(struct user_int_regs, psr)) | ||
73 | return -EIO; | ||
74 | |||
75 | if (pos < offsetof(struct user_int_regs, __status) + sizeof(long) && | ||
76 | pos + count > offsetof(struct user_int_regs, __status)) | ||
77 | return -EIO; | ||
78 | |||
79 | /* set the control regs */ | ||
80 | offs_gr0 = offsetof(struct user_int_regs, gr[0]); | ||
81 | offs_gr1 = offsetof(struct user_int_regs, gr[1]); | ||
82 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
83 | iregs, 0, offs_gr0); | ||
84 | if (ret < 0) | ||
85 | return ret; | ||
86 | |||
87 | /* skip GR0/TBR */ | ||
88 | ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
89 | offs_gr0, offs_gr1); | ||
90 | if (ret < 0) | ||
91 | return ret; | ||
92 | |||
93 | /* set the general regs */ | ||
94 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
95 | &iregs->gr[1], offs_gr1, sizeof(*iregs)); | ||
96 | if (ret < 0) | ||
97 | return ret; | ||
98 | |||
99 | return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
100 | sizeof(*iregs), -1); | ||
101 | } | ||
102 | |||
103 | /* | ||
104 | * retrieve the contents of FRV userspace FP/Media registers | ||
105 | */ | ||
106 | static int fpmregs_get(struct task_struct *target, | ||
107 | const struct user_regset *regset, | ||
108 | unsigned int pos, unsigned int count, | ||
109 | void *kbuf, void __user *ubuf) | ||
110 | { | ||
111 | const struct user_fpmedia_regs *fpregs = &target->thread.user->f; | ||
112 | int ret; | ||
113 | |||
114 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | ||
115 | fpregs, 0, sizeof(*fpregs)); | ||
116 | if (ret < 0) | ||
117 | return ret; | ||
118 | |||
119 | return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, | ||
120 | sizeof(*fpregs), -1); | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * update the contents of the FRV userspace FP/Media registers | ||
125 | */ | ||
126 | static int fpmregs_set(struct task_struct *target, | ||
127 | const struct user_regset *regset, | ||
128 | unsigned int pos, unsigned int count, | ||
129 | const void *kbuf, const void __user *ubuf) | ||
130 | { | ||
131 | struct user_fpmedia_regs *fpregs = &target->thread.user->f; | ||
132 | int ret; | ||
133 | |||
134 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | ||
135 | fpregs, 0, sizeof(*fpregs)); | ||
136 | if (ret < 0) | ||
137 | return ret; | ||
138 | |||
139 | return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, | ||
140 | sizeof(*fpregs), -1); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * determine if the FP/Media registers have actually been used | ||
145 | */ | ||
146 | static int fpmregs_active(struct task_struct *target, | ||
147 | const struct user_regset *regset) | ||
148 | { | ||
149 | return tsk_used_math(target) ? regset->n : 0; | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * Define the register sets available on the FRV under Linux | ||
154 | */ | ||
155 | enum frv_regset { | ||
156 | REGSET_GENERAL, | ||
157 | REGSET_FPMEDIA, | ||
158 | }; | ||
159 | |||
160 | static const struct user_regset frv_regsets[] = { | ||
161 | /* | ||
162 | * General register format is: | ||
163 | * PSR, ISR, CCR, CCCR, LR, LCR, PC, (STATUS), SYSCALLNO, ORIG_G8 | ||
164 | * GNER0-1, IACC0, TBR, GR1-63 | ||
165 | */ | ||
166 | [REGSET_GENERAL] = { | ||
167 | .core_note_type = NT_PRSTATUS, | ||
168 | .n = ELF_NGREG, | ||
169 | .size = sizeof(long), | ||
170 | .align = sizeof(long), | ||
171 | .get = genregs_get, | ||
172 | .set = genregs_set, | ||
173 | }, | ||
174 | /* | ||
175 | * FPU/Media register format is: | ||
176 | * FR0-63, FNER0-1, MSR0-1, ACC0-7, ACCG0-8, FSR | ||
177 | */ | ||
178 | [REGSET_FPMEDIA] = { | ||
179 | .core_note_type = NT_PRFPREG, | ||
180 | .n = sizeof(struct user_fpmedia_regs) / sizeof(long), | ||
181 | .size = sizeof(long), | ||
182 | .align = sizeof(long), | ||
183 | .get = fpmregs_get, | ||
184 | .set = fpmregs_set, | ||
185 | .active = fpmregs_active, | ||
186 | }, | ||
187 | }; | ||
188 | |||
189 | static const struct user_regset_view user_frv_native_view = { | ||
190 | .name = "frv", | ||
191 | .e_machine = EM_FRV, | ||
192 | .regsets = frv_regsets, | ||
193 | .n = ARRAY_SIZE(frv_regsets), | ||
194 | }; | ||
195 | |||
196 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) | ||
197 | { | ||
198 | return &user_frv_native_view; | ||
199 | } | ||
200 | |||
201 | /* | ||
36 | * Get contents of register REGNO in task TASK. | 202 | * Get contents of register REGNO in task TASK. |
37 | */ | 203 | */ |
38 | static inline long get_reg(struct task_struct *task, int regno) | 204 | static inline long get_reg(struct task_struct *task, int regno) |
@@ -69,40 +235,23 @@ static inline int put_reg(struct task_struct *task, int regno, | |||
69 | } | 235 | } |
70 | 236 | ||
71 | /* | 237 | /* |
72 | * check that an address falls within the bounds of the target process's memory | ||
73 | * mappings | ||
74 | */ | ||
75 | static inline int is_user_addr_valid(struct task_struct *child, | ||
76 | unsigned long start, unsigned long len) | ||
77 | { | ||
78 | #ifdef CONFIG_MMU | ||
79 | if (start >= PAGE_OFFSET || len > PAGE_OFFSET - start) | ||
80 | return -EIO; | ||
81 | return 0; | ||
82 | #else | ||
83 | struct vm_area_struct *vma; | ||
84 | |||
85 | vma = find_vma(child->mm, start); | ||
86 | if (vma && start >= vma->vm_start && start + len <= vma->vm_end) | ||
87 | return 0; | ||
88 | |||
89 | return -EIO; | ||
90 | #endif | ||
91 | } | ||
92 | |||
93 | /* | ||
94 | * Called by kernel/ptrace.c when detaching.. | 238 | * Called by kernel/ptrace.c when detaching.. |
95 | * | 239 | * |
96 | * Control h/w single stepping | 240 | * Control h/w single stepping |
97 | */ | 241 | */ |
98 | void ptrace_disable(struct task_struct *child) | 242 | void user_enable_single_step(struct task_struct *child) |
243 | { | ||
244 | child->thread.frame0->__status |= REG__STATUS_STEP; | ||
245 | } | ||
246 | |||
247 | void user_disable_single_step(struct task_struct *child) | ||
99 | { | 248 | { |
100 | child->thread.frame0->__status &= ~REG__STATUS_STEP; | 249 | child->thread.frame0->__status &= ~REG__STATUS_STEP; |
101 | } | 250 | } |
102 | 251 | ||
103 | void ptrace_enable(struct task_struct *child) | 252 | void ptrace_disable(struct task_struct *child) |
104 | { | 253 | { |
105 | child->thread.frame0->__status |= REG__STATUS_STEP; | 254 | user_disable_single_step(child); |
106 | } | 255 | } |
107 | 256 | ||
108 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 257 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) |
@@ -111,15 +260,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
111 | int ret; | 260 | int ret; |
112 | 261 | ||
113 | switch (request) { | 262 | switch (request) { |
114 | /* when I and D space are separate, these will need to be fixed. */ | ||
115 | case PTRACE_PEEKTEXT: /* read word at location addr. */ | ||
116 | case PTRACE_PEEKDATA: | ||
117 | ret = -EIO; | ||
118 | if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) | ||
119 | break; | ||
120 | ret = generic_ptrace_peekdata(child, addr, data); | ||
121 | break; | ||
122 | |||
123 | /* read the word at location addr in the USER area. */ | 263 | /* read the word at location addr in the USER area. */ |
124 | case PTRACE_PEEKUSR: { | 264 | case PTRACE_PEEKUSR: { |
125 | tmp = 0; | 265 | tmp = 0; |
@@ -163,15 +303,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
163 | break; | 303 | break; |
164 | } | 304 | } |
165 | 305 | ||
166 | /* when I and D space are separate, this will have to be fixed. */ | ||
167 | case PTRACE_POKETEXT: /* write the word at location addr. */ | ||
168 | case PTRACE_POKEDATA: | ||
169 | ret = -EIO; | ||
170 | if (is_user_addr_valid(child, addr, sizeof(tmp)) < 0) | ||
171 | break; | ||
172 | ret = generic_ptrace_pokedata(child, addr, data); | ||
173 | break; | ||
174 | |||
175 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 306 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
176 | ret = -EIO; | 307 | ret = -EIO; |
177 | if ((addr & 3) || addr < 0) | 308 | if ((addr & 3) || addr < 0) |
@@ -179,7 +310,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
179 | 310 | ||
180 | ret = 0; | 311 | ret = 0; |
181 | switch (addr >> 2) { | 312 | switch (addr >> 2) { |
182 | case 0 ... PT__END-1: | 313 | case 0 ... PT__END - 1: |
183 | ret = put_reg(child, addr >> 2, data); | 314 | ret = put_reg(child, addr >> 2, data); |
184 | break; | 315 | break; |
185 | 316 | ||
@@ -189,95 +320,29 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
189 | } | 320 | } |
190 | break; | 321 | break; |
191 | 322 | ||
192 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 323 | case PTRACE_GETREGS: /* Get all integer regs from the child. */ |
193 | case PTRACE_CONT: /* restart after signal. */ | 324 | return copy_regset_to_user(child, &user_frv_native_view, |
194 | ret = -EIO; | 325 | REGSET_GENERAL, |
195 | if (!valid_signal(data)) | 326 | 0, sizeof(child->thread.user->i), |
196 | break; | 327 | (void __user *)data); |
197 | if (request == PTRACE_SYSCALL) | 328 | |
198 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 329 | case PTRACE_SETREGS: /* Set all integer regs in the child. */ |
199 | else | 330 | return copy_regset_from_user(child, &user_frv_native_view, |
200 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 331 | REGSET_GENERAL, |
201 | child->exit_code = data; | 332 | 0, sizeof(child->thread.user->i), |
202 | ptrace_disable(child); | 333 | (const void __user *)data); |
203 | wake_up_process(child); | 334 | |
204 | ret = 0; | 335 | case PTRACE_GETFPREGS: /* Get the child FP/Media state. */ |
205 | break; | 336 | return copy_regset_to_user(child, &user_frv_native_view, |
206 | 337 | REGSET_FPMEDIA, | |
207 | /* make the child exit. Best I can do is send it a sigkill. | 338 | 0, sizeof(child->thread.user->f), |
208 | * perhaps it should be put in the status that it wants to | 339 | (void __user *)data); |
209 | * exit. | 340 | |
210 | */ | 341 | case PTRACE_SETFPREGS: /* Set the child FP/Media state. */ |
211 | case PTRACE_KILL: | 342 | return copy_regset_from_user(child, &user_frv_native_view, |
212 | ret = 0; | 343 | REGSET_FPMEDIA, |
213 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | 344 | 0, sizeof(child->thread.user->f), |
214 | break; | 345 | (const void __user *)data); |
215 | child->exit_code = SIGKILL; | ||
216 | clear_tsk_thread_flag(child, TIF_SINGLESTEP); | ||
217 | ptrace_disable(child); | ||
218 | wake_up_process(child); | ||
219 | break; | ||
220 | |||
221 | case PTRACE_SINGLESTEP: /* set the trap flag. */ | ||
222 | ret = -EIO; | ||
223 | if (!valid_signal(data)) | ||
224 | break; | ||
225 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | ||
226 | ptrace_enable(child); | ||
227 | child->exit_code = data; | ||
228 | wake_up_process(child); | ||
229 | ret = 0; | ||
230 | break; | ||
231 | |||
232 | case PTRACE_DETACH: /* detach a process that was attached. */ | ||
233 | ret = ptrace_detach(child, data); | ||
234 | break; | ||
235 | |||
236 | case PTRACE_GETREGS: { /* Get all integer regs from the child. */ | ||
237 | int i; | ||
238 | for (i = 0; i < PT__GPEND; i++) { | ||
239 | tmp = get_reg(child, i); | ||
240 | if (put_user(tmp, (unsigned long *) data)) { | ||
241 | ret = -EFAULT; | ||
242 | break; | ||
243 | } | ||
244 | data += sizeof(long); | ||
245 | } | ||
246 | ret = 0; | ||
247 | break; | ||
248 | } | ||
249 | |||
250 | case PTRACE_SETREGS: { /* Set all integer regs in the child. */ | ||
251 | int i; | ||
252 | for (i = 0; i < PT__GPEND; i++) { | ||
253 | if (get_user(tmp, (unsigned long *) data)) { | ||
254 | ret = -EFAULT; | ||
255 | break; | ||
256 | } | ||
257 | put_reg(child, i, tmp); | ||
258 | data += sizeof(long); | ||
259 | } | ||
260 | ret = 0; | ||
261 | break; | ||
262 | } | ||
263 | |||
264 | case PTRACE_GETFPREGS: { /* Get the child FP/Media state. */ | ||
265 | ret = 0; | ||
266 | if (copy_to_user((void *) data, | ||
267 | &child->thread.user->f, | ||
268 | sizeof(child->thread.user->f))) | ||
269 | ret = -EFAULT; | ||
270 | break; | ||
271 | } | ||
272 | |||
273 | case PTRACE_SETFPREGS: { /* Set the child FP/Media state. */ | ||
274 | ret = 0; | ||
275 | if (copy_from_user(&child->thread.user->f, | ||
276 | (void *) data, | ||
277 | sizeof(child->thread.user->f))) | ||
278 | ret = -EFAULT; | ||
279 | break; | ||
280 | } | ||
281 | 346 | ||
282 | case PTRACE_GETFDPIC: | 347 | case PTRACE_GETFDPIC: |
283 | tmp = 0; | 348 | tmp = 0; |
@@ -300,414 +365,36 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
300 | break; | 365 | break; |
301 | 366 | ||
302 | default: | 367 | default: |
303 | ret = -EIO; | 368 | ret = ptrace_request(child, request, addr, data); |
304 | break; | 369 | break; |
305 | } | 370 | } |
306 | return ret; | 371 | return ret; |
307 | } | 372 | } |
308 | 373 | ||
309 | int __nongprelbss kstrace; | 374 | /* |
310 | 375 | * handle tracing of system call entry | |
311 | static const struct { | 376 | * - return the revised system call number or ULONG_MAX to cause ENOSYS |
312 | const char *name; | 377 | */ |
313 | unsigned argmask; | 378 | asmlinkage unsigned long syscall_trace_entry(void) |
314 | } __syscall_name_table[NR_syscalls] = { | ||
315 | [0] = { "restart_syscall" }, | ||
316 | [1] = { "exit", 0x000001 }, | ||
317 | [2] = { "fork", 0xffffff }, | ||
318 | [3] = { "read", 0x000141 }, | ||
319 | [4] = { "write", 0x000141 }, | ||
320 | [5] = { "open", 0x000235 }, | ||
321 | [6] = { "close", 0x000001 }, | ||
322 | [7] = { "waitpid", 0x000141 }, | ||
323 | [8] = { "creat", 0x000025 }, | ||
324 | [9] = { "link", 0x000055 }, | ||
325 | [10] = { "unlink", 0x000005 }, | ||
326 | [11] = { "execve", 0x000445 }, | ||
327 | [12] = { "chdir", 0x000005 }, | ||
328 | [13] = { "time", 0x000004 }, | ||
329 | [14] = { "mknod", 0x000325 }, | ||
330 | [15] = { "chmod", 0x000025 }, | ||
331 | [16] = { "lchown", 0x000025 }, | ||
332 | [17] = { "break" }, | ||
333 | [18] = { "oldstat", 0x000045 }, | ||
334 | [19] = { "lseek", 0x000131 }, | ||
335 | [20] = { "getpid", 0xffffff }, | ||
336 | [21] = { "mount", 0x043555 }, | ||
337 | [22] = { "umount", 0x000005 }, | ||
338 | [23] = { "setuid", 0x000001 }, | ||
339 | [24] = { "getuid", 0xffffff }, | ||
340 | [25] = { "stime", 0x000004 }, | ||
341 | [26] = { "ptrace", 0x004413 }, | ||
342 | [27] = { "alarm", 0x000001 }, | ||
343 | [28] = { "oldfstat", 0x000041 }, | ||
344 | [29] = { "pause", 0xffffff }, | ||
345 | [30] = { "utime", 0x000045 }, | ||
346 | [31] = { "stty" }, | ||
347 | [32] = { "gtty" }, | ||
348 | [33] = { "access", 0x000025 }, | ||
349 | [34] = { "nice", 0x000001 }, | ||
350 | [35] = { "ftime" }, | ||
351 | [36] = { "sync", 0xffffff }, | ||
352 | [37] = { "kill", 0x000011 }, | ||
353 | [38] = { "rename", 0x000055 }, | ||
354 | [39] = { "mkdir", 0x000025 }, | ||
355 | [40] = { "rmdir", 0x000005 }, | ||
356 | [41] = { "dup", 0x000001 }, | ||
357 | [42] = { "pipe", 0x000004 }, | ||
358 | [43] = { "times", 0x000004 }, | ||
359 | [44] = { "prof" }, | ||
360 | [45] = { "brk", 0x000004 }, | ||
361 | [46] = { "setgid", 0x000001 }, | ||
362 | [47] = { "getgid", 0xffffff }, | ||
363 | [48] = { "signal", 0x000041 }, | ||
364 | [49] = { "geteuid", 0xffffff }, | ||
365 | [50] = { "getegid", 0xffffff }, | ||
366 | [51] = { "acct", 0x000005 }, | ||
367 | [52] = { "umount2", 0x000035 }, | ||
368 | [53] = { "lock" }, | ||
369 | [54] = { "ioctl", 0x000331 }, | ||
370 | [55] = { "fcntl", 0x000331 }, | ||
371 | [56] = { "mpx" }, | ||
372 | [57] = { "setpgid", 0x000011 }, | ||
373 | [58] = { "ulimit" }, | ||
374 | [60] = { "umask", 0x000002 }, | ||
375 | [61] = { "chroot", 0x000005 }, | ||
376 | [62] = { "ustat", 0x000043 }, | ||
377 | [63] = { "dup2", 0x000011 }, | ||
378 | [64] = { "getppid", 0xffffff }, | ||
379 | [65] = { "getpgrp", 0xffffff }, | ||
380 | [66] = { "setsid", 0xffffff }, | ||
381 | [67] = { "sigaction" }, | ||
382 | [68] = { "sgetmask" }, | ||
383 | [69] = { "ssetmask" }, | ||
384 | [70] = { "setreuid" }, | ||
385 | [71] = { "setregid" }, | ||
386 | [72] = { "sigsuspend" }, | ||
387 | [73] = { "sigpending" }, | ||
388 | [74] = { "sethostname" }, | ||
389 | [75] = { "setrlimit" }, | ||
390 | [76] = { "getrlimit" }, | ||
391 | [77] = { "getrusage" }, | ||
392 | [78] = { "gettimeofday" }, | ||
393 | [79] = { "settimeofday" }, | ||
394 | [80] = { "getgroups" }, | ||
395 | [81] = { "setgroups" }, | ||
396 | [82] = { "select" }, | ||
397 | [83] = { "symlink" }, | ||
398 | [84] = { "oldlstat" }, | ||
399 | [85] = { "readlink" }, | ||
400 | [86] = { "uselib" }, | ||
401 | [87] = { "swapon" }, | ||
402 | [88] = { "reboot" }, | ||
403 | [89] = { "readdir" }, | ||
404 | [91] = { "munmap", 0x000034 }, | ||
405 | [92] = { "truncate" }, | ||
406 | [93] = { "ftruncate" }, | ||
407 | [94] = { "fchmod" }, | ||
408 | [95] = { "fchown" }, | ||
409 | [96] = { "getpriority" }, | ||
410 | [97] = { "setpriority" }, | ||
411 | [99] = { "statfs" }, | ||
412 | [100] = { "fstatfs" }, | ||
413 | [102] = { "socketcall" }, | ||
414 | [103] = { "syslog" }, | ||
415 | [104] = { "setitimer" }, | ||
416 | [105] = { "getitimer" }, | ||
417 | [106] = { "stat" }, | ||
418 | [107] = { "lstat" }, | ||
419 | [108] = { "fstat" }, | ||
420 | [111] = { "vhangup" }, | ||
421 | [114] = { "wait4" }, | ||
422 | [115] = { "swapoff" }, | ||
423 | [116] = { "sysinfo" }, | ||
424 | [117] = { "ipc" }, | ||
425 | [118] = { "fsync" }, | ||
426 | [119] = { "sigreturn" }, | ||
427 | [120] = { "clone" }, | ||
428 | [121] = { "setdomainname" }, | ||
429 | [122] = { "uname" }, | ||
430 | [123] = { "modify_ldt" }, | ||
431 | [123] = { "cacheflush" }, | ||
432 | [124] = { "adjtimex" }, | ||
433 | [125] = { "mprotect" }, | ||
434 | [126] = { "sigprocmask" }, | ||
435 | [127] = { "create_module" }, | ||
436 | [128] = { "init_module" }, | ||
437 | [129] = { "delete_module" }, | ||
438 | [130] = { "get_kernel_syms" }, | ||
439 | [131] = { "quotactl" }, | ||
440 | [132] = { "getpgid" }, | ||
441 | [133] = { "fchdir" }, | ||
442 | [134] = { "bdflush" }, | ||
443 | [135] = { "sysfs" }, | ||
444 | [136] = { "personality" }, | ||
445 | [137] = { "afs_syscall" }, | ||
446 | [138] = { "setfsuid" }, | ||
447 | [139] = { "setfsgid" }, | ||
448 | [140] = { "_llseek", 0x014331 }, | ||
449 | [141] = { "getdents" }, | ||
450 | [142] = { "_newselect", 0x000141 }, | ||
451 | [143] = { "flock" }, | ||
452 | [144] = { "msync" }, | ||
453 | [145] = { "readv" }, | ||
454 | [146] = { "writev" }, | ||
455 | [147] = { "getsid", 0x000001 }, | ||
456 | [148] = { "fdatasync", 0x000001 }, | ||
457 | [149] = { "_sysctl", 0x000004 }, | ||
458 | [150] = { "mlock" }, | ||
459 | [151] = { "munlock" }, | ||
460 | [152] = { "mlockall" }, | ||
461 | [153] = { "munlockall" }, | ||
462 | [154] = { "sched_setparam" }, | ||
463 | [155] = { "sched_getparam" }, | ||
464 | [156] = { "sched_setscheduler" }, | ||
465 | [157] = { "sched_getscheduler" }, | ||
466 | [158] = { "sched_yield" }, | ||
467 | [159] = { "sched_get_priority_max" }, | ||
468 | [160] = { "sched_get_priority_min" }, | ||
469 | [161] = { "sched_rr_get_interval" }, | ||
470 | [162] = { "nanosleep", 0x000044 }, | ||
471 | [163] = { "mremap" }, | ||
472 | [164] = { "setresuid" }, | ||
473 | [165] = { "getresuid" }, | ||
474 | [166] = { "vm86" }, | ||
475 | [167] = { "query_module" }, | ||
476 | [168] = { "poll" }, | ||
477 | [169] = { "nfsservctl" }, | ||
478 | [170] = { "setresgid" }, | ||
479 | [171] = { "getresgid" }, | ||
480 | [172] = { "prctl", 0x333331 }, | ||
481 | [173] = { "rt_sigreturn", 0xffffff }, | ||
482 | [174] = { "rt_sigaction", 0x001441 }, | ||
483 | [175] = { "rt_sigprocmask", 0x001441 }, | ||
484 | [176] = { "rt_sigpending", 0x000014 }, | ||
485 | [177] = { "rt_sigtimedwait", 0x001444 }, | ||
486 | [178] = { "rt_sigqueueinfo", 0x000411 }, | ||
487 | [179] = { "rt_sigsuspend", 0x000014 }, | ||
488 | [180] = { "pread", 0x003341 }, | ||
489 | [181] = { "pwrite", 0x003341 }, | ||
490 | [182] = { "chown", 0x000115 }, | ||
491 | [183] = { "getcwd" }, | ||
492 | [184] = { "capget" }, | ||
493 | [185] = { "capset" }, | ||
494 | [186] = { "sigaltstack" }, | ||
495 | [187] = { "sendfile" }, | ||
496 | [188] = { "getpmsg" }, | ||
497 | [189] = { "putpmsg" }, | ||
498 | [190] = { "vfork", 0xffffff }, | ||
499 | [191] = { "ugetrlimit" }, | ||
500 | [192] = { "mmap2", 0x313314 }, | ||
501 | [193] = { "truncate64" }, | ||
502 | [194] = { "ftruncate64" }, | ||
503 | [195] = { "stat64", 0x000045 }, | ||
504 | [196] = { "lstat64", 0x000045 }, | ||
505 | [197] = { "fstat64", 0x000041 }, | ||
506 | [198] = { "lchown32" }, | ||
507 | [199] = { "getuid32", 0xffffff }, | ||
508 | [200] = { "getgid32", 0xffffff }, | ||
509 | [201] = { "geteuid32", 0xffffff }, | ||
510 | [202] = { "getegid32", 0xffffff }, | ||
511 | [203] = { "setreuid32" }, | ||
512 | [204] = { "setregid32" }, | ||
513 | [205] = { "getgroups32" }, | ||
514 | [206] = { "setgroups32" }, | ||
515 | [207] = { "fchown32" }, | ||
516 | [208] = { "setresuid32" }, | ||
517 | [209] = { "getresuid32" }, | ||
518 | [210] = { "setresgid32" }, | ||
519 | [211] = { "getresgid32" }, | ||
520 | [212] = { "chown32" }, | ||
521 | [213] = { "setuid32" }, | ||
522 | [214] = { "setgid32" }, | ||
523 | [215] = { "setfsuid32" }, | ||
524 | [216] = { "setfsgid32" }, | ||
525 | [217] = { "pivot_root" }, | ||
526 | [218] = { "mincore" }, | ||
527 | [219] = { "madvise" }, | ||
528 | [220] = { "getdents64" }, | ||
529 | [221] = { "fcntl64" }, | ||
530 | [223] = { "security" }, | ||
531 | [224] = { "gettid" }, | ||
532 | [225] = { "readahead" }, | ||
533 | [226] = { "setxattr" }, | ||
534 | [227] = { "lsetxattr" }, | ||
535 | [228] = { "fsetxattr" }, | ||
536 | [229] = { "getxattr" }, | ||
537 | [230] = { "lgetxattr" }, | ||
538 | [231] = { "fgetxattr" }, | ||
539 | [232] = { "listxattr" }, | ||
540 | [233] = { "llistxattr" }, | ||
541 | [234] = { "flistxattr" }, | ||
542 | [235] = { "removexattr" }, | ||
543 | [236] = { "lremovexattr" }, | ||
544 | [237] = { "fremovexattr" }, | ||
545 | [238] = { "tkill" }, | ||
546 | [239] = { "sendfile64" }, | ||
547 | [240] = { "futex" }, | ||
548 | [241] = { "sched_setaffinity" }, | ||
549 | [242] = { "sched_getaffinity" }, | ||
550 | [243] = { "set_thread_area" }, | ||
551 | [244] = { "get_thread_area" }, | ||
552 | [245] = { "io_setup" }, | ||
553 | [246] = { "io_destroy" }, | ||
554 | [247] = { "io_getevents" }, | ||
555 | [248] = { "io_submit" }, | ||
556 | [249] = { "io_cancel" }, | ||
557 | [250] = { "fadvise64" }, | ||
558 | [252] = { "exit_group", 0x000001 }, | ||
559 | [253] = { "lookup_dcookie" }, | ||
560 | [254] = { "epoll_create" }, | ||
561 | [255] = { "epoll_ctl" }, | ||
562 | [256] = { "epoll_wait" }, | ||
563 | [257] = { "remap_file_pages" }, | ||
564 | [258] = { "set_tid_address" }, | ||
565 | [259] = { "timer_create" }, | ||
566 | [260] = { "timer_settime" }, | ||
567 | [261] = { "timer_gettime" }, | ||
568 | [262] = { "timer_getoverrun" }, | ||
569 | [263] = { "timer_delete" }, | ||
570 | [264] = { "clock_settime" }, | ||
571 | [265] = { "clock_gettime" }, | ||
572 | [266] = { "clock_getres" }, | ||
573 | [267] = { "clock_nanosleep" }, | ||
574 | [268] = { "statfs64" }, | ||
575 | [269] = { "fstatfs64" }, | ||
576 | [270] = { "tgkill" }, | ||
577 | [271] = { "utimes" }, | ||
578 | [272] = { "fadvise64_64" }, | ||
579 | [273] = { "vserver" }, | ||
580 | [274] = { "mbind" }, | ||
581 | [275] = { "get_mempolicy" }, | ||
582 | [276] = { "set_mempolicy" }, | ||
583 | [277] = { "mq_open" }, | ||
584 | [278] = { "mq_unlink" }, | ||
585 | [279] = { "mq_timedsend" }, | ||
586 | [280] = { "mq_timedreceive" }, | ||
587 | [281] = { "mq_notify" }, | ||
588 | [282] = { "mq_getsetattr" }, | ||
589 | [283] = { "sys_kexec_load" }, | ||
590 | }; | ||
591 | |||
592 | asmlinkage void do_syscall_trace(int leaving) | ||
593 | { | 379 | { |
594 | #if 0 | 380 | __frame->__status |= REG__STATUS_SYSC_ENTRY; |
595 | unsigned long *argp; | 381 | if (tracehook_report_syscall_entry(__frame)) { |
596 | const char *name; | 382 | /* tracing decided this syscall should not happen, so |
597 | unsigned argmask; | 383 | * We'll return a bogus call number to get an ENOSYS |
598 | char buffer[16]; | 384 | * error, but leave the original number in |
599 | 385 | * __frame->syscallno | |
600 | if (!kstrace) | 386 | */ |
601 | return; | 387 | return ULONG_MAX; |
602 | |||
603 | if (!current->mm) | ||
604 | return; | ||
605 | |||
606 | if (__frame->gr7 == __NR_close) | ||
607 | return; | ||
608 | |||
609 | #if 0 | ||
610 | if (__frame->gr7 != __NR_mmap2 && | ||
611 | __frame->gr7 != __NR_vfork && | ||
612 | __frame->gr7 != __NR_execve && | ||
613 | __frame->gr7 != __NR_exit) | ||
614 | return; | ||
615 | #endif | ||
616 | |||
617 | argmask = 0; | ||
618 | name = NULL; | ||
619 | if (__frame->gr7 < NR_syscalls) { | ||
620 | name = __syscall_name_table[__frame->gr7].name; | ||
621 | argmask = __syscall_name_table[__frame->gr7].argmask; | ||
622 | } | ||
623 | if (!name) { | ||
624 | sprintf(buffer, "sys_%lx", __frame->gr7); | ||
625 | name = buffer; | ||
626 | } | ||
627 | |||
628 | if (!leaving) { | ||
629 | if (!argmask) { | ||
630 | printk(KERN_CRIT "[%d] %s(%lx,%lx,%lx,%lx,%lx,%lx)\n", | ||
631 | current->pid, | ||
632 | name, | ||
633 | __frame->gr8, | ||
634 | __frame->gr9, | ||
635 | __frame->gr10, | ||
636 | __frame->gr11, | ||
637 | __frame->gr12, | ||
638 | __frame->gr13); | ||
639 | } | ||
640 | else if (argmask == 0xffffff) { | ||
641 | printk(KERN_CRIT "[%d] %s()\n", | ||
642 | current->pid, | ||
643 | name); | ||
644 | } | ||
645 | else { | ||
646 | printk(KERN_CRIT "[%d] %s(", | ||
647 | current->pid, | ||
648 | name); | ||
649 | |||
650 | argp = &__frame->gr8; | ||
651 | |||
652 | do { | ||
653 | switch (argmask & 0xf) { | ||
654 | case 1: | ||
655 | printk("%ld", (long) *argp); | ||
656 | break; | ||
657 | case 2: | ||
658 | printk("%lo", *argp); | ||
659 | break; | ||
660 | case 3: | ||
661 | printk("%lx", *argp); | ||
662 | break; | ||
663 | case 4: | ||
664 | printk("%p", (void *) *argp); | ||
665 | break; | ||
666 | case 5: | ||
667 | printk("\"%s\"", (char *) *argp); | ||
668 | break; | ||
669 | } | ||
670 | |||
671 | argp++; | ||
672 | argmask >>= 4; | ||
673 | if (argmask) | ||
674 | printk(","); | ||
675 | |||
676 | } while (argmask); | ||
677 | |||
678 | printk(")\n"); | ||
679 | } | ||
680 | } | ||
681 | else { | ||
682 | if ((int)__frame->gr8 > -4096 && (int)__frame->gr8 < 4096) | ||
683 | printk(KERN_CRIT "[%d] %s() = %ld\n", current->pid, name, __frame->gr8); | ||
684 | else | ||
685 | printk(KERN_CRIT "[%d] %s() = %lx\n", current->pid, name, __frame->gr8); | ||
686 | } | 388 | } |
687 | return; | ||
688 | #endif | ||
689 | |||
690 | if (!test_thread_flag(TIF_SYSCALL_TRACE)) | ||
691 | return; | ||
692 | |||
693 | if (!(current->ptrace & PT_PTRACED)) | ||
694 | return; | ||
695 | 389 | ||
696 | /* we need to indicate entry or exit to strace */ | 390 | return __frame->syscallno; |
697 | if (leaving) | 391 | } |
698 | __frame->__status |= REG__STATUS_SYSC_EXIT; | ||
699 | else | ||
700 | __frame->__status |= REG__STATUS_SYSC_ENTRY; | ||
701 | |||
702 | ptrace_notify(SIGTRAP); | ||
703 | 392 | ||
704 | /* | 393 | /* |
705 | * this isn't the same as continuing with a signal, but it will do | 394 | * handle tracing of system call exit |
706 | * for normal use. strace only continues with a signal if the | 395 | */ |
707 | * stopping signal is not SIGTRAP. -brl | 396 | asmlinkage void syscall_trace_exit(void) |
708 | */ | 397 | { |
709 | if (current->exit_code) { | 398 | __frame->__status |= REG__STATUS_SYSC_EXIT; |
710 | send_sig(current->exit_code, current, 1); | 399 | tracehook_report_syscall_exit(__frame, 0); |
711 | current->exit_code = 0; | ||
712 | } | ||
713 | } | 400 | } |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 3bdb368292a8..4a7a62c6e783 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/unistd.h> | 21 | #include <linux/unistd.h> |
22 | #include <linux/personality.h> | 22 | #include <linux/personality.h> |
23 | #include <linux/freezer.h> | 23 | #include <linux/freezer.h> |
24 | #include <linux/tracehook.h> | ||
24 | #include <asm/ucontext.h> | 25 | #include <asm/ucontext.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
@@ -516,6 +517,9 @@ static void do_signal(void) | |||
516 | * clear the TIF_RESTORE_SIGMASK flag */ | 517 | * clear the TIF_RESTORE_SIGMASK flag */ |
517 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | 518 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
518 | clear_thread_flag(TIF_RESTORE_SIGMASK); | 519 | clear_thread_flag(TIF_RESTORE_SIGMASK); |
520 | |||
521 | tracehook_signal_handler(signr, &info, &ka, __frame, | ||
522 | test_thread_flag(TIF_SINGLESTEP)); | ||
519 | } | 523 | } |
520 | 524 | ||
521 | return; | 525 | return; |
@@ -564,4 +568,10 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags) | |||
564 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) | 568 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
565 | do_signal(); | 569 | do_signal(); |
566 | 570 | ||
571 | /* deal with notification on about to resume userspace execution */ | ||
572 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
573 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
574 | tracehook_notify_resume(__frame); | ||
575 | } | ||
576 | |||
567 | } /* end do_notify_resume() */ | 577 | } /* end do_notify_resume() */ |
diff --git a/arch/frv/kernel/uaccess.c b/arch/frv/kernel/uaccess.c index 9fb771a20df3..374f88d6cc00 100644 --- a/arch/frv/kernel/uaccess.c +++ b/arch/frv/kernel/uaccess.c | |||
@@ -23,8 +23,7 @@ long strncpy_from_user(char *dst, const char __user *src, long count) | |||
23 | char *p, ch; | 23 | char *p, ch; |
24 | long err = -EFAULT; | 24 | long err = -EFAULT; |
25 | 25 | ||
26 | if (count < 0) | 26 | BUG_ON(count < 0); |
27 | BUG(); | ||
28 | 27 | ||
29 | p = dst; | 28 | p = dst; |
30 | 29 | ||
@@ -76,8 +75,7 @@ long strnlen_user(const char __user *src, long count) | |||
76 | long err = 0; | 75 | long err = 0; |
77 | char ch; | 76 | char ch; |
78 | 77 | ||
79 | if (count < 0) | 78 | BUG_ON(count < 0); |
80 | BUG(); | ||
81 | 79 | ||
82 | #ifndef CONFIG_MMU | 80 | #ifndef CONFIG_MMU |
83 | if ((unsigned long) src < memory_start) | 81 | if ((unsigned long) src < memory_start) |