]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/ia64/kernel/kprobes.c
dentries: Extract common code to remove dentry from lru
[linux-2.6-omap-h63xx.git] / arch / ia64 / kernel / kprobes.c
index 5dc98b5abcfbcc3de963e60faaa139d86d362170..b618487cdc858b836cee4adb044579bb5cb716f4 100644 (file)
@@ -40,6 +40,8 @@ extern void jprobe_inst_return(void);
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
+struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
+
 enum instruction_type {A, I, M, F, B, L, X, u};
 static enum instruction_type bundle_encoding[32][3] = {
   { M, I, I },                         /* 00 */
@@ -180,8 +182,8 @@ static int __kprobes unsupported_inst(uint template, uint  slot,
        qp = kprobe_inst & 0x3f;
        if (is_cmp_ctype_unc_inst(template, slot, major_opcode, kprobe_inst)) {
                if (slot == 1 && qp)  {
-                       printk(KERN_WARNING "Kprobes on cmp unc"
-                                       "instruction on slot 1 at <0x%lx>"
+                       printk(KERN_WARNING "Kprobes on cmp unc "
+                                       "instruction on slot 1 at <0x%lx> "
                                        "is not supported\n", addr);
                        return -EINVAL;
 
@@ -219,8 +221,8 @@ static int __kprobes unsupported_inst(uint template, uint  slot,
                         * bit 12 to be equal to 1
                         */
                        if (slot == 1 && qp) {
-                               printk(KERN_WARNING "Kprobes on test bit"
-                                               "instruction on slot at <0x%lx>"
+                               printk(KERN_WARNING "Kprobes on test bit "
+                                               "instruction on slot at <0x%lx> "
                                                "is not supported\n", addr);
                                return -EINVAL;
                        }
@@ -240,7 +242,7 @@ static int __kprobes unsupported_inst(uint template, uint  slot,
                         */
                        int x6=(kprobe_inst >> 27) & 0x3F;
                        if ((x6 == 0x10) || (x6 == 0x11)) {
-                               printk(KERN_WARNING "Kprobes on"
+                               printk(KERN_WARNING "Kprobes on "
                                        "Indirect Predict is not supported\n");
                                return -EINVAL;
                        }
@@ -379,9 +381,10 @@ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        unsigned int i;
-       i = atomic_sub_return(1, &kcb->prev_kprobe_index);
-       __get_cpu_var(current_kprobe) = kcb->prev_kprobe[i].kp;
-       kcb->kprobe_status = kcb->prev_kprobe[i].status;
+       i = atomic_read(&kcb->prev_kprobe_index);
+       __get_cpu_var(current_kprobe) = kcb->prev_kprobe[i-1].kp;
+       kcb->kprobe_status = kcb->prev_kprobe[i-1].status;
+       atomic_sub(1, &kcb->prev_kprobe_index);
 }
 
 static void __kprobes set_current_kprobe(struct kprobe *p,
@@ -428,6 +431,23 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
         *       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;
+
+               orig_ret_address = (unsigned long)ri->ret_addr;
+               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->cr_iip = orig_ret_address;
+
        hlist_for_each_entry_safe(ri, node, tmp, head, hlist) {
                if (ri->task != current)
                        /* another task is sharing our hash bucket */
@@ -450,8 +470,6 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
 
        kretprobe_assert(ri, orig_ret_address, trampoline_address);
 
-       regs->cr_iip = orig_ret_address;
-
        reset_current_kprobe();
        spin_unlock_irqrestore(&kretprobe_lock, flags);
        preempt_enable_no_resched();