[IA64] Manual merge fix for 3 files
[pandora-kernel.git] / arch / x86_64 / kernel / kprobes.c
index 4e680f8..df08c43 100644 (file)
@@ -38,7 +38,7 @@
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/preempt.h>
-#include <linux/moduleloader.h>
+
 #include <asm/cacheflush.h>
 #include <asm/pgtable.h>
 #include <asm/kdebug.h>
@@ -51,8 +51,6 @@ static struct kprobe *kprobe_prev;
 static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev;
 static struct pt_regs jprobe_saved_regs;
 static long *jprobe_saved_rsp;
-static kprobe_opcode_t *get_insn_slot(void);
-static void free_insn_slot(kprobe_opcode_t *slot);
 void jprobe_return_end(void);
 
 /* copy of the kernel stack at the probe fire time */
@@ -76,7 +74,7 @@ static inline int is_IF_modifier(kprobe_opcode_t *insn)
        return 0;
 }
 
-int arch_prepare_kprobe(struct kprobe *p)
+int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
        /* insn: must be on special executable page on x86_64. */
        up(&kprobe_mutex);
@@ -191,7 +189,7 @@ static inline s32 *is_riprel(u8 *insn)
        return NULL;
 }
 
-void arch_copy_kprobe(struct kprobe *p)
+void __kprobes arch_copy_kprobe(struct kprobe *p)
 {
        s32 *ripdisp;
        memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE);
@@ -217,21 +215,21 @@ void arch_copy_kprobe(struct kprobe *p)
        p->opcode = *p->addr;
 }
 
-void arch_arm_kprobe(struct kprobe *p)
+void __kprobes arch_arm_kprobe(struct kprobe *p)
 {
        *p->addr = BREAKPOINT_INSTRUCTION;
        flush_icache_range((unsigned long) p->addr,
                           (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_disarm_kprobe(struct kprobe *p)
+void __kprobes arch_disarm_kprobe(struct kprobe *p)
 {
        *p->addr = p->opcode;
        flush_icache_range((unsigned long) p->addr,
                           (unsigned long) p->addr + sizeof(kprobe_opcode_t));
 }
 
-void arch_remove_kprobe(struct kprobe *p)
+void __kprobes arch_remove_kprobe(struct kprobe *p)
 {
        up(&kprobe_mutex);
        free_insn_slot(p->ainsn.insn);
@@ -263,7 +261,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs)
                kprobe_saved_rflags &= ~IF_MASK;
 }
 
-static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
        regs->eflags |= TF_MASK;
        regs->eflags &= ~IF_MASK;
@@ -274,55 +272,31 @@ static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
                regs->rip = (unsigned long)p->ainsn.insn;
 }
 
-struct task_struct  *arch_get_kprobe_task(void *ptr)
-{
-       return ((struct thread_info *) (((unsigned long) ptr) &
-                                       (~(THREAD_SIZE -1))))->task;
-}
-
-void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
+void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
+                                     struct pt_regs *regs)
 {
        unsigned long *sara = (unsigned long *)regs->rsp;
-       struct kretprobe_instance *ri;
-       static void *orig_ret_addr;
+        struct kretprobe_instance *ri;
+
+        if ((ri = get_free_rp_inst(rp)) != NULL) {
+                ri->rp = rp;
+                ri->task = current;
+               ri->ret_addr = (kprobe_opcode_t *) *sara;
 
-       /*
-        * Save the return address when the return probe hits
-        * the first time, and use it to populate the (krprobe
-        * instance)->ret_addr for subsequent return probes at
-        * the same addrress since stack address would have
-        * the kretprobe_trampoline by then.
-        */
-       if (((void*) *sara) != kretprobe_trampoline)
-               orig_ret_addr = (void*) *sara;
-
-       if ((ri = get_free_rp_inst(rp)) != NULL) {
-               ri->rp = rp;
-               ri->stack_addr = sara;
-               ri->ret_addr = orig_ret_addr;
-               add_rp_inst(ri);
                /* Replace the return addr with trampoline addr */
                *sara = (unsigned long) &kretprobe_trampoline;
-       } else {
-               rp->nmissed++;
-       }
-}
 
-void arch_kprobe_flush_task(struct task_struct *tk)
-{
-       struct kretprobe_instance *ri;
-       while ((ri = get_rp_inst_tsk(tk)) != NULL) {
-               *((unsigned long *)(ri->stack_addr)) =
-                                       (unsigned long) ri->ret_addr;
-               recycle_rp_inst(ri);
-       }
+                add_rp_inst(ri);
+        } else {
+                rp->nmissed++;
+        }
 }
 
 /*
  * Interrupts are disabled on entry as trap3 is an interrupt gate and they
  * remain disabled thorough out this function.
  */
-int kprobe_handler(struct pt_regs *regs)
+int __kprobes kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *p;
        int ret = 0;
