Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 24114
b: refs/heads/master
c: b670009
h: refs/heads/master
v: v3
  • Loading branch information
Prasanna S Panchamukhi authored and Linus Torvalds committed Mar 26, 2006
1 parent feb7fcb commit bf77dcc
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c04c1c81e211c2c95b548add7923e1d4ba4847ab
refs/heads/master: b67000962f35313cfc5eabd675dc38b91678d9ed
66 changes: 60 additions & 6 deletions trunk/arch/sparc64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/module.h>
#include <asm/kdebug.h>
#include <asm/signal.h>
#include <asm/cacheflush.h>
#include <asm/uaccess.h>

/* We do not have hardware single-stepping on sparc64.
* So we implement software single-stepping with breakpoint
Expand Down Expand Up @@ -302,16 +304,68 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
const struct exception_table_entry *entry;

switch(kcb->kprobe_status) {
case KPROBE_HIT_SS:
case KPROBE_REENTER:
/*
* We are here because the instruction being single
* stepped caused a page fault. We reset the current
* kprobe and the tpc points back to the probe address
* and allow the page fault handler to continue as a
* normal page fault.
*/
regs->tpc = (unsigned long)cur->addr;
regs->tnpc = kcb->kprobe_orig_tnpc;
regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
kcb->kprobe_orig_tstate_pil);
if (kcb->kprobe_status == KPROBE_REENTER)
restore_previous_kprobe(kcb);
else
reset_current_kprobe();
preempt_enable_no_resched();
break;
case KPROBE_HIT_ACTIVE:
case KPROBE_HIT_SSDONE:
/*
* We increment the nmissed count for accounting,
* we can also use npre/npostfault count for accouting
* these specific fault cases.
*/
kprobes_inc_nmissed_count(cur);

/*
* We come here because instructions in the pre/post
* handler caused the page_fault, this could happen
* if handler tries to access user space by
* copy_from_user(), get_user() etc. Let the
* user-specified handler try to fix it first.
*/
if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;

if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
return 1;
/*
* In case the user-specified fault handler returned
* zero, try to fix up.
*/

if (kcb->kprobe_status & KPROBE_HIT_SS) {
resume_execution(cur, regs, kcb);
entry = search_exception_tables(regs->tpc);
if (entry) {
regs->tpc = entry->fixup;
regs->tnpc = regs->tpc + 4;
return 1;
}

reset_current_kprobe();
preempt_enable_no_resched();
/*
* fixup_exception() could not handle it,
* Let do_page_fault() fix it.
*/
break;
default:
break;
}

return 0;
}

Expand Down

0 comments on commit bf77dcc

Please sign in to comment.