From 9359b8b8eec6ee8e3e5ca35c23896099f47147dd Mon Sep 17 00:00:00 2001 From: Vyacheslav Cherkashin Date: Tue, 26 Apr 2016 19:40:21 +0300 Subject: [PATCH] [IMPROVE] remove preemption disabling from kprobe Change-Id: Ie0ac12b32b4caa76fc2162b7dc467851260c9f0a Signed-off-by: Vyacheslav Cherkashin --- kprobe/arch/arm/swap-asm/swap_kprobes.c | 5 +---- kprobe/arch/x86/swap-asm/swap_kprobes.c | 37 +++++++-------------------------- kprobe/swap_kprobes.c | 2 -- kprobe/swap_kprobes.h | 1 - kprobe/swap_kprobes_deps.h | 23 -------------------- 5 files changed, 9 insertions(+), 59 deletions(-) diff --git a/kprobe/arch/arm/swap-asm/swap_kprobes.c b/kprobe/arch/arm/swap-asm/swap_kprobes.c index 89f0459..2a689b2 100644 --- a/kprobe/arch/arm/swap-asm/swap_kprobes.c +++ b/kprobe/arch/arm/swap-asm/swap_kprobes.c @@ -343,7 +343,7 @@ int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm) * @param regs Pointer to CPU registers data. * @return Void. */ -void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) +static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { int cpu = smp_processor_id(); @@ -354,7 +354,6 @@ void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) regs->ARM_pc = (unsigned long)p->ainsn.insn; } } -EXPORT_SYMBOL_GPL(prepare_singlestep); /** * @brief Saves previous kprobe. @@ -458,7 +457,6 @@ int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) unsigned long flags; local_irq_save(flags); - preempt_disable(); if (likely(instr == BREAKPOINT_INSTRUCTION)) { ret = kprobe_handler(regs); @@ -469,7 +467,6 @@ int kprobe_trap_handler(struct pt_regs *regs, unsigned int instr) ret = p && (p->opcode == instr) ? 0 : 1; } - swap_preempt_enable_no_resched(); local_irq_restore(flags); return ret; diff --git a/kprobe/arch/x86/swap-asm/swap_kprobes.c b/kprobe/arch/x86/swap-asm/swap_kprobes.c index bce501a..29cd7e8 100644 --- a/kprobe/arch/x86/swap-asm/swap_kprobes.c +++ b/kprobe/arch/x86/swap-asm/swap_kprobes.c @@ -239,25 +239,17 @@ int swap_arch_prepare_kprobe(struct kprobe *p, struct slot_manager *sm) * @param regs Pointer to CPU registers data. * @return Void. */ -void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) +static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) { - int cpu = smp_processor_id(); + regs->flags |= TF_MASK; + regs->flags &= ~IF_MASK; - if (p->ss_addr[cpu]) { - regs->EREG(ip) = (unsigned long)p->ss_addr[cpu]; - p->ss_addr[cpu] = NULL; - } else { - regs->EREG(flags) |= TF_MASK; - regs->EREG(flags) &= ~IF_MASK; - /* single step inline if the instruction is an int3 */ - if (p->opcode == BREAKPOINT_INSTRUCTION) { - regs->EREG(ip) = (unsigned long) p->addr; - /* printk(KERN_INFO "break_insn!!!\n"); */ - } else - regs->EREG(ip) = (unsigned long) p->ainsn.insn; - } + /* single step inline if the instruction is an int3 */ + if (p->opcode == BREAKPOINT_INSTRUCTION) + regs->ip = (unsigned long)p->addr; + else + regs->ip = (unsigned long)p->ainsn.insn; } -EXPORT_SYMBOL_GPL(prepare_singlestep); /** * @brief Saves previous kprobe. @@ -322,7 +314,6 @@ static int setup_singlestep(struct kprobe *p, struct pt_regs *regs, /* Boost up -- we can execute copied instructions directly */ swap_kprobe_running_set(NULL); regs->ip = (unsigned long)p->ainsn.insn; - swap_preempt_enable_no_resched(); return 1; } @@ -343,8 +334,6 @@ static int __kprobe_handler(struct pt_regs *regs) addr = (kprobe_opcode_t *) (regs->EREG(ip) - sizeof(kprobe_opcode_t)); - preempt_disable(); - kcb = swap_get_kprobe_ctlblk(); p = swap_get_kprobe(addr); @@ -430,8 +419,6 @@ ss_probe: return 1; no_kprobe: - swap_preempt_enable_no_resched(); - return ret; } @@ -646,8 +633,6 @@ static int post_kprobe_handler(struct pt_regs *regs) } swap_kprobe_running_set(NULL); out: - swap_preempt_enable_no_resched(); - /* * if somebody else is singlestepping across a probe point, eflags * will have TF set, in which case, continue the remaining processing @@ -680,7 +665,6 @@ static int kprobe_fault_handler(struct pt_regs *regs, int trapnr) restore_previous_kprobe(kcb); else swap_kprobe_running_set(NULL); - swap_preempt_enable_no_resched(); break; case KPROBE_HIT_ACTIVE: case KPROBE_HIT_SSDONE: @@ -749,12 +733,9 @@ static int kprobe_exceptions_notify(struct notifier_block *self, ret = NOTIFY_STOP; break; case DIE_GPF: - /* swap_kprobe_running() needs smp_processor_id() */ - preempt_disable(); if (swap_kprobe_running() && kprobe_fault_handler(args->regs, args->trapnr)) ret = NOTIFY_STOP; - preempt_enable(); break; default: break; @@ -803,7 +784,6 @@ int swap_longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) *regs = kcb->jprobe_saved_regs; memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack, MIN_STACK_SIZE(stack_addr)); - swap_preempt_enable_no_resched(); return 1; } @@ -925,7 +905,6 @@ int set_kjump_cb(struct pt_regs *regs, jumper_cb_t cb, void *data, size_t size) regs->ip = (unsigned long)&kjump_trampoline; swap_kprobe_running_set(NULL); - swap_preempt_enable_no_resched(); return 1; } diff --git a/kprobe/swap_kprobes.c b/kprobe/swap_kprobes.c index 5a1e444..c90757e 100644 --- a/kprobe/swap_kprobes.c +++ b/kprobe/swap_kprobes.c @@ -768,7 +768,6 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) trampoline_address = (unsigned long)&swap_kretprobe_trampoline; - preempt_disable(); kcb = swap_get_kprobe_ctlblk(); spin_lock_irqsave(&kretprobe_lock, flags); @@ -830,7 +829,6 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) swap_kprobe_running_set(NULL); spin_unlock_irqrestore(&kretprobe_lock, flags); - swap_preempt_enable_no_resched(); /* * By returning a non-zero value, we are telling diff --git a/kprobe/swap_kprobes.h b/kprobe/swap_kprobes.h index cde78a8..c69824c 100644 --- a/kprobe/swap_kprobes.h +++ b/kprobe/swap_kprobes.h @@ -297,7 +297,6 @@ void swap_kprobe_running_set(struct kprobe *p); void swap_reset_current_kprobe(void); struct kprobe_ctlblk *swap_get_kprobe_ctlblk(void); -void prepare_singlestep(struct kprobe *p, struct pt_regs *regs); #endif /* _SWAP_KPROBES_H */ diff --git a/kprobe/swap_kprobes_deps.h b/kprobe/swap_kprobes_deps.h index e555ecb..913e5c2 100644 --- a/kprobe/swap_kprobes_deps.h +++ b/kprobe/swap_kprobes_deps.h @@ -66,29 +66,6 @@ #endif -/* - * TODO: possibly unnided - * check and remove swap_preempt_enable_no_resched() call - */ -#if (defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))) - -#ifdef CONFIG_PREEMPT_COUNT -#define swap_preempt_enable_no_resched() \ -do { \ - barrier(); \ - preempt_count_dec(); \ -} while (0) -#else /* !CONFIG_PREEMPT_COUNT */ -#define swap_preempt_enable_no_resched() barrier() -#endif /* CONFIG_PREEMPT_COUNT */ - -#else /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */ - -#define swap_preempt_enable_no_resched() preempt_enable_no_resched() - -#endif /* !(defined(MODULE) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) */ - - #if LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0) #define task_job(task) (task->jobctl) #else /* LINUX_VERSION_CODE > KERNEL_VERSION(3, 1, 0) */ -- 2.7.4