diff options
-rw-r--r-- | arch/sh/kernel/process_32.c | 9 | ||||
-rw-r--r-- | arch/sh/kernel/process_64.c | 10 | ||||
-rw-r--r-- | arch/sh/kernel/sys_sh.c | 2 | ||||
-rw-r--r-- | arch/sh/mm/fault_32.c | 57 |
4 files changed, 50 insertions, 28 deletions
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 914e543102df..7b013aa8c43f 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c | |||
@@ -169,6 +169,7 @@ __asm__(".align 5\n" | |||
169 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | 169 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) |
170 | { | 170 | { |
171 | struct pt_regs regs; | 171 | struct pt_regs regs; |
172 | int pid; | ||
172 | 173 | ||
173 | memset(®s, 0, sizeof(regs)); | 174 | memset(®s, 0, sizeof(regs)); |
174 | regs.regs[4] = (unsigned long)arg; | 175 | regs.regs[4] = (unsigned long)arg; |
@@ -178,8 +179,12 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
178 | regs.sr = (1 << 30); | 179 | regs.sr = (1 << 30); |
179 | 180 | ||
180 | /* Ok, create the new process.. */ | 181 | /* Ok, create the new process.. */ |
181 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, | 182 | pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, |
182 | ®s, 0, NULL, NULL); | 183 | ®s, 0, NULL, NULL); |
184 | |||
185 | trace_mark(kernel_arch_kthread_create, "pid %d fn %p", pid, fn); | ||
186 | |||
187 | return pid; | ||
183 | } | 188 | } |
184 | 189 | ||
185 | /* | 190 | /* |
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index d0dddc438c0c..b7aa09235b51 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c | |||
@@ -396,6 +396,7 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *)) | |||
396 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | 396 | int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) |
397 | { | 397 | { |
398 | struct pt_regs regs; | 398 | struct pt_regs regs; |
399 | int pid; | ||
399 | 400 | ||
400 | memset(®s, 0, sizeof(regs)); | 401 | memset(®s, 0, sizeof(regs)); |
401 | regs.regs[2] = (unsigned long)arg; | 402 | regs.regs[2] = (unsigned long)arg; |
@@ -404,8 +405,13 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
404 | regs.pc = (unsigned long)kernel_thread_helper; | 405 | regs.pc = (unsigned long)kernel_thread_helper; |
405 | regs.sr = (1 << 30); | 406 | regs.sr = (1 << 30); |
406 | 407 | ||
407 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, | 408 | /* Ok, create the new process.. */ |
408 | ®s, 0, NULL, NULL); | 409 | pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, |
410 | ®s, 0, NULL, NULL); | ||
411 | |||
412 | trace_mark(kernel_arch_kthread_create, "pid %d fn %p", pid, fn); | ||
413 | |||
414 | return pid; | ||
409 | } | 415 | } |
410 | 416 | ||
411 | /* | 417 | /* |
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 0dfb88925add..38f098c9c72d 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c | |||
@@ -171,6 +171,8 @@ asmlinkage int sys_ipc(uint call, int first, int second, | |||
171 | version = call >> 16; /* hack for backward compatibility */ | 171 | version = call >> 16; /* hack for backward compatibility */ |
172 | call &= 0xffff; | 172 | call &= 0xffff; |
173 | 173 | ||
174 | trace_mark(kernel_arch_ipc_call, "call %u first %d", call, first); | ||
175 | |||
174 | if (call <= SEMTIMEDOP) | 176 | if (call <= SEMTIMEDOP) |
175 | switch (call) { | 177 | switch (call) { |
176 | case SEMOP: | 178 | case SEMOP: |
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index 08a08ea5d69f..898d477e47c1 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c | |||
@@ -15,28 +15,13 @@ | |||
15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
16 | #include <linux/hardirq.h> | 16 | #include <linux/hardirq.h> |
17 | #include <linux/kprobes.h> | 17 | #include <linux/kprobes.h> |
18 | #include <linux/marker.h> | ||
18 | #include <asm/io_trapped.h> | 19 | #include <asm/io_trapped.h> |
19 | #include <asm/system.h> | 20 | #include <asm/system.h> |
20 | #include <asm/mmu_context.h> | 21 | #include <asm/mmu_context.h> |
21 | #include <asm/tlbflush.h> | 22 | #include <asm/tlbflush.h> |
22 | #include <asm/kgdb.h> | 23 | #include <asm/kgdb.h> |
23 | 24 | ||
24 | static inline int notify_page_fault(struct pt_regs *regs, int trap) | ||
25 | { | ||
26 | int ret = 0; | ||
27 | |||
28 | #ifdef CONFIG_KPROBES | ||
29 | if (!user_mode(regs)) { | ||
30 | preempt_disable(); | ||
31 | if (kprobe_running() && kprobe_fault_handler(regs, trap)) | ||
32 | ret = 1; | ||
33 | preempt_enable(); | ||
34 | } | ||
35 | #endif | ||
36 | |||
37 | return ret; | ||
38 | } | ||
39 | |||
40 | /* | 25 | /* |
41 | * This routine handles page faults. It determines the address, | 26 | * This routine handles page faults. It determines the address, |
42 | * and the problem, and then passes it off to one of the appropriate | 27 | * and the problem, and then passes it off to one of the appropriate |
@@ -261,6 +246,25 @@ do_sigbus: | |||
261 | goto no_context; | 246 | goto no_context; |
262 | } | 247 | } |
263 | 248 | ||
249 | static inline int notify_page_fault(struct pt_regs *regs, int trap) | ||
250 | { | ||
251 | int ret = 0; | ||
252 | |||
253 | trace_mark(kernel_arch_trap_entry, "trap_id %d ip #p%ld", | ||
254 | trap >> 5, instruction_pointer(regs)); | ||
255 | |||
256 | #ifdef CONFIG_KPROBES | ||
257 | if (!user_mode(regs)) { | ||
258 | preempt_disable(); | ||
259 | if (kprobe_running() && kprobe_fault_handler(regs, trap)) | ||
260 | ret = 1; | ||
261 | preempt_enable(); | ||
262 | } | ||
263 | #endif | ||
264 | |||
265 | return ret; | ||
266 | } | ||
267 | |||
264 | #ifdef CONFIG_SH_STORE_QUEUES | 268 | #ifdef CONFIG_SH_STORE_QUEUES |
265 | /* | 269 | /* |
266 | * This is a special case for the SH-4 store queues, as pages for this | 270 | * This is a special case for the SH-4 store queues, as pages for this |
@@ -284,15 +288,18 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, | |||
284 | pmd_t *pmd; | 288 | pmd_t *pmd; |
285 | pte_t *pte; | 289 | pte_t *pte; |
286 | pte_t entry; | 290 | pte_t entry; |
291 | int ret = 0; | ||
287 | 292 | ||
288 | if (notify_page_fault(regs, lookup_exception_vector())) | 293 | if (notify_page_fault(regs, lookup_exception_vector())) |
289 | return 0; | 294 | goto out; |
290 | 295 | ||
291 | #ifdef CONFIG_SH_KGDB | 296 | #ifdef CONFIG_SH_KGDB |
292 | if (kgdb_nofault && kgdb_bus_err_hook) | 297 | if (kgdb_nofault && kgdb_bus_err_hook) |
293 | kgdb_bus_err_hook(); | 298 | kgdb_bus_err_hook(); |
294 | #endif | 299 | #endif |
295 | 300 | ||
301 | ret = 1; | ||
302 | |||
296 | /* | 303 | /* |
297 | * We don't take page faults for P1, P2, and parts of P4, these | 304 | * We don't take page faults for P1, P2, and parts of P4, these |
298 | * are always mapped, whether it be due to legacy behaviour in | 305 | * are always mapped, whether it be due to legacy behaviour in |
@@ -302,24 +309,23 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, | |||
302 | pgd = pgd_offset_k(address); | 309 | pgd = pgd_offset_k(address); |
303 | } else { | 310 | } else { |
304 | if (unlikely(address >= TASK_SIZE || !current->mm)) | 311 | if (unlikely(address >= TASK_SIZE || !current->mm)) |
305 | return 1; | 312 | goto out; |
306 | 313 | ||
307 | pgd = pgd_offset(current->mm, address); | 314 | pgd = pgd_offset(current->mm, address); |
308 | } | 315 | } |
309 | 316 | ||
310 | pud = pud_offset(pgd, address); | 317 | pud = pud_offset(pgd, address); |
311 | if (pud_none_or_clear_bad(pud)) | 318 | if (pud_none_or_clear_bad(pud)) |
312 | return 1; | 319 | goto out; |
313 | pmd = pmd_offset(pud, address); | 320 | pmd = pmd_offset(pud, address); |
314 | if (pmd_none_or_clear_bad(pmd)) | 321 | if (pmd_none_or_clear_bad(pmd)) |
315 | return 1; | 322 | goto out; |
316 | |||
317 | pte = pte_offset_kernel(pmd, address); | 323 | pte = pte_offset_kernel(pmd, address); |
318 | entry = *pte; | 324 | entry = *pte; |
319 | if (unlikely(pte_none(entry) || pte_not_present(entry))) | 325 | if (unlikely(pte_none(entry) || pte_not_present(entry))) |
320 | return 1; | 326 | goto out; |
321 | if (unlikely(writeaccess && !pte_write(entry))) | 327 | if (unlikely(writeaccess && !pte_write(entry))) |
322 | return 1; | 328 | goto out; |
323 | 329 | ||
324 | if (writeaccess) | 330 | if (writeaccess) |
325 | entry = pte_mkdirty(entry); | 331 | entry = pte_mkdirty(entry); |
@@ -336,5 +342,8 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, | |||
336 | set_pte(pte, entry); | 342 | set_pte(pte, entry); |
337 | update_mmu_cache(NULL, address, entry); | 343 | update_mmu_cache(NULL, address, entry); |
338 | 344 | ||
339 | return 0; | 345 | ret = 0; |
346 | out: | ||
347 | trace_mark(kernel_arch_trap_exit, MARK_NOARGS); | ||
348 | return ret; | ||
340 | } | 349 | } |