]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/arm64/kernel/probes/kprobes.c
arm64: kprobes: Use arch_populate_kprobe_blacklist()
[linux.git] / arch / arm64 / kernel / probes / kprobes.c
index 7fb6f3aa5ceb7172c91277067da624085b158433..7a679caf45856e75c21860aaa7522c080fb48e41 100644 (file)
@@ -91,8 +91,6 @@ static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)
 int __kprobes arch_prepare_kprobe(struct kprobe *p)
 {
        unsigned long probe_addr = (unsigned long)p->addr;
-       extern char __start_rodata[];
-       extern char __end_rodata[];
 
        if (probe_addr & 0x3)
                return -EINVAL;
@@ -100,10 +98,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        /* copy instruction */
        p->opcode = le32_to_cpu(*p->addr);
 
-       if (in_exception_text(probe_addr))
-               return -EINVAL;
-       if (probe_addr >= (unsigned long) __start_rodata &&
-           probe_addr <= (unsigned long) __end_rodata)
+       if (search_exception_tables(probe_addr))
                return -EINVAL;
 
        /* decode instruction */
@@ -476,26 +471,37 @@ kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)
        return DBG_HOOK_HANDLED;
 }
 
-bool arch_within_kprobe_blacklist(unsigned long addr)
+/*
+ * Provide a blacklist of symbols identifying ranges which cannot be kprobed.
+ * This blacklist is exposed to userspace via debugfs (kprobes/blacklist).
+ */
+int __init arch_populate_kprobe_blacklist(void)
 {
-       if ((addr >= (unsigned long)__kprobes_text_start &&
-           addr < (unsigned long)__kprobes_text_end) ||
-           (addr >= (unsigned long)__entry_text_start &&
-           addr < (unsigned long)__entry_text_end) ||
-           (addr >= (unsigned long)__idmap_text_start &&
-           addr < (unsigned long)__idmap_text_end) ||
-           (addr >= (unsigned long)__hyp_text_start &&
-           addr < (unsigned long)__hyp_text_end) ||
-           !!search_exception_tables(addr))
-               return true;
-
-       if (!is_kernel_in_hyp_mode()) {
-               if ((addr >= (unsigned long)__hyp_idmap_text_start &&
-                   addr < (unsigned long)__hyp_idmap_text_end))
-                       return true;
-       }
-
-       return false;
+       int ret;
+
+       ret = kprobe_add_area_blacklist((unsigned long)__entry_text_start,
+                                       (unsigned long)__entry_text_end);
+       if (ret)
+               return ret;
+       ret = kprobe_add_area_blacklist((unsigned long)__irqentry_text_start,
+                                       (unsigned long)__irqentry_text_end);
+       if (ret)
+               return ret;
+       ret = kprobe_add_area_blacklist((unsigned long)__exception_text_start,
+                                       (unsigned long)__exception_text_end);
+       if (ret)
+               return ret;
+       ret = kprobe_add_area_blacklist((unsigned long)__idmap_text_start,
+                                       (unsigned long)__idmap_text_end);
+       if (ret)
+               return ret;
+       ret = kprobe_add_area_blacklist((unsigned long)__hyp_text_start,
+                                       (unsigned long)__hyp_text_end);
+       if (ret || is_kernel_in_hyp_mode())
+               return ret;
+       ret = kprobe_add_area_blacklist((unsigned long)__hyp_idmap_text_start,
+                                       (unsigned long)__hyp_idmap_text_end);
+       return ret;
 }
 
 void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)