@@ -337,7 +311,8 @@ int kprobe_handler(struct pt_regs *regs)
                   Disarm the probe we just hit, and ignore it. */
                p = get_kprobe(addr);
                if (p) {
-                       if (kprobe_status == KPROBE_HIT_SS) {
+                       if (kprobe_status == KPROBE_HIT_SS &&
+                               *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
                                regs->eflags &= ~TF_MASK;
                                regs->eflags |= kprobe_saved_rflags;
                                unlock_kprobes();
@@ -387,7 +362,10 @@ int kprobe_handler(struct pt_regs *regs)
                         * either a probepoint or a debugger breakpoint
                         * at this address.  In either case, no further
                         * handling of this interrupt is appropriate.
+                        * Back up over the (now missing) int3 and run
+                        * the original instruction.
                         */
+                       regs->rip = (unsigned long)addr;
                        ret = 1;
                }
                /* Not one of ours: let kernel handle it */
@@ -426,38 +404,61 @@ no_kprobe:
 /*
  * Called when we hit the probe point at kretprobe_trampoline
  */
-int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 {
-       struct task_struct *tsk;
-       struct kretprobe_instance *ri;
-       struct hlist_head *head;
-       struct hlist_node *node;
-       unsigned long *sara = (unsigned long *)regs->rsp - 1;
-
-       tsk = arch_get_kprobe_task(sara);
-       head = kretprobe_inst_table_head(tsk);
-
-       hlist_for_each_entry(ri, node, head, hlist) {
-               if (ri->stack_addr == sara && ri->rp) {
-                       if (ri->rp->handler)
-                               ri->rp->handler(ri, regs);
-               }
-       }
-       return 0;
-}
+        struct kretprobe_instance *ri = NULL;
+        struct hlist_head *head;
+        struct hlist_node *node, *tmp;
+       unsigned long orig_ret_address = 0;
+       unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline;
 
-void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs,
-                                               unsigned long flags)
-{
-       struct kretprobe_instance *ri;
-       /* RA already popped */
-       unsigned long *sara = ((unsigned long *)regs->rsp) - 1;
+        head = kretprobe_inst_table_head(current);
 
-       while ((ri = get_rp_inst(sara))) {
-               regs->rip = (unsigned long)ri->ret_addr;
+       /*
+        * It is possible to have multiple instances associated with a given
+        * task either because an multiple functions in the call path
+        * have a return probe installed on them, and/or more then one return
+        * return probe was registered for a target function.
+        *
+        * We can handle this because:
+        *     - instances are always inserted at the head of the list
+        *     - when multiple return probes are registered for the same
+         *       function, the first instance's ret_addr will point to the
+        *       real return address, and all the rest will point to
+        *       kretprobe_trampoline
+        */
+       hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
+                if (ri->task != current)
+                       /* another task is sharing our hash bucket */
+                        continue;
+
+               if (ri->rp && ri->rp->handler)
+                       ri->rp->handler(ri, regs);
+
+               orig_ret_address = (unsigned long)ri->ret_addr;
                recycle_rp_inst(ri);
+
+               if (orig_ret_address != trampoline_address)
+                       /*
+                        * This is the real return address. Any other
+                        * instances associated with this task are for
+                        * other calls deeper on the call stack
+                        */
+                       break;
        }
-       regs->eflags &= ~TF_MASK;
+
+       BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
+       regs->rip = orig_ret_address;
+
+       unlock_kprobes();
+       preempt_enable_no_resched();
+
+        /*
+         * By returning a non-zero value, we are telling
+         * kprobe_handler() that we have handled unlocking
+         * and re-enabling preemption.
+         */
+        return 1;
 }
 
 /*
@@ -482,7 +483,7 @@ void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs,
  * that is atop the stack is the address following the copied instruction.
  * We need to make it the address following the original instruction.
  */
-static void resume_execution(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
 {
        unsigned long *tos = (unsigned long *)regs->rsp;
        unsigned long next_rip = 0;
@@ -540,7 +541,7 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
  * remain disabled thoroughout this function.  And we hold kprobe lock.
  */
-int post_kprobe_handler(struct pt_regs *regs)
+int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
        if (!kprobe_running())
                return 0;
@@ -550,8 +551,7 @@ int post_kprobe_handler(struct pt_regs *regs)
                current_kprobe->post_handler(current_kprobe, regs, 0);
        }
 
-       if (current_kprobe->post_handler != trampoline_post_handler)
-               resume_execution(current_kprobe, regs);
+       resume_execution(current_kprobe, regs);
        regs->eflags |= kprobe_saved_rflags;
 
        /* Restore the original saved kprobes variables and continue. */
@@ -576,7 +576,7 @@ out:
 }
 
 /* Interrupts disabled, kprobe_lock held. */
-int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
        if (current_kprobe->fault_handler
            && current_kprobe->fault_handler(current_kprobe, regs, trapnr))
@@ -595,8 +595,8 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 /*
  * Wrapper routine for handling exceptions.
  */
-int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
-                            void *data)
+int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+                                      unsigned long val, void *data)
 {
        struct die_args *args = (struct die_args *)data;
        switch (val) {
@@ -624,7 +624,7 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
        return NOTIFY_DONE;
 }
 
-int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
 {
        struct jprobe *jp = container_of(p, struct jprobe, kp);
        unsigned long addr;
@@ -645,7 +645,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
        return 1;
 }
 
-void jprobe_return(void)
+void __kprobes jprobe_return(void)
 {
        preempt_enable_no_resched();
        asm volatile ("       xchg   %%rbx,%%rsp     \n"
@@ -656,7 +656,7 @@ void jprobe_return(void)
                      (jprobe_saved_rsp):"memory");
 }
 
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
 {
        u8 *addr = (u8 *) (regs->rip - 1);
        unsigned long stack_addr = (unsigned long)jprobe_saved_rsp;
@@ -682,111 +682,12 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
        return 0;
 }
 
-/*
- * kprobe->ainsn.insn points to the copy of the instruction to be single-stepped.
- * By default on x86_64, pages we get from kmalloc or vmalloc are not
- * executable.  Single-stepping an instruction on such a page yields an
- * oops.  So instead of storing the instruction copies in their respective
- * kprobe objects, we allocate a page, map it executable, and store all the
- * instruction copies there.  (We can allocate additional pages if somebody
- * inserts a huge number of probes.)  Each page can hold up to INSNS_PER_PAGE
- * instruction slots, each of which is MAX_INSN_SIZE*sizeof(kprobe_opcode_t)
- * bytes.
- */
-#define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE*sizeof(kprobe_opcode_t)))
-struct kprobe_insn_page {
-       struct hlist_node hlist;
-       kprobe_opcode_t *insns;         /* page of instruction slots */
-       char slot_used[INSNS_PER_PAGE];
-       int nused;
+static struct kprobe trampoline_p = {
+       .addr = (kprobe_opcode_t *) &kretprobe_trampoline,
+       .pre_handler = trampoline_probe_handler
 };
 
-static struct hlist_head kprobe_insn_pages;
-
-/**
- * get_insn_slot() - Find a slot on an executable page for an instruction.
- * We allocate an executable page if there's no room on existing ones.
- */
-static kprobe_opcode_t *get_insn_slot(void)
-{
-       struct kprobe_insn_page *kip;
-       struct hlist_node *pos;
-
-       hlist_for_each(pos, &kprobe_insn_pages) {
-               kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
-               if (kip->nused < INSNS_PER_PAGE) {
-                       int i;
-                       for (i = 0; i < INSNS_PER_PAGE; i++) {
-                               if (!kip->slot_used[i]) {
-                                       kip->slot_used[i] = 1;
-                                       kip->nused++;
-                                       return kip->insns + (i*MAX_INSN_SIZE);
-                               }
-                       }
-                       /* Surprise!  No unused slots.  Fix kip->nused. */
-                       kip->nused = INSNS_PER_PAGE;
-               }
-       }
-
-       /* All out of space.  Need to allocate a new page. Use slot 0.*/
-       kip = kmalloc(sizeof(struct kprobe_insn_page), GFP_KERNEL);
-       if (!kip) {
-               return NULL;
-       }
-
-       /*
-        * For the %rip-relative displacement fixups to be doable, we
-        * need our instruction copy to be within +/- 2GB of any data it
-        * might access via %rip.  That is, within 2GB of where the
-        * kernel image and loaded module images reside.  So we allocate
-        * a page in the module loading area.
-        */
-       kip->insns = module_alloc(PAGE_SIZE);
-       if (!kip->insns) {
-               kfree(kip);
-               return NULL;
-       }
-       INIT_HLIST_NODE(&kip->hlist);
-       hlist_add_head(&kip->hlist, &kprobe_insn_pages);
-       memset(kip->slot_used, 0, INSNS_PER_PAGE);
-       kip->slot_used[0] = 1;
-       kip->nused = 1;
-       return kip->insns;
-}
-
-/**
- * free_insn_slot() - Free instruction slot obtained from get_insn_slot().
- */
-static void free_insn_slot(kprobe_opcode_t *slot)
+int __init arch_init_kprobes(void)
 {
-       struct kprobe_insn_page *kip;
-       struct hlist_node *pos;
-
-       hlist_for_each(pos, &kprobe_insn_pages) {
-               kip = hlist_entry(pos, struct kprobe_insn_page, hlist);
-               if (kip->insns <= slot
-                   && slot < kip->insns+(INSNS_PER_PAGE*MAX_INSN_SIZE)) {
-                       int i = (slot - kip->insns) / MAX_INSN_SIZE;
-                       kip->slot_used[i] = 0;
-                       kip->nused--;
-                       if (kip->nused == 0) {
-                               /*
-                                * Page is no longer in use.  Free it unless
-                                * it's the last one.  We keep the last one
-                                * so as not to have to set it up again the
-                                * next time somebody inserts a probe.
-                                */
-                               hlist_del(&kip->hlist);
-                               if (hlist_empty(&kprobe_insn_pages)) {
-                                       INIT_HLIST_NODE(&kip->hlist);
-                                       hlist_add_head(&kip->hlist,
-                                               &kprobe_insn_pages);
-                               } else {
-                                       module_free(NULL, kip->insns);
-                                       kfree(kip);
-                               }
-                       }
-                       return;
-               }
-       }
+       return register_kprobe(&trampoline_p);
 }