static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
unsigned int kprobe_cpu = NR_CPUS;
-static spinlock_t kprobe_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(kprobe_lock);
/* Locks kprobe: irqs must be disabled */
void lock_kprobes(void)
int register_kprobe(struct kprobe *p)
{
int ret = 0;
- unsigned long flags;
+ unsigned long flags = 0;
+ if ((ret = arch_prepare_kprobe(p)) != 0) {
+ goto out;
+ }
spin_lock_irqsave(&kprobe_lock, flags);
INIT_HLIST_NODE(&p->hlist);
if (get_kprobe(p->addr)) {
ret = -EEXIST;
goto out;
}
+ arch_copy_kprobe(p);
+
hlist_add_head(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
- arch_prepare_kprobe(p);
p->opcode = *p->addr;
*p->addr = BREAKPOINT_INSTRUCTION;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
out:
spin_unlock_irqrestore(&kprobe_lock, flags);
+ if (ret == -EEXIST)
+ arch_remove_kprobe(p);
return ret;
}
void unregister_kprobe(struct kprobe *p)
{
unsigned long flags;
+ arch_remove_kprobe(p);
spin_lock_irqsave(&kprobe_lock, flags);
*p->addr = p->opcode;
hlist_del(&p->hlist);