kprobes/x86-32: Move irq-exit functions to kprobes section
[pandora-kernel.git] / kernel / kprobes.c
index 0540948..00d01b0 100644 (file)
@@ -90,6 +90,9 @@ static spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
  */
 static struct kprobe_blackpoint kprobe_blacklist[] = {
        {"preempt_schedule",},
+       {"native_get_debugreg",},
+       {"irq_entries_start",},
+       {"common_interrupt",},
        {NULL}    /* Terminator */
 };
 
@@ -103,7 +106,7 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
 #define INSNS_PER_PAGE (PAGE_SIZE/(MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
 
 struct kprobe_insn_page {
-       struct hlist_node hlist;
+       struct list_head list;
        kprobe_opcode_t *insns;         /* Page of instruction slots */
        char slot_used[INSNS_PER_PAGE];
        int nused;
@@ -117,7 +120,7 @@ enum kprobe_slot_state {
 };
 
 static DEFINE_MUTEX(kprobe_insn_mutex);        /* Protects kprobe_insn_pages */
-static struct hlist_head kprobe_insn_pages;
+static LIST_HEAD(kprobe_insn_pages);
 static int kprobe_garbage_slots;
 static int collect_garbage_slots(void);
 
@@ -152,10 +155,9 @@ loop_end:
 static kprobe_opcode_t __kprobes *__get_insn_slot(void)
 {
        struct kprobe_insn_page *kip;
-       struct hlist_node *pos;
 
  retry:
-       hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
+       list_for_each_entry(kip, &kprobe_insn_pages, list) {
                if (kip->nused < INSNS_PER_PAGE) {
                        int i;
                        for (i = 0; i < INSNS_PER_PAGE; i++) {
@@ -189,8 +191,8 @@ static kprobe_opcode_t __kprobes *__get_insn_slot(void)
                kfree(kip);
                return NULL;
        }
-       INIT_HLIST_NODE(&kip->hlist);
-       hlist_add_head(&kip->hlist, &kprobe_insn_pages);
+       INIT_LIST_HEAD(&kip->list);
+       list_add(&kip->list, &kprobe_insn_pages);
        memset(kip->slot_used, SLOT_CLEAN, INSNS_PER_PAGE);
        kip->slot_used[0] = SLOT_USED;
        kip->nused = 1;
@@ -219,12 +221,8 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
                 * 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 {
+               if (!list_is_singular(&kprobe_insn_pages)) {
+                       list_del(&kip->list);
                        module_free(NULL, kip->insns);
                        kfree(kip);
                }
@@ -235,14 +233,13 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
 
 static int __kprobes collect_garbage_slots(void)
 {
-       struct kprobe_insn_page *kip;
-       struct hlist_node *pos, *next;
+       struct kprobe_insn_page *kip, *next;
 
        /* Ensure no-one is preepmted on the garbages */
        if (check_safety())
                return -EAGAIN;
 
-       hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) {
+       list_for_each_entry_safe(kip, next, &kprobe_insn_pages, list) {
                int i;
                if (kip->ngarbage == 0)
                        continue;
@@ -260,19 +257,17 @@ static int __kprobes collect_garbage_slots(void)
 void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
 {
        struct kprobe_insn_page *kip;
-       struct hlist_node *pos;
 
        mutex_lock(&kprobe_insn_mutex);
-       hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
+       list_for_each_entry(kip, &kprobe_insn_pages, list) {
                if (kip->insns <= slot &&
                    slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) {
                        int i = (slot - kip->insns) / MAX_INSN_SIZE;
                        if (dirty) {
                                kip->slot_used[i] = SLOT_DIRTY;
                                kip->ngarbage++;
-                       } else {
+                       } else
                                collect_one_slot(kip, i);
-                       }
                        break;
                }
        }
@@ -1149,6 +1144,13 @@ static void __kprobes kill_kprobe(struct kprobe *p)
        arch_remove_kprobe(p);
 }
 
+void __kprobes dump_kprobe(struct kprobe *kp)
+{
+       printk(KERN_WARNING "Dumping kprobe:\n");
+       printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
+              kp->symbol_name, kp->addr, kp->offset);
+}
+
 /* Module notifier call back, checking kprobes on the module */
 static int __kprobes kprobes_module_callback(struct notifier_block *nb,
                                             unsigned long val, void *data)