X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fkprobes.c;h=b9a9ce70e55c1f281ff4759b47abc6d03e10ae49;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=2e1c824c1cc9512356460ea3a09f2fd74c11dfe2;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 2e1c824c1..b9a9ce70e 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -6,11 +6,9 @@ #include #include #include -#include #include #include #include -#include /* We do not have hardware single-stepping on sparc64. * So we implement software single-stepping with breakpoint @@ -63,7 +61,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) flushi(p->addr); } -static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) +static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) { kcb->prev_kprobe.kp = kprobe_running(); kcb->prev_kprobe.status = kcb->kprobe_status; @@ -71,7 +69,7 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil; } -static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) +static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) { __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; kcb->kprobe_status = kcb->prev_kprobe.status; @@ -79,7 +77,7 @@ static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil; } -static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, +static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { __get_cpu_var(current_kprobe) = p; @@ -87,7 +85,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); } -static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs, +static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs, struct kprobe_ctlblk *kcb) { regs->tstate |= TSTATE_PIL; @@ -273,7 +271,7 @@ static void __kprobes resume_execution(struct kprobe *p, kcb->kprobe_orig_tstate_pil); } -static int __kprobes post_kprobe_handler(struct pt_regs *regs) +static inline int post_kprobe_handler(struct pt_regs *regs) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); @@ -300,72 +298,20 @@ out: return 1; } -static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) +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; - /* - * In case the user-specified fault handler returned - * zero, try to fix up. - */ + if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) + return 1; - entry = search_exception_tables(regs->tpc); - if (entry) { - regs->tpc = entry->fixup; - regs->tnpc = regs->tpc + 4; - return 1; - } + if (kcb->kprobe_status & KPROBE_HIT_SS) { + resume_execution(cur, regs, kcb); - /* - * fixup_exception() could not handle it, - * Let do_page_fault() fix it. - */ - break; - default: - break; + reset_current_kprobe(); + preempt_enable_no_resched(); } - return 0; } @@ -378,9 +324,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, struct die_args *args = (struct die_args *)data; int ret = NOTIFY_DONE; - if (args->regs && user_mode(args->regs)) - return ret; - switch (val) { case DIE_DEBUG: if (kprobe_handler(args->regs))