11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * Kernel Probes (KProbes) 41da177e4SLinus Torvalds * kernel/kprobes.c 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Copyright (C) IBM Corporation, 2002, 2004 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel 91da177e4SLinus Torvalds * Probes initial implementation (includes suggestions from 101da177e4SLinus Torvalds * Rusty Russell). 111da177e4SLinus Torvalds * 2004-Aug Updated by Prasanna S Panchamukhi <prasanna@in.ibm.com> with 121da177e4SLinus Torvalds * hlists and exceptions notifier as suggested by Andi Kleen. 131da177e4SLinus Torvalds * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes 141da177e4SLinus Torvalds * interface to access function arguments. 151da177e4SLinus Torvalds * 2004-Sep Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes 161da177e4SLinus Torvalds * exceptions notifier to be first on the priority list. 17b94cce92SHien Nguyen * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston 18b94cce92SHien Nguyen * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi 19b94cce92SHien Nguyen * <prasanna@in.ibm.com> added function-return probes. 201da177e4SLinus Torvalds */ 211da177e4SLinus Torvalds #include <linux/kprobes.h> 221da177e4SLinus Torvalds #include <linux/hash.h> 231da177e4SLinus Torvalds #include <linux/init.h> 244e57b681STim Schmielau #include <linux/slab.h> 25e3869792SRandy Dunlap #include <linux/stddef.h> 269984de1aSPaul Gortmaker #include <linux/export.h> 279ec4b1f3SAnanth N Mavinakayanahalli #include <linux/moduleloader.h> 283a872d89SAnanth N Mavinakayanahalli #include <linux/kallsyms.h> 29b4c6c34aSMasami Hiramatsu #include <linux/freezer.h> 30346fd59bSSrinivasa Ds #include <linux/seq_file.h> 31346fd59bSSrinivasa Ds #include <linux/debugfs.h> 32b2be84dfSMasami Hiramatsu #include <linux/sysctl.h> 331eeb66a1SChristoph Hellwig #include <linux/kdebug.h> 344460fdadSMathieu Desnoyers #include <linux/memory.h> 354554dbcbSMasami Hiramatsu #include <linux/ftrace.h> 36afd66255SMasami Hiramatsu #include <linux/cpu.h> 37bf5438fcSJason Baron #include <linux/jump_label.h> 38bf8f6e5bSAnanth N Mavinakayanahalli 39bfd45be0SChristoph Hellwig #include <asm/sections.h> 401da177e4SLinus Torvalds #include <asm/cacheflush.h> 411da177e4SLinus Torvalds #include <asm/errno.h> 427c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 431da177e4SLinus Torvalds 441da177e4SLinus Torvalds #define KPROBE_HASH_BITS 6 451da177e4SLinus Torvalds #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) 461da177e4SLinus Torvalds 473a872d89SAnanth N Mavinakayanahalli 48ef53d9c5SSrinivasa D S static int kprobes_initialized; 497e6a71d8SMasami Hiramatsu /* kprobe_table can be accessed by 507e6a71d8SMasami Hiramatsu * - Normal hlist traversal and RCU add/del under kprobe_mutex is held. 517e6a71d8SMasami Hiramatsu * Or 527e6a71d8SMasami Hiramatsu * - RCU hlist traversal under disabling preempt (breakpoint handlers) 537e6a71d8SMasami Hiramatsu */ 541da177e4SLinus Torvalds static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; 55b94cce92SHien Nguyen static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; 561da177e4SLinus Torvalds 57bf8f6e5bSAnanth N Mavinakayanahalli /* NOTE: change this value only with kprobe_mutex held */ 58e579abebSMasami Hiramatsu static bool kprobes_all_disarmed; 59bf8f6e5bSAnanth N Mavinakayanahalli 6043948f50SMasami Hiramatsu /* This protects kprobe_table and optimizing_list */ 6143948f50SMasami Hiramatsu static DEFINE_MUTEX(kprobe_mutex); 62e6584523SAnanth N Mavinakayanahalli static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; 63ef53d9c5SSrinivasa D S static struct { 64ec484608SThomas Gleixner raw_spinlock_t lock ____cacheline_aligned_in_smp; 65ef53d9c5SSrinivasa D S } kretprobe_table_locks[KPROBE_TABLE_SIZE]; 66ef53d9c5SSrinivasa D S 67290e3070SNaveen N. Rao kprobe_opcode_t * __weak kprobe_lookup_name(const char *name, 68290e3070SNaveen N. Rao unsigned int __unused) 6949e0b465SNaveen N. Rao { 7049e0b465SNaveen N. Rao return ((kprobe_opcode_t *)(kallsyms_lookup_name(name))); 7149e0b465SNaveen N. Rao } 7249e0b465SNaveen N. Rao 73ec484608SThomas Gleixner static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash) 74ef53d9c5SSrinivasa D S { 75ef53d9c5SSrinivasa D S return &(kretprobe_table_locks[hash].lock); 76ef53d9c5SSrinivasa D S } 771da177e4SLinus Torvalds 78376e2424SMasami Hiramatsu /* Blacklist -- list of struct kprobe_blacklist_entry */ 79376e2424SMasami Hiramatsu static LIST_HEAD(kprobe_blacklist); 803d8d996eSSrinivasa Ds 812d14e39dSAnil S Keshavamurthy #ifdef __ARCH_WANT_KPROBES_INSN_SLOT 829ec4b1f3SAnanth N Mavinakayanahalli /* 839ec4b1f3SAnanth N Mavinakayanahalli * kprobe->ainsn.insn points to the copy of the instruction to be 849ec4b1f3SAnanth N Mavinakayanahalli * single-stepped. x86_64, POWER4 and above have no-exec support and 859ec4b1f3SAnanth N Mavinakayanahalli * stepping on the instruction on a vmalloced/kmalloced/data page 869ec4b1f3SAnanth N Mavinakayanahalli * is a recipe for disaster 879ec4b1f3SAnanth N Mavinakayanahalli */ 889ec4b1f3SAnanth N Mavinakayanahalli struct kprobe_insn_page { 89c5cb5a2dSMasami Hiramatsu struct list_head list; 909ec4b1f3SAnanth N Mavinakayanahalli kprobe_opcode_t *insns; /* Page of instruction slots */ 91af96397dSHeiko Carstens struct kprobe_insn_cache *cache; 929ec4b1f3SAnanth N Mavinakayanahalli int nused; 93b4c6c34aSMasami Hiramatsu int ngarbage; 944610ee1dSMasami Hiramatsu char slot_used[]; 959ec4b1f3SAnanth N Mavinakayanahalli }; 969ec4b1f3SAnanth N Mavinakayanahalli 974610ee1dSMasami Hiramatsu #define KPROBE_INSN_PAGE_SIZE(slots) \ 984610ee1dSMasami Hiramatsu (offsetof(struct kprobe_insn_page, slot_used) + \ 994610ee1dSMasami Hiramatsu (sizeof(char) * (slots))) 1004610ee1dSMasami Hiramatsu 1014610ee1dSMasami Hiramatsu static int slots_per_page(struct kprobe_insn_cache *c) 1024610ee1dSMasami Hiramatsu { 1034610ee1dSMasami Hiramatsu return PAGE_SIZE/(c->insn_size * sizeof(kprobe_opcode_t)); 1044610ee1dSMasami Hiramatsu } 1054610ee1dSMasami Hiramatsu 106ab40c5c6SMasami Hiramatsu enum kprobe_slot_state { 107ab40c5c6SMasami Hiramatsu SLOT_CLEAN = 0, 108ab40c5c6SMasami Hiramatsu SLOT_DIRTY = 1, 109ab40c5c6SMasami Hiramatsu SLOT_USED = 2, 110ab40c5c6SMasami Hiramatsu }; 111ab40c5c6SMasami Hiramatsu 11263fef14fSMasami Hiramatsu void __weak *alloc_insn_page(void) 113af96397dSHeiko Carstens { 114af96397dSHeiko Carstens return module_alloc(PAGE_SIZE); 115af96397dSHeiko Carstens } 116af96397dSHeiko Carstens 117c93f5cf5SMasami Hiramatsu void __weak free_insn_page(void *page) 118af96397dSHeiko Carstens { 119be1f221cSRusty Russell module_memfree(page); 120af96397dSHeiko Carstens } 121af96397dSHeiko Carstens 122c802d64aSHeiko Carstens struct kprobe_insn_cache kprobe_insn_slots = { 123c802d64aSHeiko Carstens .mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex), 124af96397dSHeiko Carstens .alloc = alloc_insn_page, 125af96397dSHeiko Carstens .free = free_insn_page, 1264610ee1dSMasami Hiramatsu .pages = LIST_HEAD_INIT(kprobe_insn_slots.pages), 1274610ee1dSMasami Hiramatsu .insn_size = MAX_INSN_SIZE, 1284610ee1dSMasami Hiramatsu .nr_garbage = 0, 1294610ee1dSMasami Hiramatsu }; 13055479f64SMasami Hiramatsu static int collect_garbage_slots(struct kprobe_insn_cache *c); 131b4c6c34aSMasami Hiramatsu 1329ec4b1f3SAnanth N Mavinakayanahalli /** 13312941560SMasami Hiramatsu * __get_insn_slot() - Find a slot on an executable page for an instruction. 1349ec4b1f3SAnanth N Mavinakayanahalli * We allocate an executable page if there's no room on existing ones. 1359ec4b1f3SAnanth N Mavinakayanahalli */ 13655479f64SMasami Hiramatsu kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c) 1379ec4b1f3SAnanth N Mavinakayanahalli { 1389ec4b1f3SAnanth N Mavinakayanahalli struct kprobe_insn_page *kip; 139c802d64aSHeiko Carstens kprobe_opcode_t *slot = NULL; 1409ec4b1f3SAnanth N Mavinakayanahalli 1415b485629SMasami Hiramatsu /* Since the slot array is not protected by rcu, we need a mutex */ 142c802d64aSHeiko Carstens mutex_lock(&c->mutex); 143b4c6c34aSMasami Hiramatsu retry: 1445b485629SMasami Hiramatsu rcu_read_lock(); 1455b485629SMasami Hiramatsu list_for_each_entry_rcu(kip, &c->pages, list) { 1464610ee1dSMasami Hiramatsu if (kip->nused < slots_per_page(c)) { 1479ec4b1f3SAnanth N Mavinakayanahalli int i; 1484610ee1dSMasami Hiramatsu for (i = 0; i < slots_per_page(c); i++) { 149ab40c5c6SMasami Hiramatsu if (kip->slot_used[i] == SLOT_CLEAN) { 150ab40c5c6SMasami Hiramatsu kip->slot_used[i] = SLOT_USED; 1519ec4b1f3SAnanth N Mavinakayanahalli kip->nused++; 152c802d64aSHeiko Carstens slot = kip->insns + (i * c->insn_size); 1535b485629SMasami Hiramatsu rcu_read_unlock(); 154c802d64aSHeiko Carstens goto out; 1559ec4b1f3SAnanth N Mavinakayanahalli } 1569ec4b1f3SAnanth N Mavinakayanahalli } 1574610ee1dSMasami Hiramatsu /* kip->nused is broken. Fix it. */ 1584610ee1dSMasami Hiramatsu kip->nused = slots_per_page(c); 1594610ee1dSMasami Hiramatsu WARN_ON(1); 1609ec4b1f3SAnanth N Mavinakayanahalli } 1619ec4b1f3SAnanth N Mavinakayanahalli } 1625b485629SMasami Hiramatsu rcu_read_unlock(); 1639ec4b1f3SAnanth N Mavinakayanahalli 164b4c6c34aSMasami Hiramatsu /* If there are any garbage slots, collect it and try again. */ 1654610ee1dSMasami Hiramatsu if (c->nr_garbage && collect_garbage_slots(c) == 0) 166b4c6c34aSMasami Hiramatsu goto retry; 1674610ee1dSMasami Hiramatsu 1684610ee1dSMasami Hiramatsu /* All out of space. Need to allocate a new page. */ 1694610ee1dSMasami Hiramatsu kip = kmalloc(KPROBE_INSN_PAGE_SIZE(slots_per_page(c)), GFP_KERNEL); 1706f716acdSChristoph Hellwig if (!kip) 171c802d64aSHeiko Carstens goto out; 1729ec4b1f3SAnanth N Mavinakayanahalli 1739ec4b1f3SAnanth N Mavinakayanahalli /* 1749ec4b1f3SAnanth N Mavinakayanahalli * Use module_alloc so this page is within +/- 2GB of where the 1759ec4b1f3SAnanth N Mavinakayanahalli * kernel image and loaded module images reside. This is required 1769ec4b1f3SAnanth N Mavinakayanahalli * so x86_64 can correctly handle the %rip-relative fixups. 1779ec4b1f3SAnanth N Mavinakayanahalli */ 178af96397dSHeiko Carstens kip->insns = c->alloc(); 1799ec4b1f3SAnanth N Mavinakayanahalli if (!kip->insns) { 1809ec4b1f3SAnanth N Mavinakayanahalli kfree(kip); 181c802d64aSHeiko Carstens goto out; 1829ec4b1f3SAnanth N Mavinakayanahalli } 183c5cb5a2dSMasami Hiramatsu INIT_LIST_HEAD(&kip->list); 1844610ee1dSMasami Hiramatsu memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c)); 185ab40c5c6SMasami Hiramatsu kip->slot_used[0] = SLOT_USED; 1869ec4b1f3SAnanth N Mavinakayanahalli kip->nused = 1; 187b4c6c34aSMasami Hiramatsu kip->ngarbage = 0; 188af96397dSHeiko Carstens kip->cache = c; 1895b485629SMasami Hiramatsu list_add_rcu(&kip->list, &c->pages); 190c802d64aSHeiko Carstens slot = kip->insns; 191c802d64aSHeiko Carstens out: 192c802d64aSHeiko Carstens mutex_unlock(&c->mutex); 193c802d64aSHeiko Carstens return slot; 19412941560SMasami Hiramatsu } 19512941560SMasami Hiramatsu 196b4c6c34aSMasami Hiramatsu /* Return 1 if all garbages are collected, otherwise 0. */ 19755479f64SMasami Hiramatsu static int collect_one_slot(struct kprobe_insn_page *kip, int idx) 1989ec4b1f3SAnanth N Mavinakayanahalli { 199ab40c5c6SMasami Hiramatsu kip->slot_used[idx] = SLOT_CLEAN; 2009ec4b1f3SAnanth N Mavinakayanahalli kip->nused--; 2019ec4b1f3SAnanth N Mavinakayanahalli if (kip->nused == 0) { 2029ec4b1f3SAnanth N Mavinakayanahalli /* 2039ec4b1f3SAnanth N Mavinakayanahalli * Page is no longer in use. Free it unless 2049ec4b1f3SAnanth N Mavinakayanahalli * it's the last one. We keep the last one 2059ec4b1f3SAnanth N Mavinakayanahalli * so as not to have to set it up again the 2069ec4b1f3SAnanth N Mavinakayanahalli * next time somebody inserts a probe. 2079ec4b1f3SAnanth N Mavinakayanahalli */ 2084610ee1dSMasami Hiramatsu if (!list_is_singular(&kip->list)) { 2095b485629SMasami Hiramatsu list_del_rcu(&kip->list); 2105b485629SMasami Hiramatsu synchronize_rcu(); 211af96397dSHeiko Carstens kip->cache->free(kip->insns); 2129ec4b1f3SAnanth N Mavinakayanahalli kfree(kip); 2139ec4b1f3SAnanth N Mavinakayanahalli } 214b4c6c34aSMasami Hiramatsu return 1; 2159ec4b1f3SAnanth N Mavinakayanahalli } 216b4c6c34aSMasami Hiramatsu return 0; 2179ec4b1f3SAnanth N Mavinakayanahalli } 218b4c6c34aSMasami Hiramatsu 21955479f64SMasami Hiramatsu static int collect_garbage_slots(struct kprobe_insn_cache *c) 220b4c6c34aSMasami Hiramatsu { 221c5cb5a2dSMasami Hiramatsu struct kprobe_insn_page *kip, *next; 222b4c6c34aSMasami Hiramatsu 223615d0ebbSMasami Hiramatsu /* Ensure no-one is interrupted on the garbages */ 224ae8b7ce7SPaul E. McKenney synchronize_rcu(); 225b4c6c34aSMasami Hiramatsu 2264610ee1dSMasami Hiramatsu list_for_each_entry_safe(kip, next, &c->pages, list) { 227b4c6c34aSMasami Hiramatsu int i; 228b4c6c34aSMasami Hiramatsu if (kip->ngarbage == 0) 229b4c6c34aSMasami Hiramatsu continue; 230b4c6c34aSMasami Hiramatsu kip->ngarbage = 0; /* we will collect all garbages */ 2314610ee1dSMasami Hiramatsu for (i = 0; i < slots_per_page(c); i++) { 2325b485629SMasami Hiramatsu if (kip->slot_used[i] == SLOT_DIRTY && collect_one_slot(kip, i)) 233b4c6c34aSMasami Hiramatsu break; 234b4c6c34aSMasami Hiramatsu } 235b4c6c34aSMasami Hiramatsu } 2364610ee1dSMasami Hiramatsu c->nr_garbage = 0; 237b4c6c34aSMasami Hiramatsu return 0; 238b4c6c34aSMasami Hiramatsu } 239b4c6c34aSMasami Hiramatsu 24055479f64SMasami Hiramatsu void __free_insn_slot(struct kprobe_insn_cache *c, 2414610ee1dSMasami Hiramatsu kprobe_opcode_t *slot, int dirty) 2424610ee1dSMasami Hiramatsu { 2434610ee1dSMasami Hiramatsu struct kprobe_insn_page *kip; 2445b485629SMasami Hiramatsu long idx; 2454610ee1dSMasami Hiramatsu 246c802d64aSHeiko Carstens mutex_lock(&c->mutex); 2475b485629SMasami Hiramatsu rcu_read_lock(); 2485b485629SMasami Hiramatsu list_for_each_entry_rcu(kip, &c->pages, list) { 2495b485629SMasami Hiramatsu idx = ((long)slot - (long)kip->insns) / 25083ff56f4SMasami Hiramatsu (c->insn_size * sizeof(kprobe_opcode_t)); 2515b485629SMasami Hiramatsu if (idx >= 0 && idx < slots_per_page(c)) 2525b485629SMasami Hiramatsu goto out; 2535b485629SMasami Hiramatsu } 2545b485629SMasami Hiramatsu /* Could not find this slot. */ 2555b485629SMasami Hiramatsu WARN_ON(1); 2565b485629SMasami Hiramatsu kip = NULL; 2575b485629SMasami Hiramatsu out: 2585b485629SMasami Hiramatsu rcu_read_unlock(); 2595b485629SMasami Hiramatsu /* Mark and sweep: this may sleep */ 2605b485629SMasami Hiramatsu if (kip) { 2615b485629SMasami Hiramatsu /* Check double free */ 2624610ee1dSMasami Hiramatsu WARN_ON(kip->slot_used[idx] != SLOT_USED); 2634610ee1dSMasami Hiramatsu if (dirty) { 2644610ee1dSMasami Hiramatsu kip->slot_used[idx] = SLOT_DIRTY; 2654610ee1dSMasami Hiramatsu kip->ngarbage++; 2664610ee1dSMasami Hiramatsu if (++c->nr_garbage > slots_per_page(c)) 2674610ee1dSMasami Hiramatsu collect_garbage_slots(c); 2685b485629SMasami Hiramatsu } else { 2694610ee1dSMasami Hiramatsu collect_one_slot(kip, idx); 2704610ee1dSMasami Hiramatsu } 2714610ee1dSMasami Hiramatsu } 272c802d64aSHeiko Carstens mutex_unlock(&c->mutex); 2734610ee1dSMasami Hiramatsu } 2744610ee1dSMasami Hiramatsu 2755b485629SMasami Hiramatsu /* 2765b485629SMasami Hiramatsu * Check given address is on the page of kprobe instruction slots. 2775b485629SMasami Hiramatsu * This will be used for checking whether the address on a stack 2785b485629SMasami Hiramatsu * is on a text area or not. 2795b485629SMasami Hiramatsu */ 2805b485629SMasami Hiramatsu bool __is_insn_slot_addr(struct kprobe_insn_cache *c, unsigned long addr) 2815b485629SMasami Hiramatsu { 2825b485629SMasami Hiramatsu struct kprobe_insn_page *kip; 2835b485629SMasami Hiramatsu bool ret = false; 2845b485629SMasami Hiramatsu 2855b485629SMasami Hiramatsu rcu_read_lock(); 2865b485629SMasami Hiramatsu list_for_each_entry_rcu(kip, &c->pages, list) { 2875b485629SMasami Hiramatsu if (addr >= (unsigned long)kip->insns && 2885b485629SMasami Hiramatsu addr < (unsigned long)kip->insns + PAGE_SIZE) { 2895b485629SMasami Hiramatsu ret = true; 2905b485629SMasami Hiramatsu break; 2915b485629SMasami Hiramatsu } 2925b485629SMasami Hiramatsu } 2935b485629SMasami Hiramatsu rcu_read_unlock(); 2945b485629SMasami Hiramatsu 2955b485629SMasami Hiramatsu return ret; 2965b485629SMasami Hiramatsu } 2975b485629SMasami Hiramatsu 298afd66255SMasami Hiramatsu #ifdef CONFIG_OPTPROBES 299afd66255SMasami Hiramatsu /* For optimized_kprobe buffer */ 300c802d64aSHeiko Carstens struct kprobe_insn_cache kprobe_optinsn_slots = { 301c802d64aSHeiko Carstens .mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex), 302af96397dSHeiko Carstens .alloc = alloc_insn_page, 303af96397dSHeiko Carstens .free = free_insn_page, 304afd66255SMasami Hiramatsu .pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages), 305afd66255SMasami Hiramatsu /* .insn_size is initialized later */ 306afd66255SMasami Hiramatsu .nr_garbage = 0, 307afd66255SMasami Hiramatsu }; 308afd66255SMasami Hiramatsu #endif 3092d14e39dSAnil S Keshavamurthy #endif 3109ec4b1f3SAnanth N Mavinakayanahalli 311e6584523SAnanth N Mavinakayanahalli /* We have preemption disabled.. so it is safe to use __ versions */ 312e6584523SAnanth N Mavinakayanahalli static inline void set_kprobe_instance(struct kprobe *kp) 313e6584523SAnanth N Mavinakayanahalli { 314b76834bcSChristoph Lameter __this_cpu_write(kprobe_instance, kp); 315e6584523SAnanth N Mavinakayanahalli } 316e6584523SAnanth N Mavinakayanahalli 317e6584523SAnanth N Mavinakayanahalli static inline void reset_kprobe_instance(void) 318e6584523SAnanth N Mavinakayanahalli { 319b76834bcSChristoph Lameter __this_cpu_write(kprobe_instance, NULL); 320e6584523SAnanth N Mavinakayanahalli } 321e6584523SAnanth N Mavinakayanahalli 3223516a460SAnanth N Mavinakayanahalli /* 3233516a460SAnanth N Mavinakayanahalli * This routine is called either: 32449a2a1b8SAnil S Keshavamurthy * - under the kprobe_mutex - during kprobe_[un]register() 3253516a460SAnanth N Mavinakayanahalli * OR 326d217d545SAnanth N Mavinakayanahalli * - with preemption disabled - from arch/xxx/kernel/kprobes.c 3273516a460SAnanth N Mavinakayanahalli */ 328820aede0SMasami Hiramatsu struct kprobe *get_kprobe(void *addr) 3291da177e4SLinus Torvalds { 3301da177e4SLinus Torvalds struct hlist_head *head; 3313516a460SAnanth N Mavinakayanahalli struct kprobe *p; 3321da177e4SLinus Torvalds 3331da177e4SLinus Torvalds head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)]; 3346743ad43SMasami Hiramatsu hlist_for_each_entry_rcu(p, head, hlist, 3356743ad43SMasami Hiramatsu lockdep_is_held(&kprobe_mutex)) { 3361da177e4SLinus Torvalds if (p->addr == addr) 3371da177e4SLinus Torvalds return p; 3381da177e4SLinus Torvalds } 339afd66255SMasami Hiramatsu 3401da177e4SLinus Torvalds return NULL; 3411da177e4SLinus Torvalds } 342820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(get_kprobe); 3431da177e4SLinus Torvalds 344820aede0SMasami Hiramatsu static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs); 345afd66255SMasami Hiramatsu 346afd66255SMasami Hiramatsu /* Return true if the kprobe is an aggregator */ 347afd66255SMasami Hiramatsu static inline int kprobe_aggrprobe(struct kprobe *p) 348afd66255SMasami Hiramatsu { 349afd66255SMasami Hiramatsu return p->pre_handler == aggr_pre_handler; 350afd66255SMasami Hiramatsu } 351afd66255SMasami Hiramatsu 3526274de49SMasami Hiramatsu /* Return true(!0) if the kprobe is unused */ 3536274de49SMasami Hiramatsu static inline int kprobe_unused(struct kprobe *p) 3546274de49SMasami Hiramatsu { 3556274de49SMasami Hiramatsu return kprobe_aggrprobe(p) && kprobe_disabled(p) && 3566274de49SMasami Hiramatsu list_empty(&p->list); 3576274de49SMasami Hiramatsu } 3586274de49SMasami Hiramatsu 359afd66255SMasami Hiramatsu /* 360afd66255SMasami Hiramatsu * Keep all fields in the kprobe consistent 361afd66255SMasami Hiramatsu */ 3626d8e40a8SMasami Hiramatsu static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p) 363afd66255SMasami Hiramatsu { 3646d8e40a8SMasami Hiramatsu memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t)); 3656d8e40a8SMasami Hiramatsu memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn)); 366afd66255SMasami Hiramatsu } 367afd66255SMasami Hiramatsu 368afd66255SMasami Hiramatsu #ifdef CONFIG_OPTPROBES 369b2be84dfSMasami Hiramatsu /* NOTE: change this value only with kprobe_mutex held */ 370b2be84dfSMasami Hiramatsu static bool kprobes_allow_optimization; 371b2be84dfSMasami Hiramatsu 372afd66255SMasami Hiramatsu /* 373afd66255SMasami Hiramatsu * Call all pre_handler on the list, but ignores its return value. 374afd66255SMasami Hiramatsu * This must be called from arch-dep optimized caller. 375afd66255SMasami Hiramatsu */ 376820aede0SMasami Hiramatsu void opt_pre_handler(struct kprobe *p, struct pt_regs *regs) 377afd66255SMasami Hiramatsu { 378afd66255SMasami Hiramatsu struct kprobe *kp; 379afd66255SMasami Hiramatsu 380afd66255SMasami Hiramatsu list_for_each_entry_rcu(kp, &p->list, list) { 381afd66255SMasami Hiramatsu if (kp->pre_handler && likely(!kprobe_disabled(kp))) { 382afd66255SMasami Hiramatsu set_kprobe_instance(kp); 3834f3a8714SNaveen N. Rao kp->pre_handler(kp, regs); 384afd66255SMasami Hiramatsu } 385afd66255SMasami Hiramatsu reset_kprobe_instance(); 386afd66255SMasami Hiramatsu } 387afd66255SMasami Hiramatsu } 388820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(opt_pre_handler); 389afd66255SMasami Hiramatsu 3906274de49SMasami Hiramatsu /* Free optimized instructions and optimized_kprobe */ 39155479f64SMasami Hiramatsu static void free_aggr_kprobe(struct kprobe *p) 3926274de49SMasami Hiramatsu { 3936274de49SMasami Hiramatsu struct optimized_kprobe *op; 3946274de49SMasami Hiramatsu 3956274de49SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 3966274de49SMasami Hiramatsu arch_remove_optimized_kprobe(op); 3976274de49SMasami Hiramatsu arch_remove_kprobe(p); 3986274de49SMasami Hiramatsu kfree(op); 3996274de49SMasami Hiramatsu } 4006274de49SMasami Hiramatsu 401afd66255SMasami Hiramatsu /* Return true(!0) if the kprobe is ready for optimization. */ 402afd66255SMasami Hiramatsu static inline int kprobe_optready(struct kprobe *p) 403afd66255SMasami Hiramatsu { 404afd66255SMasami Hiramatsu struct optimized_kprobe *op; 405afd66255SMasami Hiramatsu 406afd66255SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 407afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 408afd66255SMasami Hiramatsu return arch_prepared_optinsn(&op->optinsn); 409afd66255SMasami Hiramatsu } 410afd66255SMasami Hiramatsu 411afd66255SMasami Hiramatsu return 0; 412afd66255SMasami Hiramatsu } 413afd66255SMasami Hiramatsu 4146274de49SMasami Hiramatsu /* Return true(!0) if the kprobe is disarmed. Note: p must be on hash list */ 4156274de49SMasami Hiramatsu static inline int kprobe_disarmed(struct kprobe *p) 4166274de49SMasami Hiramatsu { 4176274de49SMasami Hiramatsu struct optimized_kprobe *op; 4186274de49SMasami Hiramatsu 4196274de49SMasami Hiramatsu /* If kprobe is not aggr/opt probe, just return kprobe is disabled */ 4206274de49SMasami Hiramatsu if (!kprobe_aggrprobe(p)) 4216274de49SMasami Hiramatsu return kprobe_disabled(p); 4226274de49SMasami Hiramatsu 4236274de49SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 4246274de49SMasami Hiramatsu 4256274de49SMasami Hiramatsu return kprobe_disabled(p) && list_empty(&op->list); 4266274de49SMasami Hiramatsu } 4276274de49SMasami Hiramatsu 4286274de49SMasami Hiramatsu /* Return true(!0) if the probe is queued on (un)optimizing lists */ 42955479f64SMasami Hiramatsu static int kprobe_queued(struct kprobe *p) 4306274de49SMasami Hiramatsu { 4316274de49SMasami Hiramatsu struct optimized_kprobe *op; 4326274de49SMasami Hiramatsu 4336274de49SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 4346274de49SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 4356274de49SMasami Hiramatsu if (!list_empty(&op->list)) 4366274de49SMasami Hiramatsu return 1; 4376274de49SMasami Hiramatsu } 4386274de49SMasami Hiramatsu return 0; 4396274de49SMasami Hiramatsu } 4406274de49SMasami Hiramatsu 441afd66255SMasami Hiramatsu /* 442afd66255SMasami Hiramatsu * Return an optimized kprobe whose optimizing code replaces 443afd66255SMasami Hiramatsu * instructions including addr (exclude breakpoint). 444afd66255SMasami Hiramatsu */ 44555479f64SMasami Hiramatsu static struct kprobe *get_optimized_kprobe(unsigned long addr) 446afd66255SMasami Hiramatsu { 447afd66255SMasami Hiramatsu int i; 448afd66255SMasami Hiramatsu struct kprobe *p = NULL; 449afd66255SMasami Hiramatsu struct optimized_kprobe *op; 450afd66255SMasami Hiramatsu 451afd66255SMasami Hiramatsu /* Don't check i == 0, since that is a breakpoint case. */ 452afd66255SMasami Hiramatsu for (i = 1; !p && i < MAX_OPTIMIZED_LENGTH; i++) 453afd66255SMasami Hiramatsu p = get_kprobe((void *)(addr - i)); 454afd66255SMasami Hiramatsu 455afd66255SMasami Hiramatsu if (p && kprobe_optready(p)) { 456afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 457afd66255SMasami Hiramatsu if (arch_within_optimized_kprobe(op, addr)) 458afd66255SMasami Hiramatsu return p; 459afd66255SMasami Hiramatsu } 460afd66255SMasami Hiramatsu 461afd66255SMasami Hiramatsu return NULL; 462afd66255SMasami Hiramatsu } 463afd66255SMasami Hiramatsu 464afd66255SMasami Hiramatsu /* Optimization staging list, protected by kprobe_mutex */ 465afd66255SMasami Hiramatsu static LIST_HEAD(optimizing_list); 4666274de49SMasami Hiramatsu static LIST_HEAD(unoptimizing_list); 4677b959fc5SMasami Hiramatsu static LIST_HEAD(freeing_list); 468afd66255SMasami Hiramatsu 469afd66255SMasami Hiramatsu static void kprobe_optimizer(struct work_struct *work); 470afd66255SMasami Hiramatsu static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); 471afd66255SMasami Hiramatsu #define OPTIMIZE_DELAY 5 472afd66255SMasami Hiramatsu 47361f4e13fSMasami Hiramatsu /* 47461f4e13fSMasami Hiramatsu * Optimize (replace a breakpoint with a jump) kprobes listed on 47561f4e13fSMasami Hiramatsu * optimizing_list. 47661f4e13fSMasami Hiramatsu */ 47755479f64SMasami Hiramatsu static void do_optimize_kprobes(void) 478afd66255SMasami Hiramatsu { 479f1c6ece2SAndrea Righi lockdep_assert_held(&text_mutex); 480afd66255SMasami Hiramatsu /* 481afd66255SMasami Hiramatsu * The optimization/unoptimization refers online_cpus via 482afd66255SMasami Hiramatsu * stop_machine() and cpu-hotplug modifies online_cpus. 483afd66255SMasami Hiramatsu * And same time, text_mutex will be held in cpu-hotplug and here. 484afd66255SMasami Hiramatsu * This combination can cause a deadlock (cpu-hotplug try to lock 485afd66255SMasami Hiramatsu * text_mutex but stop_machine can not be done because online_cpus 486afd66255SMasami Hiramatsu * has been changed) 4872d1e38f5SThomas Gleixner * To avoid this deadlock, caller must have locked cpu hotplug 488afd66255SMasami Hiramatsu * for preventing cpu-hotplug outside of text_mutex locking. 489afd66255SMasami Hiramatsu */ 4902d1e38f5SThomas Gleixner lockdep_assert_cpus_held(); 4912d1e38f5SThomas Gleixner 4922d1e38f5SThomas Gleixner /* Optimization never be done when disarmed */ 4932d1e38f5SThomas Gleixner if (kprobes_all_disarmed || !kprobes_allow_optimization || 4942d1e38f5SThomas Gleixner list_empty(&optimizing_list)) 4952d1e38f5SThomas Gleixner return; 4962d1e38f5SThomas Gleixner 497cd7ebe22SMasami Hiramatsu arch_optimize_kprobes(&optimizing_list); 49861f4e13fSMasami Hiramatsu } 49961f4e13fSMasami Hiramatsu 5006274de49SMasami Hiramatsu /* 5016274de49SMasami Hiramatsu * Unoptimize (replace a jump with a breakpoint and remove the breakpoint 5026274de49SMasami Hiramatsu * if need) kprobes listed on unoptimizing_list. 5036274de49SMasami Hiramatsu */ 50455479f64SMasami Hiramatsu static void do_unoptimize_kprobes(void) 5056274de49SMasami Hiramatsu { 5066274de49SMasami Hiramatsu struct optimized_kprobe *op, *tmp; 5076274de49SMasami Hiramatsu 508f1c6ece2SAndrea Righi lockdep_assert_held(&text_mutex); 5092d1e38f5SThomas Gleixner /* See comment in do_optimize_kprobes() */ 5102d1e38f5SThomas Gleixner lockdep_assert_cpus_held(); 5112d1e38f5SThomas Gleixner 5126274de49SMasami Hiramatsu /* Unoptimization must be done anytime */ 5136274de49SMasami Hiramatsu if (list_empty(&unoptimizing_list)) 5146274de49SMasami Hiramatsu return; 5156274de49SMasami Hiramatsu 5167b959fc5SMasami Hiramatsu arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); 517f984ba4eSMasami Hiramatsu /* Loop free_list for disarming */ 5187b959fc5SMasami Hiramatsu list_for_each_entry_safe(op, tmp, &freeing_list, list) { 519f66c0447SMasami Hiramatsu /* Switching from detour code to origin */ 520f66c0447SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 5216274de49SMasami Hiramatsu /* Disarm probes if marked disabled */ 5226274de49SMasami Hiramatsu if (kprobe_disabled(&op->kp)) 5236274de49SMasami Hiramatsu arch_disarm_kprobe(&op->kp); 5246274de49SMasami Hiramatsu if (kprobe_unused(&op->kp)) { 5256274de49SMasami Hiramatsu /* 5266274de49SMasami Hiramatsu * Remove unused probes from hash list. After waiting 5276274de49SMasami Hiramatsu * for synchronization, these probes are reclaimed. 5286274de49SMasami Hiramatsu * (reclaiming is done by do_free_cleaned_kprobes.) 5296274de49SMasami Hiramatsu */ 5306274de49SMasami Hiramatsu hlist_del_rcu(&op->kp.hlist); 5316274de49SMasami Hiramatsu } else 5326274de49SMasami Hiramatsu list_del_init(&op->list); 5336274de49SMasami Hiramatsu } 5346274de49SMasami Hiramatsu } 5356274de49SMasami Hiramatsu 5366274de49SMasami Hiramatsu /* Reclaim all kprobes on the free_list */ 53755479f64SMasami Hiramatsu static void do_free_cleaned_kprobes(void) 5386274de49SMasami Hiramatsu { 5396274de49SMasami Hiramatsu struct optimized_kprobe *op, *tmp; 5406274de49SMasami Hiramatsu 5417b959fc5SMasami Hiramatsu list_for_each_entry_safe(op, tmp, &freeing_list, list) { 5426274de49SMasami Hiramatsu list_del_init(&op->list); 543cbdd96f5SMasami Hiramatsu if (WARN_ON_ONCE(!kprobe_unused(&op->kp))) { 544cbdd96f5SMasami Hiramatsu /* 545cbdd96f5SMasami Hiramatsu * This must not happen, but if there is a kprobe 546cbdd96f5SMasami Hiramatsu * still in use, keep it on kprobes hash list. 547cbdd96f5SMasami Hiramatsu */ 548cbdd96f5SMasami Hiramatsu continue; 549cbdd96f5SMasami Hiramatsu } 5506274de49SMasami Hiramatsu free_aggr_kprobe(&op->kp); 5516274de49SMasami Hiramatsu } 5526274de49SMasami Hiramatsu } 5536274de49SMasami Hiramatsu 5546274de49SMasami Hiramatsu /* Start optimizer after OPTIMIZE_DELAY passed */ 55555479f64SMasami Hiramatsu static void kick_kprobe_optimizer(void) 5566274de49SMasami Hiramatsu { 5576274de49SMasami Hiramatsu schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY); 5586274de49SMasami Hiramatsu } 5596274de49SMasami Hiramatsu 56061f4e13fSMasami Hiramatsu /* Kprobe jump optimizer */ 56155479f64SMasami Hiramatsu static void kprobe_optimizer(struct work_struct *work) 56261f4e13fSMasami Hiramatsu { 56372ef3794SSteven Rostedt mutex_lock(&kprobe_mutex); 5642d1e38f5SThomas Gleixner cpus_read_lock(); 565f1c6ece2SAndrea Righi mutex_lock(&text_mutex); 56661f4e13fSMasami Hiramatsu /* Lock modules while optimizing kprobes */ 56761f4e13fSMasami Hiramatsu mutex_lock(&module_mutex); 56861f4e13fSMasami Hiramatsu 56961f4e13fSMasami Hiramatsu /* 5706274de49SMasami Hiramatsu * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed) 5716274de49SMasami Hiramatsu * kprobes before waiting for quiesence period. 5726274de49SMasami Hiramatsu */ 5737b959fc5SMasami Hiramatsu do_unoptimize_kprobes(); 5746274de49SMasami Hiramatsu 5756274de49SMasami Hiramatsu /* 576a30b85dfSMasami Hiramatsu * Step 2: Wait for quiesence period to ensure all potentially 577a30b85dfSMasami Hiramatsu * preempted tasks to have normally scheduled. Because optprobe 578a30b85dfSMasami Hiramatsu * may modify multiple instructions, there is a chance that Nth 579a30b85dfSMasami Hiramatsu * instruction is preempted. In that case, such tasks can return 580a30b85dfSMasami Hiramatsu * to 2nd-Nth byte of jump instruction. This wait is for avoiding it. 581a30b85dfSMasami Hiramatsu * Note that on non-preemptive kernel, this is transparently converted 582a30b85dfSMasami Hiramatsu * to synchronoze_sched() to wait for all interrupts to have completed. 58361f4e13fSMasami Hiramatsu */ 584a30b85dfSMasami Hiramatsu synchronize_rcu_tasks(); 58561f4e13fSMasami Hiramatsu 5866274de49SMasami Hiramatsu /* Step 3: Optimize kprobes after quiesence period */ 58761f4e13fSMasami Hiramatsu do_optimize_kprobes(); 5886274de49SMasami Hiramatsu 5896274de49SMasami Hiramatsu /* Step 4: Free cleaned kprobes after quiesence period */ 5907b959fc5SMasami Hiramatsu do_free_cleaned_kprobes(); 5916274de49SMasami Hiramatsu 592afd66255SMasami Hiramatsu mutex_unlock(&module_mutex); 593f1c6ece2SAndrea Righi mutex_unlock(&text_mutex); 5942d1e38f5SThomas Gleixner cpus_read_unlock(); 5956274de49SMasami Hiramatsu 596cd7ebe22SMasami Hiramatsu /* Step 5: Kick optimizer again if needed */ 597f984ba4eSMasami Hiramatsu if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) 598cd7ebe22SMasami Hiramatsu kick_kprobe_optimizer(); 599*1a0aa991SMasami Hiramatsu 600*1a0aa991SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 6016274de49SMasami Hiramatsu } 6026274de49SMasami Hiramatsu 6036274de49SMasami Hiramatsu /* Wait for completing optimization and unoptimization */ 60430e7d894SThomas Gleixner void wait_for_kprobe_optimizer(void) 6056274de49SMasami Hiramatsu { 606ad72b3beSTejun Heo mutex_lock(&kprobe_mutex); 607ad72b3beSTejun Heo 608ad72b3beSTejun Heo while (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) { 609ad72b3beSTejun Heo mutex_unlock(&kprobe_mutex); 610ad72b3beSTejun Heo 611ad72b3beSTejun Heo /* this will also make optimizing_work execute immmediately */ 612ad72b3beSTejun Heo flush_delayed_work(&optimizing_work); 613ad72b3beSTejun Heo /* @optimizing_work might not have been queued yet, relax */ 614ad72b3beSTejun Heo cpu_relax(); 615ad72b3beSTejun Heo 616ad72b3beSTejun Heo mutex_lock(&kprobe_mutex); 617ad72b3beSTejun Heo } 618ad72b3beSTejun Heo 619ad72b3beSTejun Heo mutex_unlock(&kprobe_mutex); 620afd66255SMasami Hiramatsu } 621afd66255SMasami Hiramatsu 622e4add247SMasami Hiramatsu static bool optprobe_queued_unopt(struct optimized_kprobe *op) 623e4add247SMasami Hiramatsu { 624e4add247SMasami Hiramatsu struct optimized_kprobe *_op; 625e4add247SMasami Hiramatsu 626e4add247SMasami Hiramatsu list_for_each_entry(_op, &unoptimizing_list, list) { 627e4add247SMasami Hiramatsu if (op == _op) 628e4add247SMasami Hiramatsu return true; 629e4add247SMasami Hiramatsu } 630e4add247SMasami Hiramatsu 631e4add247SMasami Hiramatsu return false; 632e4add247SMasami Hiramatsu } 633e4add247SMasami Hiramatsu 634afd66255SMasami Hiramatsu /* Optimize kprobe if p is ready to be optimized */ 63555479f64SMasami Hiramatsu static void optimize_kprobe(struct kprobe *p) 636afd66255SMasami Hiramatsu { 637afd66255SMasami Hiramatsu struct optimized_kprobe *op; 638afd66255SMasami Hiramatsu 639afd66255SMasami Hiramatsu /* Check if the kprobe is disabled or not ready for optimization. */ 640b2be84dfSMasami Hiramatsu if (!kprobe_optready(p) || !kprobes_allow_optimization || 641afd66255SMasami Hiramatsu (kprobe_disabled(p) || kprobes_all_disarmed)) 642afd66255SMasami Hiramatsu return; 643afd66255SMasami Hiramatsu 644059053a2SMasami Hiramatsu /* kprobes with post_handler can not be optimized */ 645059053a2SMasami Hiramatsu if (p->post_handler) 646afd66255SMasami Hiramatsu return; 647afd66255SMasami Hiramatsu 648afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 649afd66255SMasami Hiramatsu 650afd66255SMasami Hiramatsu /* Check there is no other kprobes at the optimized instructions */ 651afd66255SMasami Hiramatsu if (arch_check_optimized_kprobe(op) < 0) 652afd66255SMasami Hiramatsu return; 653afd66255SMasami Hiramatsu 654afd66255SMasami Hiramatsu /* Check if it is already optimized. */ 655e4add247SMasami Hiramatsu if (op->kp.flags & KPROBE_FLAG_OPTIMIZED) { 656e4add247SMasami Hiramatsu if (optprobe_queued_unopt(op)) { 6576274de49SMasami Hiramatsu /* This is under unoptimizing. Just dequeue the probe */ 6586274de49SMasami Hiramatsu list_del_init(&op->list); 659e4add247SMasami Hiramatsu } 660e4add247SMasami Hiramatsu return; 661e4add247SMasami Hiramatsu } 662e4add247SMasami Hiramatsu op->kp.flags |= KPROBE_FLAG_OPTIMIZED; 663e4add247SMasami Hiramatsu 664e4add247SMasami Hiramatsu /* On unoptimizing/optimizing_list, op must have OPTIMIZED flag */ 665e4add247SMasami Hiramatsu if (WARN_ON_ONCE(!list_empty(&op->list))) 666e4add247SMasami Hiramatsu return; 667e4add247SMasami Hiramatsu 668afd66255SMasami Hiramatsu list_add(&op->list, &optimizing_list); 6696274de49SMasami Hiramatsu kick_kprobe_optimizer(); 6706274de49SMasami Hiramatsu } 6716274de49SMasami Hiramatsu 6726274de49SMasami Hiramatsu /* Short cut to direct unoptimizing */ 67355479f64SMasami Hiramatsu static void force_unoptimize_kprobe(struct optimized_kprobe *op) 6746274de49SMasami Hiramatsu { 6752d1e38f5SThomas Gleixner lockdep_assert_cpus_held(); 6766274de49SMasami Hiramatsu arch_unoptimize_kprobe(op); 677f66c0447SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 6786274de49SMasami Hiramatsu if (kprobe_disabled(&op->kp)) 6796274de49SMasami Hiramatsu arch_disarm_kprobe(&op->kp); 680afd66255SMasami Hiramatsu } 681afd66255SMasami Hiramatsu 682afd66255SMasami Hiramatsu /* Unoptimize a kprobe if p is optimized */ 68355479f64SMasami Hiramatsu static void unoptimize_kprobe(struct kprobe *p, bool force) 684afd66255SMasami Hiramatsu { 685afd66255SMasami Hiramatsu struct optimized_kprobe *op; 686afd66255SMasami Hiramatsu 6876274de49SMasami Hiramatsu if (!kprobe_aggrprobe(p) || kprobe_disarmed(p)) 6886274de49SMasami Hiramatsu return; /* This is not an optprobe nor optimized */ 6896274de49SMasami Hiramatsu 690afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 691e4add247SMasami Hiramatsu if (!kprobe_optimized(p)) 692e4add247SMasami Hiramatsu return; 693e4add247SMasami Hiramatsu 694e4add247SMasami Hiramatsu if (!list_empty(&op->list)) { 695e4add247SMasami Hiramatsu if (optprobe_queued_unopt(op)) { 696e4add247SMasami Hiramatsu /* Queued in unoptimizing queue */ 697e4add247SMasami Hiramatsu if (force) { 6986274de49SMasami Hiramatsu /* 699e4add247SMasami Hiramatsu * Forcibly unoptimize the kprobe here, and queue it 700e4add247SMasami Hiramatsu * in the freeing list for release afterwards. 7016274de49SMasami Hiramatsu */ 7026274de49SMasami Hiramatsu force_unoptimize_kprobe(op); 703e4add247SMasami Hiramatsu list_move(&op->list, &freeing_list); 704e4add247SMasami Hiramatsu } 705e4add247SMasami Hiramatsu } else { 706e4add247SMasami Hiramatsu /* Dequeue from the optimizing queue */ 707e4add247SMasami Hiramatsu list_del_init(&op->list); 708e4add247SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 7096274de49SMasami Hiramatsu } 7106274de49SMasami Hiramatsu return; 7116274de49SMasami Hiramatsu } 7126274de49SMasami Hiramatsu 7136274de49SMasami Hiramatsu /* Optimized kprobe case */ 714e4add247SMasami Hiramatsu if (force) { 7156274de49SMasami Hiramatsu /* Forcibly update the code: this is a special case */ 7166274de49SMasami Hiramatsu force_unoptimize_kprobe(op); 717e4add247SMasami Hiramatsu } else { 7186274de49SMasami Hiramatsu list_add(&op->list, &unoptimizing_list); 7196274de49SMasami Hiramatsu kick_kprobe_optimizer(); 720afd66255SMasami Hiramatsu } 721afd66255SMasami Hiramatsu } 722afd66255SMasami Hiramatsu 7230490cd1fSMasami Hiramatsu /* Cancel unoptimizing for reusing */ 724819319fcSMasami Hiramatsu static int reuse_unused_kprobe(struct kprobe *ap) 7250490cd1fSMasami Hiramatsu { 7260490cd1fSMasami Hiramatsu struct optimized_kprobe *op; 7270490cd1fSMasami Hiramatsu 7280490cd1fSMasami Hiramatsu /* 7290490cd1fSMasami Hiramatsu * Unused kprobe MUST be on the way of delayed unoptimizing (means 7300490cd1fSMasami Hiramatsu * there is still a relative jump) and disabled. 7310490cd1fSMasami Hiramatsu */ 7320490cd1fSMasami Hiramatsu op = container_of(ap, struct optimized_kprobe, kp); 7334458515bSMasami Hiramatsu WARN_ON_ONCE(list_empty(&op->list)); 7340490cd1fSMasami Hiramatsu /* Enable the probe again */ 7350490cd1fSMasami Hiramatsu ap->flags &= ~KPROBE_FLAG_DISABLED; 7360490cd1fSMasami Hiramatsu /* Optimize it again (remove from op->list) */ 7375f843ed4SMasami Hiramatsu if (!kprobe_optready(ap)) 7385f843ed4SMasami Hiramatsu return -EINVAL; 739819319fcSMasami Hiramatsu 7400490cd1fSMasami Hiramatsu optimize_kprobe(ap); 741819319fcSMasami Hiramatsu return 0; 7420490cd1fSMasami Hiramatsu } 7430490cd1fSMasami Hiramatsu 744afd66255SMasami Hiramatsu /* Remove optimized instructions */ 74555479f64SMasami Hiramatsu static void kill_optimized_kprobe(struct kprobe *p) 746afd66255SMasami Hiramatsu { 747afd66255SMasami Hiramatsu struct optimized_kprobe *op; 748afd66255SMasami Hiramatsu 749afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 7506274de49SMasami Hiramatsu if (!list_empty(&op->list)) 7516274de49SMasami Hiramatsu /* Dequeue from the (un)optimization queue */ 752afd66255SMasami Hiramatsu list_del_init(&op->list); 753afd66255SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 7547b959fc5SMasami Hiramatsu 7557b959fc5SMasami Hiramatsu if (kprobe_unused(p)) { 7567b959fc5SMasami Hiramatsu /* Enqueue if it is unused */ 7577b959fc5SMasami Hiramatsu list_add(&op->list, &freeing_list); 7587b959fc5SMasami Hiramatsu /* 7597b959fc5SMasami Hiramatsu * Remove unused probes from the hash list. After waiting 7607b959fc5SMasami Hiramatsu * for synchronization, this probe is reclaimed. 7617b959fc5SMasami Hiramatsu * (reclaiming is done by do_free_cleaned_kprobes().) 7627b959fc5SMasami Hiramatsu */ 7637b959fc5SMasami Hiramatsu hlist_del_rcu(&op->kp.hlist); 7647b959fc5SMasami Hiramatsu } 7657b959fc5SMasami Hiramatsu 7666274de49SMasami Hiramatsu /* Don't touch the code, because it is already freed. */ 767afd66255SMasami Hiramatsu arch_remove_optimized_kprobe(op); 768afd66255SMasami Hiramatsu } 769afd66255SMasami Hiramatsu 770a460246cSMasami Hiramatsu static inline 771a460246cSMasami Hiramatsu void __prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) 772a460246cSMasami Hiramatsu { 773a460246cSMasami Hiramatsu if (!kprobe_ftrace(p)) 774a460246cSMasami Hiramatsu arch_prepare_optimized_kprobe(op, p); 775a460246cSMasami Hiramatsu } 776a460246cSMasami Hiramatsu 777afd66255SMasami Hiramatsu /* Try to prepare optimized instructions */ 77855479f64SMasami Hiramatsu static void prepare_optimized_kprobe(struct kprobe *p) 779afd66255SMasami Hiramatsu { 780afd66255SMasami Hiramatsu struct optimized_kprobe *op; 781afd66255SMasami Hiramatsu 782afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 783a460246cSMasami Hiramatsu __prepare_optimized_kprobe(op, p); 784afd66255SMasami Hiramatsu } 785afd66255SMasami Hiramatsu 786afd66255SMasami Hiramatsu /* Allocate new optimized_kprobe and try to prepare optimized instructions */ 78755479f64SMasami Hiramatsu static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) 788afd66255SMasami Hiramatsu { 789afd66255SMasami Hiramatsu struct optimized_kprobe *op; 790afd66255SMasami Hiramatsu 791afd66255SMasami Hiramatsu op = kzalloc(sizeof(struct optimized_kprobe), GFP_KERNEL); 792afd66255SMasami Hiramatsu if (!op) 793afd66255SMasami Hiramatsu return NULL; 794afd66255SMasami Hiramatsu 795afd66255SMasami Hiramatsu INIT_LIST_HEAD(&op->list); 796afd66255SMasami Hiramatsu op->kp.addr = p->addr; 797a460246cSMasami Hiramatsu __prepare_optimized_kprobe(op, p); 798afd66255SMasami Hiramatsu 799afd66255SMasami Hiramatsu return &op->kp; 800afd66255SMasami Hiramatsu } 801afd66255SMasami Hiramatsu 80255479f64SMasami Hiramatsu static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p); 803afd66255SMasami Hiramatsu 804afd66255SMasami Hiramatsu /* 805afd66255SMasami Hiramatsu * Prepare an optimized_kprobe and optimize it 806afd66255SMasami Hiramatsu * NOTE: p must be a normal registered kprobe 807afd66255SMasami Hiramatsu */ 80855479f64SMasami Hiramatsu static void try_to_optimize_kprobe(struct kprobe *p) 809afd66255SMasami Hiramatsu { 810afd66255SMasami Hiramatsu struct kprobe *ap; 811afd66255SMasami Hiramatsu struct optimized_kprobe *op; 812afd66255SMasami Hiramatsu 813ae6aa16fSMasami Hiramatsu /* Impossible to optimize ftrace-based kprobe */ 814ae6aa16fSMasami Hiramatsu if (kprobe_ftrace(p)) 815ae6aa16fSMasami Hiramatsu return; 816ae6aa16fSMasami Hiramatsu 81725764288SMasami Hiramatsu /* For preparing optimization, jump_label_text_reserved() is called */ 8182d1e38f5SThomas Gleixner cpus_read_lock(); 81925764288SMasami Hiramatsu jump_label_lock(); 82025764288SMasami Hiramatsu mutex_lock(&text_mutex); 82125764288SMasami Hiramatsu 822afd66255SMasami Hiramatsu ap = alloc_aggr_kprobe(p); 823afd66255SMasami Hiramatsu if (!ap) 82425764288SMasami Hiramatsu goto out; 825afd66255SMasami Hiramatsu 826afd66255SMasami Hiramatsu op = container_of(ap, struct optimized_kprobe, kp); 827afd66255SMasami Hiramatsu if (!arch_prepared_optinsn(&op->optinsn)) { 828afd66255SMasami Hiramatsu /* If failed to setup optimizing, fallback to kprobe */ 8296274de49SMasami Hiramatsu arch_remove_optimized_kprobe(op); 8306274de49SMasami Hiramatsu kfree(op); 83125764288SMasami Hiramatsu goto out; 832afd66255SMasami Hiramatsu } 833afd66255SMasami Hiramatsu 834afd66255SMasami Hiramatsu init_aggr_kprobe(ap, p); 83525764288SMasami Hiramatsu optimize_kprobe(ap); /* This just kicks optimizer thread */ 83625764288SMasami Hiramatsu 83725764288SMasami Hiramatsu out: 83825764288SMasami Hiramatsu mutex_unlock(&text_mutex); 83925764288SMasami Hiramatsu jump_label_unlock(); 8402d1e38f5SThomas Gleixner cpus_read_unlock(); 841afd66255SMasami Hiramatsu } 842afd66255SMasami Hiramatsu 843b2be84dfSMasami Hiramatsu #ifdef CONFIG_SYSCTL 84455479f64SMasami Hiramatsu static void optimize_all_kprobes(void) 845b2be84dfSMasami Hiramatsu { 846b2be84dfSMasami Hiramatsu struct hlist_head *head; 847b2be84dfSMasami Hiramatsu struct kprobe *p; 848b2be84dfSMasami Hiramatsu unsigned int i; 849b2be84dfSMasami Hiramatsu 8505c51543bSMasami Hiramatsu mutex_lock(&kprobe_mutex); 851b2be84dfSMasami Hiramatsu /* If optimization is already allowed, just return */ 852b2be84dfSMasami Hiramatsu if (kprobes_allow_optimization) 8535c51543bSMasami Hiramatsu goto out; 854b2be84dfSMasami Hiramatsu 8552d1e38f5SThomas Gleixner cpus_read_lock(); 856b2be84dfSMasami Hiramatsu kprobes_allow_optimization = true; 857b2be84dfSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 858b2be84dfSMasami Hiramatsu head = &kprobe_table[i]; 8597e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) 860b2be84dfSMasami Hiramatsu if (!kprobe_disabled(p)) 861b2be84dfSMasami Hiramatsu optimize_kprobe(p); 862b2be84dfSMasami Hiramatsu } 8632d1e38f5SThomas Gleixner cpus_read_unlock(); 864b2be84dfSMasami Hiramatsu printk(KERN_INFO "Kprobes globally optimized\n"); 8655c51543bSMasami Hiramatsu out: 8665c51543bSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 867b2be84dfSMasami Hiramatsu } 868b2be84dfSMasami Hiramatsu 86955479f64SMasami Hiramatsu static void unoptimize_all_kprobes(void) 870b2be84dfSMasami Hiramatsu { 871b2be84dfSMasami Hiramatsu struct hlist_head *head; 872b2be84dfSMasami Hiramatsu struct kprobe *p; 873b2be84dfSMasami Hiramatsu unsigned int i; 874b2be84dfSMasami Hiramatsu 8755c51543bSMasami Hiramatsu mutex_lock(&kprobe_mutex); 876b2be84dfSMasami Hiramatsu /* If optimization is already prohibited, just return */ 8775c51543bSMasami Hiramatsu if (!kprobes_allow_optimization) { 8785c51543bSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 879b2be84dfSMasami Hiramatsu return; 8805c51543bSMasami Hiramatsu } 881b2be84dfSMasami Hiramatsu 8822d1e38f5SThomas Gleixner cpus_read_lock(); 883b2be84dfSMasami Hiramatsu kprobes_allow_optimization = false; 884b2be84dfSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 885b2be84dfSMasami Hiramatsu head = &kprobe_table[i]; 8867e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 887b2be84dfSMasami Hiramatsu if (!kprobe_disabled(p)) 8886274de49SMasami Hiramatsu unoptimize_kprobe(p, false); 889b2be84dfSMasami Hiramatsu } 890b2be84dfSMasami Hiramatsu } 8912d1e38f5SThomas Gleixner cpus_read_unlock(); 8925c51543bSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 8935c51543bSMasami Hiramatsu 8946274de49SMasami Hiramatsu /* Wait for unoptimizing completion */ 8956274de49SMasami Hiramatsu wait_for_kprobe_optimizer(); 8966274de49SMasami Hiramatsu printk(KERN_INFO "Kprobes globally unoptimized\n"); 897b2be84dfSMasami Hiramatsu } 898b2be84dfSMasami Hiramatsu 8995c51543bSMasami Hiramatsu static DEFINE_MUTEX(kprobe_sysctl_mutex); 900b2be84dfSMasami Hiramatsu int sysctl_kprobes_optimization; 901b2be84dfSMasami Hiramatsu int proc_kprobes_optimization_handler(struct ctl_table *table, int write, 90232927393SChristoph Hellwig void *buffer, size_t *length, 903b2be84dfSMasami Hiramatsu loff_t *ppos) 904b2be84dfSMasami Hiramatsu { 905b2be84dfSMasami Hiramatsu int ret; 906b2be84dfSMasami Hiramatsu 9075c51543bSMasami Hiramatsu mutex_lock(&kprobe_sysctl_mutex); 908b2be84dfSMasami Hiramatsu sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0; 909b2be84dfSMasami Hiramatsu ret = proc_dointvec_minmax(table, write, buffer, length, ppos); 910b2be84dfSMasami Hiramatsu 911b2be84dfSMasami Hiramatsu if (sysctl_kprobes_optimization) 912b2be84dfSMasami Hiramatsu optimize_all_kprobes(); 913b2be84dfSMasami Hiramatsu else 914b2be84dfSMasami Hiramatsu unoptimize_all_kprobes(); 9155c51543bSMasami Hiramatsu mutex_unlock(&kprobe_sysctl_mutex); 916b2be84dfSMasami Hiramatsu 917b2be84dfSMasami Hiramatsu return ret; 918b2be84dfSMasami Hiramatsu } 919b2be84dfSMasami Hiramatsu #endif /* CONFIG_SYSCTL */ 920b2be84dfSMasami Hiramatsu 9216274de49SMasami Hiramatsu /* Put a breakpoint for a probe. Must be called with text_mutex locked */ 92255479f64SMasami Hiramatsu static void __arm_kprobe(struct kprobe *p) 923afd66255SMasami Hiramatsu { 9246d8e40a8SMasami Hiramatsu struct kprobe *_p; 925afd66255SMasami Hiramatsu 926afd66255SMasami Hiramatsu /* Check collision with other optimized kprobes */ 9276d8e40a8SMasami Hiramatsu _p = get_optimized_kprobe((unsigned long)p->addr); 9286d8e40a8SMasami Hiramatsu if (unlikely(_p)) 9296274de49SMasami Hiramatsu /* Fallback to unoptimized kprobe */ 9306274de49SMasami Hiramatsu unoptimize_kprobe(_p, true); 931afd66255SMasami Hiramatsu 932afd66255SMasami Hiramatsu arch_arm_kprobe(p); 933afd66255SMasami Hiramatsu optimize_kprobe(p); /* Try to optimize (add kprobe to a list) */ 934afd66255SMasami Hiramatsu } 935afd66255SMasami Hiramatsu 9366274de49SMasami Hiramatsu /* Remove the breakpoint of a probe. Must be called with text_mutex locked */ 93755479f64SMasami Hiramatsu static void __disarm_kprobe(struct kprobe *p, bool reopt) 938afd66255SMasami Hiramatsu { 9396d8e40a8SMasami Hiramatsu struct kprobe *_p; 940afd66255SMasami Hiramatsu 94169d54b91SWang Nan /* Try to unoptimize */ 94269d54b91SWang Nan unoptimize_kprobe(p, kprobes_all_disarmed); 943afd66255SMasami Hiramatsu 9446274de49SMasami Hiramatsu if (!kprobe_queued(p)) { 9456274de49SMasami Hiramatsu arch_disarm_kprobe(p); 946afd66255SMasami Hiramatsu /* If another kprobe was blocked, optimize it. */ 9476d8e40a8SMasami Hiramatsu _p = get_optimized_kprobe((unsigned long)p->addr); 9486274de49SMasami Hiramatsu if (unlikely(_p) && reopt) 9496d8e40a8SMasami Hiramatsu optimize_kprobe(_p); 950afd66255SMasami Hiramatsu } 9516274de49SMasami Hiramatsu /* TODO: reoptimize others after unoptimized this probe */ 9526274de49SMasami Hiramatsu } 953afd66255SMasami Hiramatsu 954afd66255SMasami Hiramatsu #else /* !CONFIG_OPTPROBES */ 955afd66255SMasami Hiramatsu 956afd66255SMasami Hiramatsu #define optimize_kprobe(p) do {} while (0) 9576274de49SMasami Hiramatsu #define unoptimize_kprobe(p, f) do {} while (0) 958afd66255SMasami Hiramatsu #define kill_optimized_kprobe(p) do {} while (0) 959afd66255SMasami Hiramatsu #define prepare_optimized_kprobe(p) do {} while (0) 960afd66255SMasami Hiramatsu #define try_to_optimize_kprobe(p) do {} while (0) 961afd66255SMasami Hiramatsu #define __arm_kprobe(p) arch_arm_kprobe(p) 9626274de49SMasami Hiramatsu #define __disarm_kprobe(p, o) arch_disarm_kprobe(p) 9636274de49SMasami Hiramatsu #define kprobe_disarmed(p) kprobe_disabled(p) 9646274de49SMasami Hiramatsu #define wait_for_kprobe_optimizer() do {} while (0) 965afd66255SMasami Hiramatsu 966819319fcSMasami Hiramatsu static int reuse_unused_kprobe(struct kprobe *ap) 9670490cd1fSMasami Hiramatsu { 968819319fcSMasami Hiramatsu /* 969819319fcSMasami Hiramatsu * If the optimized kprobe is NOT supported, the aggr kprobe is 970819319fcSMasami Hiramatsu * released at the same time that the last aggregated kprobe is 971819319fcSMasami Hiramatsu * unregistered. 972819319fcSMasami Hiramatsu * Thus there should be no chance to reuse unused kprobe. 973819319fcSMasami Hiramatsu */ 9740490cd1fSMasami Hiramatsu printk(KERN_ERR "Error: There should be no unused kprobe here.\n"); 975819319fcSMasami Hiramatsu return -EINVAL; 9760490cd1fSMasami Hiramatsu } 9770490cd1fSMasami Hiramatsu 97855479f64SMasami Hiramatsu static void free_aggr_kprobe(struct kprobe *p) 979afd66255SMasami Hiramatsu { 9806274de49SMasami Hiramatsu arch_remove_kprobe(p); 981afd66255SMasami Hiramatsu kfree(p); 982afd66255SMasami Hiramatsu } 983afd66255SMasami Hiramatsu 98455479f64SMasami Hiramatsu static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) 985afd66255SMasami Hiramatsu { 986afd66255SMasami Hiramatsu return kzalloc(sizeof(struct kprobe), GFP_KERNEL); 987afd66255SMasami Hiramatsu } 988afd66255SMasami Hiramatsu #endif /* CONFIG_OPTPROBES */ 989afd66255SMasami Hiramatsu 990e7dbfe34SMasami Hiramatsu #ifdef CONFIG_KPROBES_ON_FTRACE 991ae6aa16fSMasami Hiramatsu static struct ftrace_ops kprobe_ftrace_ops __read_mostly = { 992e5253896SMasami Hiramatsu .func = kprobe_ftrace_handler, 9930bc11ed5SMasami Hiramatsu .flags = FTRACE_OPS_FL_SAVE_REGS, 9940bc11ed5SMasami Hiramatsu }; 9950bc11ed5SMasami Hiramatsu 9960bc11ed5SMasami Hiramatsu static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = { 9970bc11ed5SMasami Hiramatsu .func = kprobe_ftrace_handler, 9981d70be34SMasami Hiramatsu .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY, 999ae6aa16fSMasami Hiramatsu }; 10000bc11ed5SMasami Hiramatsu 10010bc11ed5SMasami Hiramatsu static int kprobe_ipmodify_enabled; 1002ae6aa16fSMasami Hiramatsu static int kprobe_ftrace_enabled; 1003ae6aa16fSMasami Hiramatsu 1004ae6aa16fSMasami Hiramatsu /* Must ensure p->addr is really on ftrace */ 100555479f64SMasami Hiramatsu static int prepare_kprobe(struct kprobe *p) 1006ae6aa16fSMasami Hiramatsu { 1007ae6aa16fSMasami Hiramatsu if (!kprobe_ftrace(p)) 1008ae6aa16fSMasami Hiramatsu return arch_prepare_kprobe(p); 1009ae6aa16fSMasami Hiramatsu 1010ae6aa16fSMasami Hiramatsu return arch_prepare_kprobe_ftrace(p); 1011ae6aa16fSMasami Hiramatsu } 1012ae6aa16fSMasami Hiramatsu 1013ae6aa16fSMasami Hiramatsu /* Caller must lock kprobe_mutex */ 10140bc11ed5SMasami Hiramatsu static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, 10150bc11ed5SMasami Hiramatsu int *cnt) 1016ae6aa16fSMasami Hiramatsu { 101712310e34SJessica Yu int ret = 0; 1018ae6aa16fSMasami Hiramatsu 10190bc11ed5SMasami Hiramatsu ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 0, 0); 102012310e34SJessica Yu if (ret) { 10214458515bSMasami Hiramatsu pr_debug("Failed to arm kprobe-ftrace at %pS (%d)\n", 10224458515bSMasami Hiramatsu p->addr, ret); 102312310e34SJessica Yu return ret; 1024ae6aa16fSMasami Hiramatsu } 102512310e34SJessica Yu 10260bc11ed5SMasami Hiramatsu if (*cnt == 0) { 10270bc11ed5SMasami Hiramatsu ret = register_ftrace_function(ops); 102812310e34SJessica Yu if (ret) { 102912310e34SJessica Yu pr_debug("Failed to init kprobe-ftrace (%d)\n", ret); 103012310e34SJessica Yu goto err_ftrace; 103112310e34SJessica Yu } 103212310e34SJessica Yu } 103312310e34SJessica Yu 10340bc11ed5SMasami Hiramatsu (*cnt)++; 103512310e34SJessica Yu return ret; 103612310e34SJessica Yu 103712310e34SJessica Yu err_ftrace: 103812310e34SJessica Yu /* 10390bc11ed5SMasami Hiramatsu * At this point, sinec ops is not registered, we should be sefe from 10400bc11ed5SMasami Hiramatsu * registering empty filter. 104112310e34SJessica Yu */ 10420bc11ed5SMasami Hiramatsu ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0); 104312310e34SJessica Yu return ret; 1044ae6aa16fSMasami Hiramatsu } 1045ae6aa16fSMasami Hiramatsu 10460bc11ed5SMasami Hiramatsu static int arm_kprobe_ftrace(struct kprobe *p) 10470bc11ed5SMasami Hiramatsu { 10480bc11ed5SMasami Hiramatsu bool ipmodify = (p->post_handler != NULL); 10490bc11ed5SMasami Hiramatsu 10500bc11ed5SMasami Hiramatsu return __arm_kprobe_ftrace(p, 10510bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, 10520bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); 10530bc11ed5SMasami Hiramatsu } 10540bc11ed5SMasami Hiramatsu 1055ae6aa16fSMasami Hiramatsu /* Caller must lock kprobe_mutex */ 10560bc11ed5SMasami Hiramatsu static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, 10570bc11ed5SMasami Hiramatsu int *cnt) 1058ae6aa16fSMasami Hiramatsu { 1059297f9233SJessica Yu int ret = 0; 1060297f9233SJessica Yu 10610bc11ed5SMasami Hiramatsu if (*cnt == 1) { 10620bc11ed5SMasami Hiramatsu ret = unregister_ftrace_function(ops); 1063297f9233SJessica Yu if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (%d)\n", ret)) 1064297f9233SJessica Yu return ret; 1065297f9233SJessica Yu } 1066ae6aa16fSMasami Hiramatsu 10670bc11ed5SMasami Hiramatsu (*cnt)--; 1068297f9233SJessica Yu 10690bc11ed5SMasami Hiramatsu ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0); 10704458515bSMasami Hiramatsu WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)\n", 10714458515bSMasami Hiramatsu p->addr, ret); 1072297f9233SJessica Yu return ret; 1073ae6aa16fSMasami Hiramatsu } 10740bc11ed5SMasami Hiramatsu 10750bc11ed5SMasami Hiramatsu static int disarm_kprobe_ftrace(struct kprobe *p) 10760bc11ed5SMasami Hiramatsu { 10770bc11ed5SMasami Hiramatsu bool ipmodify = (p->post_handler != NULL); 10780bc11ed5SMasami Hiramatsu 10790bc11ed5SMasami Hiramatsu return __disarm_kprobe_ftrace(p, 10800bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, 10810bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); 10820bc11ed5SMasami Hiramatsu } 1083e7dbfe34SMasami Hiramatsu #else /* !CONFIG_KPROBES_ON_FTRACE */ 1084ae6aa16fSMasami Hiramatsu #define prepare_kprobe(p) arch_prepare_kprobe(p) 108512310e34SJessica Yu #define arm_kprobe_ftrace(p) (-ENODEV) 1086297f9233SJessica Yu #define disarm_kprobe_ftrace(p) (-ENODEV) 1087ae6aa16fSMasami Hiramatsu #endif 1088ae6aa16fSMasami Hiramatsu 1089201517a7SMasami Hiramatsu /* Arm a kprobe with text_mutex */ 109012310e34SJessica Yu static int arm_kprobe(struct kprobe *kp) 1091201517a7SMasami Hiramatsu { 109212310e34SJessica Yu if (unlikely(kprobe_ftrace(kp))) 109312310e34SJessica Yu return arm_kprobe_ftrace(kp); 109412310e34SJessica Yu 10952d1e38f5SThomas Gleixner cpus_read_lock(); 1096201517a7SMasami Hiramatsu mutex_lock(&text_mutex); 1097afd66255SMasami Hiramatsu __arm_kprobe(kp); 1098201517a7SMasami Hiramatsu mutex_unlock(&text_mutex); 10992d1e38f5SThomas Gleixner cpus_read_unlock(); 110012310e34SJessica Yu 110112310e34SJessica Yu return 0; 1102201517a7SMasami Hiramatsu } 1103201517a7SMasami Hiramatsu 1104201517a7SMasami Hiramatsu /* Disarm a kprobe with text_mutex */ 1105297f9233SJessica Yu static int disarm_kprobe(struct kprobe *kp, bool reopt) 1106201517a7SMasami Hiramatsu { 1107297f9233SJessica Yu if (unlikely(kprobe_ftrace(kp))) 1108297f9233SJessica Yu return disarm_kprobe_ftrace(kp); 11092d1e38f5SThomas Gleixner 11102d1e38f5SThomas Gleixner cpus_read_lock(); 1111201517a7SMasami Hiramatsu mutex_lock(&text_mutex); 1112ae6aa16fSMasami Hiramatsu __disarm_kprobe(kp, reopt); 1113201517a7SMasami Hiramatsu mutex_unlock(&text_mutex); 11142d1e38f5SThomas Gleixner cpus_read_unlock(); 1115297f9233SJessica Yu 1116297f9233SJessica Yu return 0; 1117201517a7SMasami Hiramatsu } 1118201517a7SMasami Hiramatsu 111964f562c6SAnanth N Mavinakayanahalli /* 112064f562c6SAnanth N Mavinakayanahalli * Aggregate handlers for multiple kprobes support - these handlers 112164f562c6SAnanth N Mavinakayanahalli * take care of invoking the individual kprobe handlers on p->list 112264f562c6SAnanth N Mavinakayanahalli */ 1123820aede0SMasami Hiramatsu static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs) 112464f562c6SAnanth N Mavinakayanahalli { 112564f562c6SAnanth N Mavinakayanahalli struct kprobe *kp; 112664f562c6SAnanth N Mavinakayanahalli 11273516a460SAnanth N Mavinakayanahalli list_for_each_entry_rcu(kp, &p->list, list) { 1128de5bd88dSMasami Hiramatsu if (kp->pre_handler && likely(!kprobe_disabled(kp))) { 1129e6584523SAnanth N Mavinakayanahalli set_kprobe_instance(kp); 11308b0914eaSPrasanna S Panchamukhi if (kp->pre_handler(kp, regs)) 11318b0914eaSPrasanna S Panchamukhi return 1; 113264f562c6SAnanth N Mavinakayanahalli } 1133e6584523SAnanth N Mavinakayanahalli reset_kprobe_instance(); 113464f562c6SAnanth N Mavinakayanahalli } 113564f562c6SAnanth N Mavinakayanahalli return 0; 113664f562c6SAnanth N Mavinakayanahalli } 1137820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(aggr_pre_handler); 113864f562c6SAnanth N Mavinakayanahalli 1139820aede0SMasami Hiramatsu static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs, 114064f562c6SAnanth N Mavinakayanahalli unsigned long flags) 114164f562c6SAnanth N Mavinakayanahalli { 114264f562c6SAnanth N Mavinakayanahalli struct kprobe *kp; 114364f562c6SAnanth N Mavinakayanahalli 11443516a460SAnanth N Mavinakayanahalli list_for_each_entry_rcu(kp, &p->list, list) { 1145de5bd88dSMasami Hiramatsu if (kp->post_handler && likely(!kprobe_disabled(kp))) { 1146e6584523SAnanth N Mavinakayanahalli set_kprobe_instance(kp); 114764f562c6SAnanth N Mavinakayanahalli kp->post_handler(kp, regs, flags); 1148e6584523SAnanth N Mavinakayanahalli reset_kprobe_instance(); 114964f562c6SAnanth N Mavinakayanahalli } 115064f562c6SAnanth N Mavinakayanahalli } 115164f562c6SAnanth N Mavinakayanahalli } 1152820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(aggr_post_handler); 115364f562c6SAnanth N Mavinakayanahalli 1154820aede0SMasami Hiramatsu static int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, 1155b94cce92SHien Nguyen int trapnr) 115664f562c6SAnanth N Mavinakayanahalli { 1157b76834bcSChristoph Lameter struct kprobe *cur = __this_cpu_read(kprobe_instance); 1158e6584523SAnanth N Mavinakayanahalli 115964f562c6SAnanth N Mavinakayanahalli /* 116064f562c6SAnanth N Mavinakayanahalli * if we faulted "during" the execution of a user specified 116164f562c6SAnanth N Mavinakayanahalli * probe handler, invoke just that probe's fault handler 116264f562c6SAnanth N Mavinakayanahalli */ 1163e6584523SAnanth N Mavinakayanahalli if (cur && cur->fault_handler) { 1164e6584523SAnanth N Mavinakayanahalli if (cur->fault_handler(cur, regs, trapnr)) 116564f562c6SAnanth N Mavinakayanahalli return 1; 116664f562c6SAnanth N Mavinakayanahalli } 116764f562c6SAnanth N Mavinakayanahalli return 0; 116864f562c6SAnanth N Mavinakayanahalli } 1169820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(aggr_fault_handler); 117064f562c6SAnanth N Mavinakayanahalli 1171bf8d5c52SKeshavamurthy Anil S /* Walks the list and increments nmissed count for multiprobe case */ 1172820aede0SMasami Hiramatsu void kprobes_inc_nmissed_count(struct kprobe *p) 1173bf8d5c52SKeshavamurthy Anil S { 1174bf8d5c52SKeshavamurthy Anil S struct kprobe *kp; 1175afd66255SMasami Hiramatsu if (!kprobe_aggrprobe(p)) { 1176bf8d5c52SKeshavamurthy Anil S p->nmissed++; 1177bf8d5c52SKeshavamurthy Anil S } else { 1178bf8d5c52SKeshavamurthy Anil S list_for_each_entry_rcu(kp, &p->list, list) 1179bf8d5c52SKeshavamurthy Anil S kp->nmissed++; 1180bf8d5c52SKeshavamurthy Anil S } 1181bf8d5c52SKeshavamurthy Anil S return; 1182bf8d5c52SKeshavamurthy Anil S } 1183820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kprobes_inc_nmissed_count); 1184bf8d5c52SKeshavamurthy Anil S 1185820aede0SMasami Hiramatsu void recycle_rp_inst(struct kretprobe_instance *ri, 118699219a3fSbibo,mao struct hlist_head *head) 1187b94cce92SHien Nguyen { 1188ef53d9c5SSrinivasa D S struct kretprobe *rp = ri->rp; 1189ef53d9c5SSrinivasa D S 1190b94cce92SHien Nguyen /* remove rp inst off the rprobe_inst_table */ 1191b94cce92SHien Nguyen hlist_del(&ri->hlist); 1192ef53d9c5SSrinivasa D S INIT_HLIST_NODE(&ri->hlist); 1193ef53d9c5SSrinivasa D S if (likely(rp)) { 1194ec484608SThomas Gleixner raw_spin_lock(&rp->lock); 1195ef53d9c5SSrinivasa D S hlist_add_head(&ri->hlist, &rp->free_instances); 1196ec484608SThomas Gleixner raw_spin_unlock(&rp->lock); 1197b94cce92SHien Nguyen } else 1198b94cce92SHien Nguyen /* Unregistering */ 119999219a3fSbibo,mao hlist_add_head(&ri->hlist, head); 1200b94cce92SHien Nguyen } 1201820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(recycle_rp_inst); 1202b94cce92SHien Nguyen 1203820aede0SMasami Hiramatsu void kretprobe_hash_lock(struct task_struct *tsk, 1204ef53d9c5SSrinivasa D S struct hlist_head **head, unsigned long *flags) 1205635c17c2SNamhyung Kim __acquires(hlist_lock) 1206b94cce92SHien Nguyen { 1207ef53d9c5SSrinivasa D S unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS); 1208ec484608SThomas Gleixner raw_spinlock_t *hlist_lock; 1209ef53d9c5SSrinivasa D S 1210ef53d9c5SSrinivasa D S *head = &kretprobe_inst_table[hash]; 1211ef53d9c5SSrinivasa D S hlist_lock = kretprobe_table_lock_ptr(hash); 1212ec484608SThomas Gleixner raw_spin_lock_irqsave(hlist_lock, *flags); 1213ef53d9c5SSrinivasa D S } 1214820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kretprobe_hash_lock); 1215ef53d9c5SSrinivasa D S 1216820aede0SMasami Hiramatsu static void kretprobe_table_lock(unsigned long hash, 1217017c39bdSMasami Hiramatsu unsigned long *flags) 1218635c17c2SNamhyung Kim __acquires(hlist_lock) 1219ef53d9c5SSrinivasa D S { 1220ec484608SThomas Gleixner raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); 1221ec484608SThomas Gleixner raw_spin_lock_irqsave(hlist_lock, *flags); 1222ef53d9c5SSrinivasa D S } 1223820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kretprobe_table_lock); 1224ef53d9c5SSrinivasa D S 1225820aede0SMasami Hiramatsu void kretprobe_hash_unlock(struct task_struct *tsk, 1226017c39bdSMasami Hiramatsu unsigned long *flags) 1227635c17c2SNamhyung Kim __releases(hlist_lock) 1228ef53d9c5SSrinivasa D S { 1229ef53d9c5SSrinivasa D S unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS); 1230ec484608SThomas Gleixner raw_spinlock_t *hlist_lock; 1231ef53d9c5SSrinivasa D S 1232ef53d9c5SSrinivasa D S hlist_lock = kretprobe_table_lock_ptr(hash); 1233ec484608SThomas Gleixner raw_spin_unlock_irqrestore(hlist_lock, *flags); 1234ef53d9c5SSrinivasa D S } 1235820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kretprobe_hash_unlock); 1236ef53d9c5SSrinivasa D S 1237820aede0SMasami Hiramatsu static void kretprobe_table_unlock(unsigned long hash, 12386376b229SNamhyung Kim unsigned long *flags) 1239635c17c2SNamhyung Kim __releases(hlist_lock) 1240ef53d9c5SSrinivasa D S { 1241ec484608SThomas Gleixner raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash); 1242ec484608SThomas Gleixner raw_spin_unlock_irqrestore(hlist_lock, *flags); 1243b94cce92SHien Nguyen } 1244820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kretprobe_table_unlock); 1245b94cce92SHien Nguyen 1246b94cce92SHien Nguyen /* 1247c6fd91f0Sbibo mao * This function is called from finish_task_switch when task tk becomes dead, 1248c6fd91f0Sbibo mao * so that we can recycle any function-return probe instances associated 1249c6fd91f0Sbibo mao * with this task. These left over instances represent probed functions 1250c6fd91f0Sbibo mao * that have been called but will never return. 1251b94cce92SHien Nguyen */ 1252820aede0SMasami Hiramatsu void kprobe_flush_task(struct task_struct *tk) 1253b94cce92SHien Nguyen { 1254802eae7cSRusty Lynch struct kretprobe_instance *ri; 125599219a3fSbibo,mao struct hlist_head *head, empty_rp; 1256b67bfe0dSSasha Levin struct hlist_node *tmp; 1257ef53d9c5SSrinivasa D S unsigned long hash, flags = 0; 1258802eae7cSRusty Lynch 1259ef53d9c5SSrinivasa D S if (unlikely(!kprobes_initialized)) 1260ef53d9c5SSrinivasa D S /* Early boot. kretprobe_table_locks not yet initialized. */ 1261ef53d9c5SSrinivasa D S return; 1262ef53d9c5SSrinivasa D S 1263d496aab5SAnanth N Mavinakayanahalli INIT_HLIST_HEAD(&empty_rp); 1264ef53d9c5SSrinivasa D S hash = hash_ptr(tk, KPROBE_HASH_BITS); 1265ef53d9c5SSrinivasa D S head = &kretprobe_inst_table[hash]; 1266ef53d9c5SSrinivasa D S kretprobe_table_lock(hash, &flags); 1267b67bfe0dSSasha Levin hlist_for_each_entry_safe(ri, tmp, head, hlist) { 1268802eae7cSRusty Lynch if (ri->task == tk) 126999219a3fSbibo,mao recycle_rp_inst(ri, &empty_rp); 1270802eae7cSRusty Lynch } 1271ef53d9c5SSrinivasa D S kretprobe_table_unlock(hash, &flags); 1272b67bfe0dSSasha Levin hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) { 127399219a3fSbibo,mao hlist_del(&ri->hlist); 127499219a3fSbibo,mao kfree(ri); 127599219a3fSbibo,mao } 1276b94cce92SHien Nguyen } 1277820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_flush_task); 1278b94cce92SHien Nguyen 1279b94cce92SHien Nguyen static inline void free_rp_inst(struct kretprobe *rp) 1280b94cce92SHien Nguyen { 1281b94cce92SHien Nguyen struct kretprobe_instance *ri; 1282b67bfe0dSSasha Levin struct hlist_node *next; 12834c4308cbSChristoph Hellwig 1284b67bfe0dSSasha Levin hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) { 1285ef53d9c5SSrinivasa D S hlist_del(&ri->hlist); 1286b94cce92SHien Nguyen kfree(ri); 1287b94cce92SHien Nguyen } 1288b94cce92SHien Nguyen } 1289b94cce92SHien Nguyen 1290820aede0SMasami Hiramatsu static void cleanup_rp_inst(struct kretprobe *rp) 12914a296e07SMasami Hiramatsu { 1292ef53d9c5SSrinivasa D S unsigned long flags, hash; 12934a296e07SMasami Hiramatsu struct kretprobe_instance *ri; 1294b67bfe0dSSasha Levin struct hlist_node *next; 1295ef53d9c5SSrinivasa D S struct hlist_head *head; 1296ef53d9c5SSrinivasa D S 12974a296e07SMasami Hiramatsu /* No race here */ 1298ef53d9c5SSrinivasa D S for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) { 1299ef53d9c5SSrinivasa D S kretprobe_table_lock(hash, &flags); 1300ef53d9c5SSrinivasa D S head = &kretprobe_inst_table[hash]; 1301b67bfe0dSSasha Levin hlist_for_each_entry_safe(ri, next, head, hlist) { 1302ef53d9c5SSrinivasa D S if (ri->rp == rp) 13034a296e07SMasami Hiramatsu ri->rp = NULL; 13044a296e07SMasami Hiramatsu } 1305ef53d9c5SSrinivasa D S kretprobe_table_unlock(hash, &flags); 1306ef53d9c5SSrinivasa D S } 13074a296e07SMasami Hiramatsu free_rp_inst(rp); 13084a296e07SMasami Hiramatsu } 1309820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(cleanup_rp_inst); 13104a296e07SMasami Hiramatsu 1311059053a2SMasami Hiramatsu /* Add the new probe to ap->list */ 131255479f64SMasami Hiramatsu static int add_new_kprobe(struct kprobe *ap, struct kprobe *p) 13138b0914eaSPrasanna S Panchamukhi { 1314059053a2SMasami Hiramatsu if (p->post_handler) 13156274de49SMasami Hiramatsu unoptimize_kprobe(ap, true); /* Fall back to normal kprobe */ 1316afd66255SMasami Hiramatsu 1317b918e5e6SMasami Hiramatsu list_add_rcu(&p->list, &ap->list); 1318b918e5e6SMasami Hiramatsu if (p->post_handler && !ap->post_handler) 1319b918e5e6SMasami Hiramatsu ap->post_handler = aggr_post_handler; 1320de5bd88dSMasami Hiramatsu 13218b0914eaSPrasanna S Panchamukhi return 0; 13228b0914eaSPrasanna S Panchamukhi } 13238b0914eaSPrasanna S Panchamukhi 13248b0914eaSPrasanna S Panchamukhi /* 132564f562c6SAnanth N Mavinakayanahalli * Fill in the required fields of the "manager kprobe". Replace the 132664f562c6SAnanth N Mavinakayanahalli * earlier kprobe in the hlist with the manager kprobe 132764f562c6SAnanth N Mavinakayanahalli */ 132855479f64SMasami Hiramatsu static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p) 132964f562c6SAnanth N Mavinakayanahalli { 1330afd66255SMasami Hiramatsu /* Copy p's insn slot to ap */ 13318b0914eaSPrasanna S Panchamukhi copy_kprobe(p, ap); 1332a9ad965eSbibo, mao flush_insn_slot(ap); 133364f562c6SAnanth N Mavinakayanahalli ap->addr = p->addr; 1334afd66255SMasami Hiramatsu ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED; 133564f562c6SAnanth N Mavinakayanahalli ap->pre_handler = aggr_pre_handler; 133664f562c6SAnanth N Mavinakayanahalli ap->fault_handler = aggr_fault_handler; 1337e8386a0cSMasami Hiramatsu /* We don't care the kprobe which has gone. */ 1338e8386a0cSMasami Hiramatsu if (p->post_handler && !kprobe_gone(p)) 133936721656Smao, bibo ap->post_handler = aggr_post_handler; 134064f562c6SAnanth N Mavinakayanahalli 134164f562c6SAnanth N Mavinakayanahalli INIT_LIST_HEAD(&ap->list); 1342afd66255SMasami Hiramatsu INIT_HLIST_NODE(&ap->hlist); 134364f562c6SAnanth N Mavinakayanahalli 1344afd66255SMasami Hiramatsu list_add_rcu(&p->list, &ap->list); 1345adad0f33SKeshavamurthy Anil S hlist_replace_rcu(&p->hlist, &ap->hlist); 134664f562c6SAnanth N Mavinakayanahalli } 134764f562c6SAnanth N Mavinakayanahalli 134864f562c6SAnanth N Mavinakayanahalli /* 134964f562c6SAnanth N Mavinakayanahalli * This is the second or subsequent kprobe at the address - handle 135064f562c6SAnanth N Mavinakayanahalli * the intricacies 135164f562c6SAnanth N Mavinakayanahalli */ 135255479f64SMasami Hiramatsu static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p) 135364f562c6SAnanth N Mavinakayanahalli { 135464f562c6SAnanth N Mavinakayanahalli int ret = 0; 13556d8e40a8SMasami Hiramatsu struct kprobe *ap = orig_p; 135664f562c6SAnanth N Mavinakayanahalli 13572d1e38f5SThomas Gleixner cpus_read_lock(); 13582d1e38f5SThomas Gleixner 135925764288SMasami Hiramatsu /* For preparing optimization, jump_label_text_reserved() is called */ 136025764288SMasami Hiramatsu jump_label_lock(); 136125764288SMasami Hiramatsu mutex_lock(&text_mutex); 136225764288SMasami Hiramatsu 13636d8e40a8SMasami Hiramatsu if (!kprobe_aggrprobe(orig_p)) { 13646d8e40a8SMasami Hiramatsu /* If orig_p is not an aggr_kprobe, create new aggr_kprobe. */ 13656d8e40a8SMasami Hiramatsu ap = alloc_aggr_kprobe(orig_p); 136625764288SMasami Hiramatsu if (!ap) { 136725764288SMasami Hiramatsu ret = -ENOMEM; 136825764288SMasami Hiramatsu goto out; 136925764288SMasami Hiramatsu } 13706d8e40a8SMasami Hiramatsu init_aggr_kprobe(ap, orig_p); 1371819319fcSMasami Hiramatsu } else if (kprobe_unused(ap)) { 13720490cd1fSMasami Hiramatsu /* This probe is going to die. Rescue it */ 1373819319fcSMasami Hiramatsu ret = reuse_unused_kprobe(ap); 1374819319fcSMasami Hiramatsu if (ret) 1375819319fcSMasami Hiramatsu goto out; 1376819319fcSMasami Hiramatsu } 1377b918e5e6SMasami Hiramatsu 1378b918e5e6SMasami Hiramatsu if (kprobe_gone(ap)) { 1379e8386a0cSMasami Hiramatsu /* 1380e8386a0cSMasami Hiramatsu * Attempting to insert new probe at the same location that 1381e8386a0cSMasami Hiramatsu * had a probe in the module vaddr area which already 1382e8386a0cSMasami Hiramatsu * freed. So, the instruction slot has already been 1383e8386a0cSMasami Hiramatsu * released. We need a new slot for the new probe. 1384e8386a0cSMasami Hiramatsu */ 1385b918e5e6SMasami Hiramatsu ret = arch_prepare_kprobe(ap); 1386e8386a0cSMasami Hiramatsu if (ret) 1387b918e5e6SMasami Hiramatsu /* 1388b918e5e6SMasami Hiramatsu * Even if fail to allocate new slot, don't need to 1389b918e5e6SMasami Hiramatsu * free aggr_probe. It will be used next time, or 1390b918e5e6SMasami Hiramatsu * freed by unregister_kprobe. 1391b918e5e6SMasami Hiramatsu */ 139225764288SMasami Hiramatsu goto out; 1393de5bd88dSMasami Hiramatsu 1394afd66255SMasami Hiramatsu /* Prepare optimized instructions if possible. */ 1395afd66255SMasami Hiramatsu prepare_optimized_kprobe(ap); 1396afd66255SMasami Hiramatsu 1397e8386a0cSMasami Hiramatsu /* 1398de5bd88dSMasami Hiramatsu * Clear gone flag to prevent allocating new slot again, and 1399de5bd88dSMasami Hiramatsu * set disabled flag because it is not armed yet. 1400e8386a0cSMasami Hiramatsu */ 1401de5bd88dSMasami Hiramatsu ap->flags = (ap->flags & ~KPROBE_FLAG_GONE) 1402de5bd88dSMasami Hiramatsu | KPROBE_FLAG_DISABLED; 1403e8386a0cSMasami Hiramatsu } 1404b918e5e6SMasami Hiramatsu 1405afd66255SMasami Hiramatsu /* Copy ap's insn slot to p */ 1406b918e5e6SMasami Hiramatsu copy_kprobe(ap, p); 140725764288SMasami Hiramatsu ret = add_new_kprobe(ap, p); 140825764288SMasami Hiramatsu 140925764288SMasami Hiramatsu out: 141025764288SMasami Hiramatsu mutex_unlock(&text_mutex); 141125764288SMasami Hiramatsu jump_label_unlock(); 14122d1e38f5SThomas Gleixner cpus_read_unlock(); 141325764288SMasami Hiramatsu 141425764288SMasami Hiramatsu if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) { 141525764288SMasami Hiramatsu ap->flags &= ~KPROBE_FLAG_DISABLED; 141612310e34SJessica Yu if (!kprobes_all_disarmed) { 141725764288SMasami Hiramatsu /* Arm the breakpoint again. */ 141812310e34SJessica Yu ret = arm_kprobe(ap); 141912310e34SJessica Yu if (ret) { 142012310e34SJessica Yu ap->flags |= KPROBE_FLAG_DISABLED; 142112310e34SJessica Yu list_del_rcu(&p->list); 1422ae8b7ce7SPaul E. McKenney synchronize_rcu(); 142312310e34SJessica Yu } 142412310e34SJessica Yu } 142525764288SMasami Hiramatsu } 142625764288SMasami Hiramatsu return ret; 142764f562c6SAnanth N Mavinakayanahalli } 142864f562c6SAnanth N Mavinakayanahalli 1429be8f2743SMasami Hiramatsu bool __weak arch_within_kprobe_blacklist(unsigned long addr) 1430be8f2743SMasami Hiramatsu { 1431be8f2743SMasami Hiramatsu /* The __kprobes marked functions and entry code must not be probed */ 1432be8f2743SMasami Hiramatsu return addr >= (unsigned long)__kprobes_text_start && 1433be8f2743SMasami Hiramatsu addr < (unsigned long)__kprobes_text_end; 1434be8f2743SMasami Hiramatsu } 1435be8f2743SMasami Hiramatsu 14366143c6fbSMasami Hiramatsu static bool __within_kprobe_blacklist(unsigned long addr) 1437d0aaff97SPrasanna S Panchamukhi { 1438376e2424SMasami Hiramatsu struct kprobe_blacklist_entry *ent; 14393d8d996eSSrinivasa Ds 1440be8f2743SMasami Hiramatsu if (arch_within_kprobe_blacklist(addr)) 1441376e2424SMasami Hiramatsu return true; 14423d8d996eSSrinivasa Ds /* 14433d8d996eSSrinivasa Ds * If there exists a kprobe_blacklist, verify and 14443d8d996eSSrinivasa Ds * fail any probe registration in the prohibited area 14453d8d996eSSrinivasa Ds */ 1446376e2424SMasami Hiramatsu list_for_each_entry(ent, &kprobe_blacklist, list) { 1447376e2424SMasami Hiramatsu if (addr >= ent->start_addr && addr < ent->end_addr) 1448376e2424SMasami Hiramatsu return true; 14493d8d996eSSrinivasa Ds } 14506143c6fbSMasami Hiramatsu return false; 14516143c6fbSMasami Hiramatsu } 1452376e2424SMasami Hiramatsu 14536143c6fbSMasami Hiramatsu bool within_kprobe_blacklist(unsigned long addr) 14546143c6fbSMasami Hiramatsu { 14556143c6fbSMasami Hiramatsu char symname[KSYM_NAME_LEN], *p; 14566143c6fbSMasami Hiramatsu 14576143c6fbSMasami Hiramatsu if (__within_kprobe_blacklist(addr)) 14586143c6fbSMasami Hiramatsu return true; 14596143c6fbSMasami Hiramatsu 14606143c6fbSMasami Hiramatsu /* Check if the address is on a suffixed-symbol */ 14616143c6fbSMasami Hiramatsu if (!lookup_symbol_name(addr, symname)) { 14626143c6fbSMasami Hiramatsu p = strchr(symname, '.'); 14636143c6fbSMasami Hiramatsu if (!p) 14646143c6fbSMasami Hiramatsu return false; 14656143c6fbSMasami Hiramatsu *p = '\0'; 14666143c6fbSMasami Hiramatsu addr = (unsigned long)kprobe_lookup_name(symname, 0); 14676143c6fbSMasami Hiramatsu if (addr) 14686143c6fbSMasami Hiramatsu return __within_kprobe_blacklist(addr); 14696143c6fbSMasami Hiramatsu } 1470376e2424SMasami Hiramatsu return false; 1471d0aaff97SPrasanna S Panchamukhi } 1472d0aaff97SPrasanna S Panchamukhi 1473b2a5cd69SMasami Hiramatsu /* 1474b2a5cd69SMasami Hiramatsu * If we have a symbol_name argument, look it up and add the offset field 1475b2a5cd69SMasami Hiramatsu * to it. This way, we can specify a relative address to a symbol. 1476bc81d48dSMasami Hiramatsu * This returns encoded errors if it fails to look up symbol or invalid 1477bc81d48dSMasami Hiramatsu * combination of parameters. 1478b2a5cd69SMasami Hiramatsu */ 14791d585e70SNaveen N. Rao static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr, 14801d585e70SNaveen N. Rao const char *symbol_name, unsigned int offset) 1481b2a5cd69SMasami Hiramatsu { 14821d585e70SNaveen N. Rao if ((symbol_name && addr) || (!symbol_name && !addr)) 1483bc81d48dSMasami Hiramatsu goto invalid; 1484bc81d48dSMasami Hiramatsu 14851d585e70SNaveen N. Rao if (symbol_name) { 14867246f600SLinus Torvalds addr = kprobe_lookup_name(symbol_name, offset); 1487bc81d48dSMasami Hiramatsu if (!addr) 1488bc81d48dSMasami Hiramatsu return ERR_PTR(-ENOENT); 1489b2a5cd69SMasami Hiramatsu } 1490b2a5cd69SMasami Hiramatsu 14911d585e70SNaveen N. Rao addr = (kprobe_opcode_t *)(((char *)addr) + offset); 1492bc81d48dSMasami Hiramatsu if (addr) 1493bc81d48dSMasami Hiramatsu return addr; 1494bc81d48dSMasami Hiramatsu 1495bc81d48dSMasami Hiramatsu invalid: 1496bc81d48dSMasami Hiramatsu return ERR_PTR(-EINVAL); 1497b2a5cd69SMasami Hiramatsu } 1498b2a5cd69SMasami Hiramatsu 14991d585e70SNaveen N. Rao static kprobe_opcode_t *kprobe_addr(struct kprobe *p) 15001d585e70SNaveen N. Rao { 15011d585e70SNaveen N. Rao return _kprobe_addr(p->addr, p->symbol_name, p->offset); 15021d585e70SNaveen N. Rao } 15031d585e70SNaveen N. Rao 15041f0ab409SAnanth N Mavinakayanahalli /* Check passed kprobe is valid and return kprobe in kprobe_table. */ 150555479f64SMasami Hiramatsu static struct kprobe *__get_valid_kprobe(struct kprobe *p) 15061f0ab409SAnanth N Mavinakayanahalli { 15076d8e40a8SMasami Hiramatsu struct kprobe *ap, *list_p; 15081f0ab409SAnanth N Mavinakayanahalli 15097e6a71d8SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 15107e6a71d8SMasami Hiramatsu 15116d8e40a8SMasami Hiramatsu ap = get_kprobe(p->addr); 15126d8e40a8SMasami Hiramatsu if (unlikely(!ap)) 15131f0ab409SAnanth N Mavinakayanahalli return NULL; 15141f0ab409SAnanth N Mavinakayanahalli 15156d8e40a8SMasami Hiramatsu if (p != ap) { 15167e6a71d8SMasami Hiramatsu list_for_each_entry(list_p, &ap->list, list) 15171f0ab409SAnanth N Mavinakayanahalli if (list_p == p) 15181f0ab409SAnanth N Mavinakayanahalli /* kprobe p is a valid probe */ 15191f0ab409SAnanth N Mavinakayanahalli goto valid; 15201f0ab409SAnanth N Mavinakayanahalli return NULL; 15211f0ab409SAnanth N Mavinakayanahalli } 15221f0ab409SAnanth N Mavinakayanahalli valid: 15236d8e40a8SMasami Hiramatsu return ap; 15241f0ab409SAnanth N Mavinakayanahalli } 15251f0ab409SAnanth N Mavinakayanahalli 15261f0ab409SAnanth N Mavinakayanahalli /* Return error if the kprobe is being re-registered */ 15271f0ab409SAnanth N Mavinakayanahalli static inline int check_kprobe_rereg(struct kprobe *p) 15281f0ab409SAnanth N Mavinakayanahalli { 15291f0ab409SAnanth N Mavinakayanahalli int ret = 0; 15301f0ab409SAnanth N Mavinakayanahalli 15311f0ab409SAnanth N Mavinakayanahalli mutex_lock(&kprobe_mutex); 15326d8e40a8SMasami Hiramatsu if (__get_valid_kprobe(p)) 15331f0ab409SAnanth N Mavinakayanahalli ret = -EINVAL; 15341f0ab409SAnanth N Mavinakayanahalli mutex_unlock(&kprobe_mutex); 15356d8e40a8SMasami Hiramatsu 15361f0ab409SAnanth N Mavinakayanahalli return ret; 15371f0ab409SAnanth N Mavinakayanahalli } 15381f0ab409SAnanth N Mavinakayanahalli 1539f7f242ffSHeiko Carstens int __weak arch_check_ftrace_location(struct kprobe *p) 15401da177e4SLinus Torvalds { 1541ae6aa16fSMasami Hiramatsu unsigned long ftrace_addr; 1542ae6aa16fSMasami Hiramatsu 1543ae6aa16fSMasami Hiramatsu ftrace_addr = ftrace_location((unsigned long)p->addr); 1544ae6aa16fSMasami Hiramatsu if (ftrace_addr) { 1545e7dbfe34SMasami Hiramatsu #ifdef CONFIG_KPROBES_ON_FTRACE 1546ae6aa16fSMasami Hiramatsu /* Given address is not on the instruction boundary */ 1547ae6aa16fSMasami Hiramatsu if ((unsigned long)p->addr != ftrace_addr) 1548ae6aa16fSMasami Hiramatsu return -EILSEQ; 1549ae6aa16fSMasami Hiramatsu p->flags |= KPROBE_FLAG_FTRACE; 1550e7dbfe34SMasami Hiramatsu #else /* !CONFIG_KPROBES_ON_FTRACE */ 1551ae6aa16fSMasami Hiramatsu return -EINVAL; 1552ae6aa16fSMasami Hiramatsu #endif 1553ae6aa16fSMasami Hiramatsu } 1554f7f242ffSHeiko Carstens return 0; 1555f7f242ffSHeiko Carstens } 1556f7fa6ef0SMasami Hiramatsu 1557f7f242ffSHeiko Carstens static int check_kprobe_address_safe(struct kprobe *p, 1558f7f242ffSHeiko Carstens struct module **probed_mod) 1559f7f242ffSHeiko Carstens { 1560f7f242ffSHeiko Carstens int ret; 1561f7f242ffSHeiko Carstens 1562f7f242ffSHeiko Carstens ret = arch_check_ftrace_location(p); 1563f7f242ffSHeiko Carstens if (ret) 1564f7f242ffSHeiko Carstens return ret; 1565f7fa6ef0SMasami Hiramatsu jump_label_lock(); 1566f7fa6ef0SMasami Hiramatsu preempt_disable(); 1567f7fa6ef0SMasami Hiramatsu 1568f7fa6ef0SMasami Hiramatsu /* Ensure it is not in reserved area nor out of text */ 1569f7fa6ef0SMasami Hiramatsu if (!kernel_text_address((unsigned long) p->addr) || 1570376e2424SMasami Hiramatsu within_kprobe_blacklist((unsigned long) p->addr) || 1571e336b402SMasami Hiramatsu jump_label_text_reserved(p->addr, p->addr) || 1572e336b402SMasami Hiramatsu find_bug((unsigned long)p->addr)) { 1573f7fa6ef0SMasami Hiramatsu ret = -EINVAL; 1574f7fa6ef0SMasami Hiramatsu goto out; 1575f7fa6ef0SMasami Hiramatsu } 1576f7fa6ef0SMasami Hiramatsu 1577f7fa6ef0SMasami Hiramatsu /* Check if are we probing a module */ 1578f7fa6ef0SMasami Hiramatsu *probed_mod = __module_text_address((unsigned long) p->addr); 1579f7fa6ef0SMasami Hiramatsu if (*probed_mod) { 1580f7fa6ef0SMasami Hiramatsu /* 1581f7fa6ef0SMasami Hiramatsu * We must hold a refcount of the probed module while updating 1582f7fa6ef0SMasami Hiramatsu * its code to prohibit unexpected unloading. 1583f7fa6ef0SMasami Hiramatsu */ 1584f7fa6ef0SMasami Hiramatsu if (unlikely(!try_module_get(*probed_mod))) { 1585f7fa6ef0SMasami Hiramatsu ret = -ENOENT; 1586f7fa6ef0SMasami Hiramatsu goto out; 1587f7fa6ef0SMasami Hiramatsu } 1588f7fa6ef0SMasami Hiramatsu 1589f7fa6ef0SMasami Hiramatsu /* 1590f7fa6ef0SMasami Hiramatsu * If the module freed .init.text, we couldn't insert 1591f7fa6ef0SMasami Hiramatsu * kprobes in there. 1592f7fa6ef0SMasami Hiramatsu */ 1593f7fa6ef0SMasami Hiramatsu if (within_module_init((unsigned long)p->addr, *probed_mod) && 1594f7fa6ef0SMasami Hiramatsu (*probed_mod)->state != MODULE_STATE_COMING) { 1595f7fa6ef0SMasami Hiramatsu module_put(*probed_mod); 1596f7fa6ef0SMasami Hiramatsu *probed_mod = NULL; 1597f7fa6ef0SMasami Hiramatsu ret = -ENOENT; 1598f7fa6ef0SMasami Hiramatsu } 1599f7fa6ef0SMasami Hiramatsu } 1600f7fa6ef0SMasami Hiramatsu out: 1601f7fa6ef0SMasami Hiramatsu preempt_enable(); 1602f7fa6ef0SMasami Hiramatsu jump_label_unlock(); 1603f7fa6ef0SMasami Hiramatsu 1604f7fa6ef0SMasami Hiramatsu return ret; 1605f7fa6ef0SMasami Hiramatsu } 1606f7fa6ef0SMasami Hiramatsu 160755479f64SMasami Hiramatsu int register_kprobe(struct kprobe *p) 1608f7fa6ef0SMasami Hiramatsu { 1609f7fa6ef0SMasami Hiramatsu int ret; 161064f562c6SAnanth N Mavinakayanahalli struct kprobe *old_p; 1611df019b1dSKeshavamurthy Anil S struct module *probed_mod; 1612b2a5cd69SMasami Hiramatsu kprobe_opcode_t *addr; 16131da177e4SLinus Torvalds 1614f7fa6ef0SMasami Hiramatsu /* Adjust probe address from symbol */ 1615b2a5cd69SMasami Hiramatsu addr = kprobe_addr(p); 1616bc81d48dSMasami Hiramatsu if (IS_ERR(addr)) 1617bc81d48dSMasami Hiramatsu return PTR_ERR(addr); 1618b2a5cd69SMasami Hiramatsu p->addr = addr; 16193a872d89SAnanth N Mavinakayanahalli 16201f0ab409SAnanth N Mavinakayanahalli ret = check_kprobe_rereg(p); 16211f0ab409SAnanth N Mavinakayanahalli if (ret) 16221f0ab409SAnanth N Mavinakayanahalli return ret; 16231f0ab409SAnanth N Mavinakayanahalli 1624de5bd88dSMasami Hiramatsu /* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */ 1625de5bd88dSMasami Hiramatsu p->flags &= KPROBE_FLAG_DISABLED; 16263516a460SAnanth N Mavinakayanahalli p->nmissed = 0; 16279861668fSMasami Hiramatsu INIT_LIST_HEAD(&p->list); 1628afd66255SMasami Hiramatsu 1629f7fa6ef0SMasami Hiramatsu ret = check_kprobe_address_safe(p, &probed_mod); 1630f7fa6ef0SMasami Hiramatsu if (ret) 1631f7fa6ef0SMasami Hiramatsu return ret; 1632f7fa6ef0SMasami Hiramatsu 1633f7fa6ef0SMasami Hiramatsu mutex_lock(&kprobe_mutex); 1634afd66255SMasami Hiramatsu 163564f562c6SAnanth N Mavinakayanahalli old_p = get_kprobe(p->addr); 163664f562c6SAnanth N Mavinakayanahalli if (old_p) { 1637afd66255SMasami Hiramatsu /* Since this may unoptimize old_p, locking text_mutex. */ 163864f562c6SAnanth N Mavinakayanahalli ret = register_aggr_kprobe(old_p, p); 16391da177e4SLinus Torvalds goto out; 16401da177e4SLinus Torvalds } 16411da177e4SLinus Torvalds 16422d1e38f5SThomas Gleixner cpus_read_lock(); 16432d1e38f5SThomas Gleixner /* Prevent text modification */ 16442d1e38f5SThomas Gleixner mutex_lock(&text_mutex); 1645ae6aa16fSMasami Hiramatsu ret = prepare_kprobe(p); 164625764288SMasami Hiramatsu mutex_unlock(&text_mutex); 16472d1e38f5SThomas Gleixner cpus_read_unlock(); 16486f716acdSChristoph Hellwig if (ret) 1649afd66255SMasami Hiramatsu goto out; 165049a2a1b8SAnil S Keshavamurthy 165164f562c6SAnanth N Mavinakayanahalli INIT_HLIST_NODE(&p->hlist); 16523516a460SAnanth N Mavinakayanahalli hlist_add_head_rcu(&p->hlist, 16531da177e4SLinus Torvalds &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); 16541da177e4SLinus Torvalds 165512310e34SJessica Yu if (!kprobes_all_disarmed && !kprobe_disabled(p)) { 165612310e34SJessica Yu ret = arm_kprobe(p); 165712310e34SJessica Yu if (ret) { 165812310e34SJessica Yu hlist_del_rcu(&p->hlist); 1659ae8b7ce7SPaul E. McKenney synchronize_rcu(); 166012310e34SJessica Yu goto out; 166112310e34SJessica Yu } 166212310e34SJessica Yu } 166374a0b576SChristoph Hellwig 1664afd66255SMasami Hiramatsu /* Try to optimize kprobe */ 1665afd66255SMasami Hiramatsu try_to_optimize_kprobe(p); 16661da177e4SLinus Torvalds out: 16677a7d1cf9SIngo Molnar mutex_unlock(&kprobe_mutex); 166849a2a1b8SAnil S Keshavamurthy 1669e8386a0cSMasami Hiramatsu if (probed_mod) 1670df019b1dSKeshavamurthy Anil S module_put(probed_mod); 1671e8386a0cSMasami Hiramatsu 16721da177e4SLinus Torvalds return ret; 16731da177e4SLinus Torvalds } 167499081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kprobe); 16751da177e4SLinus Torvalds 16766f0f1dd7SMasami Hiramatsu /* Check if all probes on the aggrprobe are disabled */ 167755479f64SMasami Hiramatsu static int aggr_kprobe_disabled(struct kprobe *ap) 16786f0f1dd7SMasami Hiramatsu { 16796f0f1dd7SMasami Hiramatsu struct kprobe *kp; 16806f0f1dd7SMasami Hiramatsu 16817e6a71d8SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 16827e6a71d8SMasami Hiramatsu 16837e6a71d8SMasami Hiramatsu list_for_each_entry(kp, &ap->list, list) 16846f0f1dd7SMasami Hiramatsu if (!kprobe_disabled(kp)) 16856f0f1dd7SMasami Hiramatsu /* 16866f0f1dd7SMasami Hiramatsu * There is an active probe on the list. 16876f0f1dd7SMasami Hiramatsu * We can't disable this ap. 16886f0f1dd7SMasami Hiramatsu */ 16896f0f1dd7SMasami Hiramatsu return 0; 16906f0f1dd7SMasami Hiramatsu 16916f0f1dd7SMasami Hiramatsu return 1; 16926f0f1dd7SMasami Hiramatsu } 16936f0f1dd7SMasami Hiramatsu 16946f0f1dd7SMasami Hiramatsu /* Disable one kprobe: Make sure called under kprobe_mutex is locked */ 169555479f64SMasami Hiramatsu static struct kprobe *__disable_kprobe(struct kprobe *p) 16966f0f1dd7SMasami Hiramatsu { 16976f0f1dd7SMasami Hiramatsu struct kprobe *orig_p; 1698297f9233SJessica Yu int ret; 16996f0f1dd7SMasami Hiramatsu 17006f0f1dd7SMasami Hiramatsu /* Get an original kprobe for return */ 17016f0f1dd7SMasami Hiramatsu orig_p = __get_valid_kprobe(p); 17026f0f1dd7SMasami Hiramatsu if (unlikely(orig_p == NULL)) 1703297f9233SJessica Yu return ERR_PTR(-EINVAL); 17046f0f1dd7SMasami Hiramatsu 17056f0f1dd7SMasami Hiramatsu if (!kprobe_disabled(p)) { 17066f0f1dd7SMasami Hiramatsu /* Disable probe if it is a child probe */ 17076f0f1dd7SMasami Hiramatsu if (p != orig_p) 17086f0f1dd7SMasami Hiramatsu p->flags |= KPROBE_FLAG_DISABLED; 17096f0f1dd7SMasami Hiramatsu 17106f0f1dd7SMasami Hiramatsu /* Try to disarm and disable this/parent probe */ 17116f0f1dd7SMasami Hiramatsu if (p == orig_p || aggr_kprobe_disabled(orig_p)) { 171269d54b91SWang Nan /* 171369d54b91SWang Nan * If kprobes_all_disarmed is set, orig_p 171469d54b91SWang Nan * should have already been disarmed, so 171569d54b91SWang Nan * skip unneed disarming process. 171669d54b91SWang Nan */ 1717297f9233SJessica Yu if (!kprobes_all_disarmed) { 1718297f9233SJessica Yu ret = disarm_kprobe(orig_p, true); 1719297f9233SJessica Yu if (ret) { 1720297f9233SJessica Yu p->flags &= ~KPROBE_FLAG_DISABLED; 1721297f9233SJessica Yu return ERR_PTR(ret); 1722297f9233SJessica Yu } 1723297f9233SJessica Yu } 17246f0f1dd7SMasami Hiramatsu orig_p->flags |= KPROBE_FLAG_DISABLED; 17256f0f1dd7SMasami Hiramatsu } 17266f0f1dd7SMasami Hiramatsu } 17276f0f1dd7SMasami Hiramatsu 17286f0f1dd7SMasami Hiramatsu return orig_p; 17296f0f1dd7SMasami Hiramatsu } 17306f0f1dd7SMasami Hiramatsu 17319861668fSMasami Hiramatsu /* 17329861668fSMasami Hiramatsu * Unregister a kprobe without a scheduler synchronization. 17339861668fSMasami Hiramatsu */ 173455479f64SMasami Hiramatsu static int __unregister_kprobe_top(struct kprobe *p) 1735df019b1dSKeshavamurthy Anil S { 17366d8e40a8SMasami Hiramatsu struct kprobe *ap, *list_p; 173764f562c6SAnanth N Mavinakayanahalli 17386f0f1dd7SMasami Hiramatsu /* Disable kprobe. This will disarm it if needed. */ 17396f0f1dd7SMasami Hiramatsu ap = __disable_kprobe(p); 1740297f9233SJessica Yu if (IS_ERR(ap)) 1741297f9233SJessica Yu return PTR_ERR(ap); 17429861668fSMasami Hiramatsu 17436f0f1dd7SMasami Hiramatsu if (ap == p) 1744bf8f6e5bSAnanth N Mavinakayanahalli /* 17456f0f1dd7SMasami Hiramatsu * This probe is an independent(and non-optimized) kprobe 17466f0f1dd7SMasami Hiramatsu * (not an aggrprobe). Remove from the hash list. 1747bf8f6e5bSAnanth N Mavinakayanahalli */ 17486f0f1dd7SMasami Hiramatsu goto disarmed; 17496f0f1dd7SMasami Hiramatsu 17506f0f1dd7SMasami Hiramatsu /* Following process expects this probe is an aggrprobe */ 17516f0f1dd7SMasami Hiramatsu WARN_ON(!kprobe_aggrprobe(ap)); 17526f0f1dd7SMasami Hiramatsu 17536274de49SMasami Hiramatsu if (list_is_singular(&ap->list) && kprobe_disarmed(ap)) 17546274de49SMasami Hiramatsu /* 17556274de49SMasami Hiramatsu * !disarmed could be happen if the probe is under delayed 17566274de49SMasami Hiramatsu * unoptimizing. 17576274de49SMasami Hiramatsu */ 17586f0f1dd7SMasami Hiramatsu goto disarmed; 17596f0f1dd7SMasami Hiramatsu else { 17606f0f1dd7SMasami Hiramatsu /* If disabling probe has special handlers, update aggrprobe */ 1761e8386a0cSMasami Hiramatsu if (p->post_handler && !kprobe_gone(p)) { 17627e6a71d8SMasami Hiramatsu list_for_each_entry(list_p, &ap->list, list) { 17639861668fSMasami Hiramatsu if ((list_p != p) && (list_p->post_handler)) 17649861668fSMasami Hiramatsu goto noclean; 17659861668fSMasami Hiramatsu } 17666d8e40a8SMasami Hiramatsu ap->post_handler = NULL; 17679861668fSMasami Hiramatsu } 17689861668fSMasami Hiramatsu noclean: 17696f0f1dd7SMasami Hiramatsu /* 17706f0f1dd7SMasami Hiramatsu * Remove from the aggrprobe: this path will do nothing in 17716f0f1dd7SMasami Hiramatsu * __unregister_kprobe_bottom(). 17726f0f1dd7SMasami Hiramatsu */ 177349a2a1b8SAnil S Keshavamurthy list_del_rcu(&p->list); 17746f0f1dd7SMasami Hiramatsu if (!kprobe_disabled(ap) && !kprobes_all_disarmed) 17756f0f1dd7SMasami Hiramatsu /* 17766f0f1dd7SMasami Hiramatsu * Try to optimize this probe again, because post 17776f0f1dd7SMasami Hiramatsu * handler may have been changed. 17786f0f1dd7SMasami Hiramatsu */ 17796d8e40a8SMasami Hiramatsu optimize_kprobe(ap); 1780afd66255SMasami Hiramatsu } 17816f0f1dd7SMasami Hiramatsu return 0; 17826f0f1dd7SMasami Hiramatsu 17836f0f1dd7SMasami Hiramatsu disarmed: 17846f0f1dd7SMasami Hiramatsu hlist_del_rcu(&ap->hlist); 17859861668fSMasami Hiramatsu return 0; 178649a2a1b8SAnil S Keshavamurthy } 178749a2a1b8SAnil S Keshavamurthy 178855479f64SMasami Hiramatsu static void __unregister_kprobe_bottom(struct kprobe *p) 17899861668fSMasami Hiramatsu { 17906d8e40a8SMasami Hiramatsu struct kprobe *ap; 17913516a460SAnanth N Mavinakayanahalli 1792e8386a0cSMasami Hiramatsu if (list_empty(&p->list)) 17936274de49SMasami Hiramatsu /* This is an independent kprobe */ 1794e8386a0cSMasami Hiramatsu arch_remove_kprobe(p); 1795e8386a0cSMasami Hiramatsu else if (list_is_singular(&p->list)) { 17966274de49SMasami Hiramatsu /* This is the last child of an aggrprobe */ 17976d8e40a8SMasami Hiramatsu ap = list_entry(p->list.next, struct kprobe, list); 17989861668fSMasami Hiramatsu list_del(&p->list); 17996d8e40a8SMasami Hiramatsu free_aggr_kprobe(ap); 180049a2a1b8SAnil S Keshavamurthy } 18016274de49SMasami Hiramatsu /* Otherwise, do nothing. */ 18029861668fSMasami Hiramatsu } 18039861668fSMasami Hiramatsu 180455479f64SMasami Hiramatsu int register_kprobes(struct kprobe **kps, int num) 18059861668fSMasami Hiramatsu { 18069861668fSMasami Hiramatsu int i, ret = 0; 18079861668fSMasami Hiramatsu 18089861668fSMasami Hiramatsu if (num <= 0) 18099861668fSMasami Hiramatsu return -EINVAL; 18109861668fSMasami Hiramatsu for (i = 0; i < num; i++) { 181149ad2fd7SMasami Hiramatsu ret = register_kprobe(kps[i]); 181267dddaadSMasami Hiramatsu if (ret < 0) { 181367dddaadSMasami Hiramatsu if (i > 0) 18149861668fSMasami Hiramatsu unregister_kprobes(kps, i); 181536721656Smao, bibo break; 181636721656Smao, bibo } 181736721656Smao, bibo } 18189861668fSMasami Hiramatsu return ret; 181936721656Smao, bibo } 182099081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kprobes); 18219861668fSMasami Hiramatsu 182255479f64SMasami Hiramatsu void unregister_kprobe(struct kprobe *p) 18239861668fSMasami Hiramatsu { 18249861668fSMasami Hiramatsu unregister_kprobes(&p, 1); 18259861668fSMasami Hiramatsu } 182699081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kprobe); 18279861668fSMasami Hiramatsu 182855479f64SMasami Hiramatsu void unregister_kprobes(struct kprobe **kps, int num) 18299861668fSMasami Hiramatsu { 18309861668fSMasami Hiramatsu int i; 18319861668fSMasami Hiramatsu 18329861668fSMasami Hiramatsu if (num <= 0) 18339861668fSMasami Hiramatsu return; 18349861668fSMasami Hiramatsu mutex_lock(&kprobe_mutex); 18359861668fSMasami Hiramatsu for (i = 0; i < num; i++) 18369861668fSMasami Hiramatsu if (__unregister_kprobe_top(kps[i]) < 0) 18379861668fSMasami Hiramatsu kps[i]->addr = NULL; 183836721656Smao, bibo mutex_unlock(&kprobe_mutex); 18399861668fSMasami Hiramatsu 1840ae8b7ce7SPaul E. McKenney synchronize_rcu(); 18419861668fSMasami Hiramatsu for (i = 0; i < num; i++) 18429861668fSMasami Hiramatsu if (kps[i]->addr) 18439861668fSMasami Hiramatsu __unregister_kprobe_bottom(kps[i]); 18441da177e4SLinus Torvalds } 184599081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kprobes); 18461da177e4SLinus Torvalds 18475f6bee34SNaveen N. Rao int __weak kprobe_exceptions_notify(struct notifier_block *self, 1848fc62d020SNaveen N. Rao unsigned long val, void *data) 1849fc62d020SNaveen N. Rao { 1850fc62d020SNaveen N. Rao return NOTIFY_DONE; 1851fc62d020SNaveen N. Rao } 18525f6bee34SNaveen N. Rao NOKPROBE_SYMBOL(kprobe_exceptions_notify); 1853fc62d020SNaveen N. Rao 18541da177e4SLinus Torvalds static struct notifier_block kprobe_exceptions_nb = { 18551da177e4SLinus Torvalds .notifier_call = kprobe_exceptions_notify, 18563d5631e0SAnil S Keshavamurthy .priority = 0x7fffffff /* we need to be notified first */ 18573d5631e0SAnil S Keshavamurthy }; 18583d5631e0SAnil S Keshavamurthy 18593d7e3382SMichael Ellerman unsigned long __weak arch_deref_entry_point(void *entry) 18603d7e3382SMichael Ellerman { 18613d7e3382SMichael Ellerman return (unsigned long)entry; 18623d7e3382SMichael Ellerman } 18631da177e4SLinus Torvalds 18649edddaa2SAnanth N Mavinakayanahalli #ifdef CONFIG_KRETPROBES 1865e65cefe8SAdrian Bunk /* 1866e65cefe8SAdrian Bunk * This kprobe pre_handler is registered with every kretprobe. When probe 1867e65cefe8SAdrian Bunk * hits it will set up the return probe. 1868e65cefe8SAdrian Bunk */ 1869820aede0SMasami Hiramatsu static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) 1870e65cefe8SAdrian Bunk { 1871e65cefe8SAdrian Bunk struct kretprobe *rp = container_of(p, struct kretprobe, kp); 1872ef53d9c5SSrinivasa D S unsigned long hash, flags = 0; 18734c4308cbSChristoph Hellwig struct kretprobe_instance *ri; 18744c4308cbSChristoph Hellwig 1875f96f5678SMasami Hiramatsu /* 1876f96f5678SMasami Hiramatsu * To avoid deadlocks, prohibit return probing in NMI contexts, 1877f96f5678SMasami Hiramatsu * just skip the probe and increase the (inexact) 'nmissed' 1878f96f5678SMasami Hiramatsu * statistical counter, so that the user is informed that 1879f96f5678SMasami Hiramatsu * something happened: 1880f96f5678SMasami Hiramatsu */ 1881f96f5678SMasami Hiramatsu if (unlikely(in_nmi())) { 1882f96f5678SMasami Hiramatsu rp->nmissed++; 1883f96f5678SMasami Hiramatsu return 0; 1884f96f5678SMasami Hiramatsu } 1885f96f5678SMasami Hiramatsu 1886ef53d9c5SSrinivasa D S /* TODO: consider to only swap the RA after the last pre_handler fired */ 1887ef53d9c5SSrinivasa D S hash = hash_ptr(current, KPROBE_HASH_BITS); 1888ec484608SThomas Gleixner raw_spin_lock_irqsave(&rp->lock, flags); 1889ef53d9c5SSrinivasa D S if (!hlist_empty(&rp->free_instances)) { 18904c4308cbSChristoph Hellwig ri = hlist_entry(rp->free_instances.first, 1891ef53d9c5SSrinivasa D S struct kretprobe_instance, hlist); 1892ef53d9c5SSrinivasa D S hlist_del(&ri->hlist); 1893ec484608SThomas Gleixner raw_spin_unlock_irqrestore(&rp->lock, flags); 1894ef53d9c5SSrinivasa D S 18954c4308cbSChristoph Hellwig ri->rp = rp; 18964c4308cbSChristoph Hellwig ri->task = current; 1897f47cd9b5SAbhishek Sagar 189855ca6140SJiang Liu if (rp->entry_handler && rp->entry_handler(ri, regs)) { 189955ca6140SJiang Liu raw_spin_lock_irqsave(&rp->lock, flags); 190055ca6140SJiang Liu hlist_add_head(&ri->hlist, &rp->free_instances); 190155ca6140SJiang Liu raw_spin_unlock_irqrestore(&rp->lock, flags); 1902f47cd9b5SAbhishek Sagar return 0; 190355ca6140SJiang Liu } 1904f47cd9b5SAbhishek Sagar 19054c4308cbSChristoph Hellwig arch_prepare_kretprobe(ri, regs); 19064c4308cbSChristoph Hellwig 19074c4308cbSChristoph Hellwig /* XXX(hch): why is there no hlist_move_head? */ 1908ef53d9c5SSrinivasa D S INIT_HLIST_NODE(&ri->hlist); 1909ef53d9c5SSrinivasa D S kretprobe_table_lock(hash, &flags); 1910ef53d9c5SSrinivasa D S hlist_add_head(&ri->hlist, &kretprobe_inst_table[hash]); 1911ef53d9c5SSrinivasa D S kretprobe_table_unlock(hash, &flags); 1912ef53d9c5SSrinivasa D S } else { 19134c4308cbSChristoph Hellwig rp->nmissed++; 1914ec484608SThomas Gleixner raw_spin_unlock_irqrestore(&rp->lock, flags); 1915ef53d9c5SSrinivasa D S } 1916e65cefe8SAdrian Bunk return 0; 1917e65cefe8SAdrian Bunk } 1918820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(pre_handler_kretprobe); 1919e65cefe8SAdrian Bunk 1920659b957fSNaveen N. Rao bool __weak arch_kprobe_on_func_entry(unsigned long offset) 192190ec5e89SNaveen N. Rao { 192290ec5e89SNaveen N. Rao return !offset; 192390ec5e89SNaveen N. Rao } 192490ec5e89SNaveen N. Rao 1925659b957fSNaveen N. Rao bool kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) 19261d585e70SNaveen N. Rao { 19271d585e70SNaveen N. Rao kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset); 19281d585e70SNaveen N. Rao 19291d585e70SNaveen N. Rao if (IS_ERR(kp_addr)) 19301d585e70SNaveen N. Rao return false; 19311d585e70SNaveen N. Rao 19321d585e70SNaveen N. Rao if (!kallsyms_lookup_size_offset((unsigned long)kp_addr, NULL, &offset) || 1933659b957fSNaveen N. Rao !arch_kprobe_on_func_entry(offset)) 19341d585e70SNaveen N. Rao return false; 19351d585e70SNaveen N. Rao 19361d585e70SNaveen N. Rao return true; 19371d585e70SNaveen N. Rao } 19381d585e70SNaveen N. Rao 193955479f64SMasami Hiramatsu int register_kretprobe(struct kretprobe *rp) 1940b94cce92SHien Nguyen { 1941b94cce92SHien Nguyen int ret = 0; 1942b94cce92SHien Nguyen struct kretprobe_instance *inst; 1943b94cce92SHien Nguyen int i; 1944b2a5cd69SMasami Hiramatsu void *addr; 194590ec5e89SNaveen N. Rao 1946659b957fSNaveen N. Rao if (!kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset)) 194790ec5e89SNaveen N. Rao return -EINVAL; 1948f438d914SMasami Hiramatsu 1949f438d914SMasami Hiramatsu if (kretprobe_blacklist_size) { 1950b2a5cd69SMasami Hiramatsu addr = kprobe_addr(&rp->kp); 1951bc81d48dSMasami Hiramatsu if (IS_ERR(addr)) 1952bc81d48dSMasami Hiramatsu return PTR_ERR(addr); 1953f438d914SMasami Hiramatsu 1954f438d914SMasami Hiramatsu for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { 1955f438d914SMasami Hiramatsu if (kretprobe_blacklist[i].addr == addr) 1956f438d914SMasami Hiramatsu return -EINVAL; 1957f438d914SMasami Hiramatsu } 1958f438d914SMasami Hiramatsu } 1959b94cce92SHien Nguyen 1960b94cce92SHien Nguyen rp->kp.pre_handler = pre_handler_kretprobe; 19617522a842SAnanth N Mavinakayanahalli rp->kp.post_handler = NULL; 19627522a842SAnanth N Mavinakayanahalli rp->kp.fault_handler = NULL; 1963b94cce92SHien Nguyen 1964b94cce92SHien Nguyen /* Pre-allocate memory for max kretprobe instances */ 1965b94cce92SHien Nguyen if (rp->maxactive <= 0) { 196692616606SThomas Gleixner #ifdef CONFIG_PREEMPTION 1967c2ef6661SHeiko Carstens rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus()); 1968b94cce92SHien Nguyen #else 19694dae560fSAnanth N Mavinakayanahalli rp->maxactive = num_possible_cpus(); 1970b94cce92SHien Nguyen #endif 1971b94cce92SHien Nguyen } 1972ec484608SThomas Gleixner raw_spin_lock_init(&rp->lock); 1973b94cce92SHien Nguyen INIT_HLIST_HEAD(&rp->free_instances); 1974b94cce92SHien Nguyen for (i = 0; i < rp->maxactive; i++) { 1975f47cd9b5SAbhishek Sagar inst = kmalloc(sizeof(struct kretprobe_instance) + 1976f47cd9b5SAbhishek Sagar rp->data_size, GFP_KERNEL); 1977b94cce92SHien Nguyen if (inst == NULL) { 1978b94cce92SHien Nguyen free_rp_inst(rp); 1979b94cce92SHien Nguyen return -ENOMEM; 1980b94cce92SHien Nguyen } 1981ef53d9c5SSrinivasa D S INIT_HLIST_NODE(&inst->hlist); 1982ef53d9c5SSrinivasa D S hlist_add_head(&inst->hlist, &rp->free_instances); 1983b94cce92SHien Nguyen } 1984b94cce92SHien Nguyen 1985b94cce92SHien Nguyen rp->nmissed = 0; 1986b94cce92SHien Nguyen /* Establish function entry probe point */ 198749ad2fd7SMasami Hiramatsu ret = register_kprobe(&rp->kp); 19884a296e07SMasami Hiramatsu if (ret != 0) 1989b94cce92SHien Nguyen free_rp_inst(rp); 1990b94cce92SHien Nguyen return ret; 1991b94cce92SHien Nguyen } 199299081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobe); 1993b94cce92SHien Nguyen 199455479f64SMasami Hiramatsu int register_kretprobes(struct kretprobe **rps, int num) 19954a296e07SMasami Hiramatsu { 19964a296e07SMasami Hiramatsu int ret = 0, i; 19974a296e07SMasami Hiramatsu 19984a296e07SMasami Hiramatsu if (num <= 0) 19994a296e07SMasami Hiramatsu return -EINVAL; 20004a296e07SMasami Hiramatsu for (i = 0; i < num; i++) { 200149ad2fd7SMasami Hiramatsu ret = register_kretprobe(rps[i]); 200267dddaadSMasami Hiramatsu if (ret < 0) { 200367dddaadSMasami Hiramatsu if (i > 0) 20044a296e07SMasami Hiramatsu unregister_kretprobes(rps, i); 20054a296e07SMasami Hiramatsu break; 20064a296e07SMasami Hiramatsu } 20074a296e07SMasami Hiramatsu } 20084a296e07SMasami Hiramatsu return ret; 20094a296e07SMasami Hiramatsu } 201099081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobes); 20114a296e07SMasami Hiramatsu 201255479f64SMasami Hiramatsu void unregister_kretprobe(struct kretprobe *rp) 20134a296e07SMasami Hiramatsu { 20144a296e07SMasami Hiramatsu unregister_kretprobes(&rp, 1); 20154a296e07SMasami Hiramatsu } 201699081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobe); 20174a296e07SMasami Hiramatsu 201855479f64SMasami Hiramatsu void unregister_kretprobes(struct kretprobe **rps, int num) 20194a296e07SMasami Hiramatsu { 20204a296e07SMasami Hiramatsu int i; 20214a296e07SMasami Hiramatsu 20224a296e07SMasami Hiramatsu if (num <= 0) 20234a296e07SMasami Hiramatsu return; 20244a296e07SMasami Hiramatsu mutex_lock(&kprobe_mutex); 20254a296e07SMasami Hiramatsu for (i = 0; i < num; i++) 20264a296e07SMasami Hiramatsu if (__unregister_kprobe_top(&rps[i]->kp) < 0) 20274a296e07SMasami Hiramatsu rps[i]->kp.addr = NULL; 20284a296e07SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 20294a296e07SMasami Hiramatsu 2030ae8b7ce7SPaul E. McKenney synchronize_rcu(); 20314a296e07SMasami Hiramatsu for (i = 0; i < num; i++) { 20324a296e07SMasami Hiramatsu if (rps[i]->kp.addr) { 20334a296e07SMasami Hiramatsu __unregister_kprobe_bottom(&rps[i]->kp); 20344a296e07SMasami Hiramatsu cleanup_rp_inst(rps[i]); 20354a296e07SMasami Hiramatsu } 20364a296e07SMasami Hiramatsu } 20374a296e07SMasami Hiramatsu } 203899081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobes); 20394a296e07SMasami Hiramatsu 20409edddaa2SAnanth N Mavinakayanahalli #else /* CONFIG_KRETPROBES */ 204155479f64SMasami Hiramatsu int register_kretprobe(struct kretprobe *rp) 2042b94cce92SHien Nguyen { 2043b94cce92SHien Nguyen return -ENOSYS; 2044b94cce92SHien Nguyen } 204599081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobe); 2046b94cce92SHien Nguyen 204755479f64SMasami Hiramatsu int register_kretprobes(struct kretprobe **rps, int num) 20484a296e07SMasami Hiramatsu { 20494a296e07SMasami Hiramatsu return -ENOSYS; 20504a296e07SMasami Hiramatsu } 205199081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobes); 205299081ab5SMasami Hiramatsu 205355479f64SMasami Hiramatsu void unregister_kretprobe(struct kretprobe *rp) 20544a296e07SMasami Hiramatsu { 20554a296e07SMasami Hiramatsu } 205699081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobe); 20574a296e07SMasami Hiramatsu 205855479f64SMasami Hiramatsu void unregister_kretprobes(struct kretprobe **rps, int num) 20594a296e07SMasami Hiramatsu { 20604a296e07SMasami Hiramatsu } 206199081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobes); 20624a296e07SMasami Hiramatsu 2063820aede0SMasami Hiramatsu static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) 2064346fd59bSSrinivasa Ds { 2065346fd59bSSrinivasa Ds return 0; 2066346fd59bSSrinivasa Ds } 2067820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(pre_handler_kretprobe); 20684a296e07SMasami Hiramatsu 20699edddaa2SAnanth N Mavinakayanahalli #endif /* CONFIG_KRETPROBES */ 2070b94cce92SHien Nguyen 2071e8386a0cSMasami Hiramatsu /* Set the kprobe gone and remove its instruction buffer. */ 207255479f64SMasami Hiramatsu static void kill_kprobe(struct kprobe *p) 2073e8386a0cSMasami Hiramatsu { 2074e8386a0cSMasami Hiramatsu struct kprobe *kp; 2075de5bd88dSMasami Hiramatsu 20767e6a71d8SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 20777e6a71d8SMasami Hiramatsu 2078e8386a0cSMasami Hiramatsu p->flags |= KPROBE_FLAG_GONE; 2079afd66255SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 2080e8386a0cSMasami Hiramatsu /* 2081e8386a0cSMasami Hiramatsu * If this is an aggr_kprobe, we have to list all the 2082e8386a0cSMasami Hiramatsu * chained probes and mark them GONE. 2083e8386a0cSMasami Hiramatsu */ 20847e6a71d8SMasami Hiramatsu list_for_each_entry(kp, &p->list, list) 2085e8386a0cSMasami Hiramatsu kp->flags |= KPROBE_FLAG_GONE; 2086e8386a0cSMasami Hiramatsu p->post_handler = NULL; 2087afd66255SMasami Hiramatsu kill_optimized_kprobe(p); 2088e8386a0cSMasami Hiramatsu } 2089e8386a0cSMasami Hiramatsu /* 2090e8386a0cSMasami Hiramatsu * Here, we can remove insn_slot safely, because no thread calls 2091e8386a0cSMasami Hiramatsu * the original probed function (which will be freed soon) any more. 2092e8386a0cSMasami Hiramatsu */ 2093e8386a0cSMasami Hiramatsu arch_remove_kprobe(p); 2094e8386a0cSMasami Hiramatsu } 2095e8386a0cSMasami Hiramatsu 2096c0614829SMasami Hiramatsu /* Disable one kprobe */ 209755479f64SMasami Hiramatsu int disable_kprobe(struct kprobe *kp) 2098c0614829SMasami Hiramatsu { 2099c0614829SMasami Hiramatsu int ret = 0; 2100297f9233SJessica Yu struct kprobe *p; 2101c0614829SMasami Hiramatsu 2102c0614829SMasami Hiramatsu mutex_lock(&kprobe_mutex); 2103c0614829SMasami Hiramatsu 21046f0f1dd7SMasami Hiramatsu /* Disable this kprobe */ 2105297f9233SJessica Yu p = __disable_kprobe(kp); 2106297f9233SJessica Yu if (IS_ERR(p)) 2107297f9233SJessica Yu ret = PTR_ERR(p); 2108c0614829SMasami Hiramatsu 2109c0614829SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2110c0614829SMasami Hiramatsu return ret; 2111c0614829SMasami Hiramatsu } 2112c0614829SMasami Hiramatsu EXPORT_SYMBOL_GPL(disable_kprobe); 2113c0614829SMasami Hiramatsu 2114c0614829SMasami Hiramatsu /* Enable one kprobe */ 211555479f64SMasami Hiramatsu int enable_kprobe(struct kprobe *kp) 2116c0614829SMasami Hiramatsu { 2117c0614829SMasami Hiramatsu int ret = 0; 2118c0614829SMasami Hiramatsu struct kprobe *p; 2119c0614829SMasami Hiramatsu 2120c0614829SMasami Hiramatsu mutex_lock(&kprobe_mutex); 2121c0614829SMasami Hiramatsu 2122c0614829SMasami Hiramatsu /* Check whether specified probe is valid. */ 2123c0614829SMasami Hiramatsu p = __get_valid_kprobe(kp); 2124c0614829SMasami Hiramatsu if (unlikely(p == NULL)) { 2125c0614829SMasami Hiramatsu ret = -EINVAL; 2126c0614829SMasami Hiramatsu goto out; 2127c0614829SMasami Hiramatsu } 2128c0614829SMasami Hiramatsu 2129c0614829SMasami Hiramatsu if (kprobe_gone(kp)) { 2130c0614829SMasami Hiramatsu /* This kprobe has gone, we couldn't enable it. */ 2131c0614829SMasami Hiramatsu ret = -EINVAL; 2132c0614829SMasami Hiramatsu goto out; 2133c0614829SMasami Hiramatsu } 2134c0614829SMasami Hiramatsu 2135c0614829SMasami Hiramatsu if (p != kp) 2136c0614829SMasami Hiramatsu kp->flags &= ~KPROBE_FLAG_DISABLED; 2137c0614829SMasami Hiramatsu 2138c0614829SMasami Hiramatsu if (!kprobes_all_disarmed && kprobe_disabled(p)) { 2139c0614829SMasami Hiramatsu p->flags &= ~KPROBE_FLAG_DISABLED; 214012310e34SJessica Yu ret = arm_kprobe(p); 214112310e34SJessica Yu if (ret) 214212310e34SJessica Yu p->flags |= KPROBE_FLAG_DISABLED; 2143c0614829SMasami Hiramatsu } 2144c0614829SMasami Hiramatsu out: 2145c0614829SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2146c0614829SMasami Hiramatsu return ret; 2147c0614829SMasami Hiramatsu } 2148c0614829SMasami Hiramatsu EXPORT_SYMBOL_GPL(enable_kprobe); 2149c0614829SMasami Hiramatsu 21504458515bSMasami Hiramatsu /* Caller must NOT call this in usual path. This is only for critical case */ 2151820aede0SMasami Hiramatsu void dump_kprobe(struct kprobe *kp) 215224851d24SFrederic Weisbecker { 21534458515bSMasami Hiramatsu pr_err("Dumping kprobe:\n"); 21544458515bSMasami Hiramatsu pr_err("Name: %s\nOffset: %x\nAddress: %pS\n", 21554458515bSMasami Hiramatsu kp->symbol_name, kp->offset, kp->addr); 215624851d24SFrederic Weisbecker } 2157820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(dump_kprobe); 215824851d24SFrederic Weisbecker 2159fb1a59faSMasami Hiramatsu int kprobe_add_ksym_blacklist(unsigned long entry) 2160fb1a59faSMasami Hiramatsu { 2161fb1a59faSMasami Hiramatsu struct kprobe_blacklist_entry *ent; 2162fb1a59faSMasami Hiramatsu unsigned long offset = 0, size = 0; 2163fb1a59faSMasami Hiramatsu 2164fb1a59faSMasami Hiramatsu if (!kernel_text_address(entry) || 2165fb1a59faSMasami Hiramatsu !kallsyms_lookup_size_offset(entry, &size, &offset)) 2166fb1a59faSMasami Hiramatsu return -EINVAL; 2167fb1a59faSMasami Hiramatsu 2168fb1a59faSMasami Hiramatsu ent = kmalloc(sizeof(*ent), GFP_KERNEL); 2169fb1a59faSMasami Hiramatsu if (!ent) 2170fb1a59faSMasami Hiramatsu return -ENOMEM; 2171fb1a59faSMasami Hiramatsu ent->start_addr = entry; 2172fb1a59faSMasami Hiramatsu ent->end_addr = entry + size; 2173fb1a59faSMasami Hiramatsu INIT_LIST_HEAD(&ent->list); 2174fb1a59faSMasami Hiramatsu list_add_tail(&ent->list, &kprobe_blacklist); 2175fb1a59faSMasami Hiramatsu 2176fb1a59faSMasami Hiramatsu return (int)size; 2177fb1a59faSMasami Hiramatsu } 2178fb1a59faSMasami Hiramatsu 2179fb1a59faSMasami Hiramatsu /* Add all symbols in given area into kprobe blacklist */ 2180fb1a59faSMasami Hiramatsu int kprobe_add_area_blacklist(unsigned long start, unsigned long end) 2181fb1a59faSMasami Hiramatsu { 2182fb1a59faSMasami Hiramatsu unsigned long entry; 2183fb1a59faSMasami Hiramatsu int ret = 0; 2184fb1a59faSMasami Hiramatsu 2185fb1a59faSMasami Hiramatsu for (entry = start; entry < end; entry += ret) { 2186fb1a59faSMasami Hiramatsu ret = kprobe_add_ksym_blacklist(entry); 2187fb1a59faSMasami Hiramatsu if (ret < 0) 2188fb1a59faSMasami Hiramatsu return ret; 2189fb1a59faSMasami Hiramatsu if (ret == 0) /* In case of alias symbol */ 2190fb1a59faSMasami Hiramatsu ret = 1; 2191fb1a59faSMasami Hiramatsu } 2192fb1a59faSMasami Hiramatsu return 0; 2193fb1a59faSMasami Hiramatsu } 2194fb1a59faSMasami Hiramatsu 21951e6769b0SMasami Hiramatsu /* Remove all symbols in given area from kprobe blacklist */ 21961e6769b0SMasami Hiramatsu static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end) 21971e6769b0SMasami Hiramatsu { 21981e6769b0SMasami Hiramatsu struct kprobe_blacklist_entry *ent, *n; 21991e6769b0SMasami Hiramatsu 22001e6769b0SMasami Hiramatsu list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) { 22011e6769b0SMasami Hiramatsu if (ent->start_addr < start || ent->start_addr >= end) 22021e6769b0SMasami Hiramatsu continue; 22031e6769b0SMasami Hiramatsu list_del(&ent->list); 22041e6769b0SMasami Hiramatsu kfree(ent); 22051e6769b0SMasami Hiramatsu } 22061e6769b0SMasami Hiramatsu } 22071e6769b0SMasami Hiramatsu 220816db6264SMasami Hiramatsu static void kprobe_remove_ksym_blacklist(unsigned long entry) 220916db6264SMasami Hiramatsu { 221016db6264SMasami Hiramatsu kprobe_remove_area_blacklist(entry, entry + 1); 221116db6264SMasami Hiramatsu } 221216db6264SMasami Hiramatsu 2213fb1a59faSMasami Hiramatsu int __init __weak arch_populate_kprobe_blacklist(void) 2214fb1a59faSMasami Hiramatsu { 2215fb1a59faSMasami Hiramatsu return 0; 2216fb1a59faSMasami Hiramatsu } 2217fb1a59faSMasami Hiramatsu 2218376e2424SMasami Hiramatsu /* 2219376e2424SMasami Hiramatsu * Lookup and populate the kprobe_blacklist. 2220376e2424SMasami Hiramatsu * 2221376e2424SMasami Hiramatsu * Unlike the kretprobe blacklist, we'll need to determine 2222376e2424SMasami Hiramatsu * the range of addresses that belong to the said functions, 2223376e2424SMasami Hiramatsu * since a kprobe need not necessarily be at the beginning 2224376e2424SMasami Hiramatsu * of a function. 2225376e2424SMasami Hiramatsu */ 2226376e2424SMasami Hiramatsu static int __init populate_kprobe_blacklist(unsigned long *start, 2227376e2424SMasami Hiramatsu unsigned long *end) 2228376e2424SMasami Hiramatsu { 2229fb1a59faSMasami Hiramatsu unsigned long entry; 2230376e2424SMasami Hiramatsu unsigned long *iter; 2231fb1a59faSMasami Hiramatsu int ret; 2232376e2424SMasami Hiramatsu 2233376e2424SMasami Hiramatsu for (iter = start; iter < end; iter++) { 2234d81b4253SMasami Hiramatsu entry = arch_deref_entry_point((void *)*iter); 2235fb1a59faSMasami Hiramatsu ret = kprobe_add_ksym_blacklist(entry); 2236fb1a59faSMasami Hiramatsu if (ret == -EINVAL) 2237376e2424SMasami Hiramatsu continue; 2238fb1a59faSMasami Hiramatsu if (ret < 0) 2239fb1a59faSMasami Hiramatsu return ret; 2240376e2424SMasami Hiramatsu } 2241fb1a59faSMasami Hiramatsu 2242fb1a59faSMasami Hiramatsu /* Symbols in __kprobes_text are blacklisted */ 2243fb1a59faSMasami Hiramatsu ret = kprobe_add_area_blacklist((unsigned long)__kprobes_text_start, 2244fb1a59faSMasami Hiramatsu (unsigned long)__kprobes_text_end); 224566e9b071SThomas Gleixner if (ret) 224666e9b071SThomas Gleixner return ret; 224766e9b071SThomas Gleixner 224866e9b071SThomas Gleixner /* Symbols in noinstr section are blacklisted */ 224966e9b071SThomas Gleixner ret = kprobe_add_area_blacklist((unsigned long)__noinstr_text_start, 225066e9b071SThomas Gleixner (unsigned long)__noinstr_text_end); 2251fb1a59faSMasami Hiramatsu 2252fb1a59faSMasami Hiramatsu return ret ? : arch_populate_kprobe_blacklist(); 2253376e2424SMasami Hiramatsu } 2254376e2424SMasami Hiramatsu 22551e6769b0SMasami Hiramatsu static void add_module_kprobe_blacklist(struct module *mod) 22561e6769b0SMasami Hiramatsu { 22571e6769b0SMasami Hiramatsu unsigned long start, end; 225816db6264SMasami Hiramatsu int i; 225916db6264SMasami Hiramatsu 226016db6264SMasami Hiramatsu if (mod->kprobe_blacklist) { 226116db6264SMasami Hiramatsu for (i = 0; i < mod->num_kprobe_blacklist; i++) 226216db6264SMasami Hiramatsu kprobe_add_ksym_blacklist(mod->kprobe_blacklist[i]); 226316db6264SMasami Hiramatsu } 22641e6769b0SMasami Hiramatsu 22651e6769b0SMasami Hiramatsu start = (unsigned long)mod->kprobes_text_start; 22661e6769b0SMasami Hiramatsu if (start) { 22671e6769b0SMasami Hiramatsu end = start + mod->kprobes_text_size; 22681e6769b0SMasami Hiramatsu kprobe_add_area_blacklist(start, end); 22691e6769b0SMasami Hiramatsu } 227066e9b071SThomas Gleixner 227166e9b071SThomas Gleixner start = (unsigned long)mod->noinstr_text_start; 227266e9b071SThomas Gleixner if (start) { 227366e9b071SThomas Gleixner end = start + mod->noinstr_text_size; 227466e9b071SThomas Gleixner kprobe_add_area_blacklist(start, end); 227566e9b071SThomas Gleixner } 22761e6769b0SMasami Hiramatsu } 22771e6769b0SMasami Hiramatsu 22781e6769b0SMasami Hiramatsu static void remove_module_kprobe_blacklist(struct module *mod) 22791e6769b0SMasami Hiramatsu { 22801e6769b0SMasami Hiramatsu unsigned long start, end; 228116db6264SMasami Hiramatsu int i; 228216db6264SMasami Hiramatsu 228316db6264SMasami Hiramatsu if (mod->kprobe_blacklist) { 228416db6264SMasami Hiramatsu for (i = 0; i < mod->num_kprobe_blacklist; i++) 228516db6264SMasami Hiramatsu kprobe_remove_ksym_blacklist(mod->kprobe_blacklist[i]); 228616db6264SMasami Hiramatsu } 22871e6769b0SMasami Hiramatsu 22881e6769b0SMasami Hiramatsu start = (unsigned long)mod->kprobes_text_start; 22891e6769b0SMasami Hiramatsu if (start) { 22901e6769b0SMasami Hiramatsu end = start + mod->kprobes_text_size; 22911e6769b0SMasami Hiramatsu kprobe_remove_area_blacklist(start, end); 22921e6769b0SMasami Hiramatsu } 229366e9b071SThomas Gleixner 229466e9b071SThomas Gleixner start = (unsigned long)mod->noinstr_text_start; 229566e9b071SThomas Gleixner if (start) { 229666e9b071SThomas Gleixner end = start + mod->noinstr_text_size; 229766e9b071SThomas Gleixner kprobe_remove_area_blacklist(start, end); 229866e9b071SThomas Gleixner } 22991e6769b0SMasami Hiramatsu } 23001e6769b0SMasami Hiramatsu 2301e8386a0cSMasami Hiramatsu /* Module notifier call back, checking kprobes on the module */ 230255479f64SMasami Hiramatsu static int kprobes_module_callback(struct notifier_block *nb, 2303e8386a0cSMasami Hiramatsu unsigned long val, void *data) 2304e8386a0cSMasami Hiramatsu { 2305e8386a0cSMasami Hiramatsu struct module *mod = data; 2306e8386a0cSMasami Hiramatsu struct hlist_head *head; 2307e8386a0cSMasami Hiramatsu struct kprobe *p; 2308e8386a0cSMasami Hiramatsu unsigned int i; 2309f24659d9SMasami Hiramatsu int checkcore = (val == MODULE_STATE_GOING); 2310e8386a0cSMasami Hiramatsu 23111e6769b0SMasami Hiramatsu if (val == MODULE_STATE_COMING) { 23121e6769b0SMasami Hiramatsu mutex_lock(&kprobe_mutex); 23131e6769b0SMasami Hiramatsu add_module_kprobe_blacklist(mod); 23141e6769b0SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 23151e6769b0SMasami Hiramatsu } 2316f24659d9SMasami Hiramatsu if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE) 2317e8386a0cSMasami Hiramatsu return NOTIFY_DONE; 2318e8386a0cSMasami Hiramatsu 2319e8386a0cSMasami Hiramatsu /* 2320f24659d9SMasami Hiramatsu * When MODULE_STATE_GOING was notified, both of module .text and 2321f24659d9SMasami Hiramatsu * .init.text sections would be freed. When MODULE_STATE_LIVE was 2322f24659d9SMasami Hiramatsu * notified, only .init.text section would be freed. We need to 2323f24659d9SMasami Hiramatsu * disable kprobes which have been inserted in the sections. 2324e8386a0cSMasami Hiramatsu */ 2325e8386a0cSMasami Hiramatsu mutex_lock(&kprobe_mutex); 2326e8386a0cSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 2327e8386a0cSMasami Hiramatsu head = &kprobe_table[i]; 23287e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) 2329f24659d9SMasami Hiramatsu if (within_module_init((unsigned long)p->addr, mod) || 2330f24659d9SMasami Hiramatsu (checkcore && 2331f24659d9SMasami Hiramatsu within_module_core((unsigned long)p->addr, mod))) { 2332e8386a0cSMasami Hiramatsu /* 2333e8386a0cSMasami Hiramatsu * The vaddr this probe is installed will soon 2334e8386a0cSMasami Hiramatsu * be vfreed buy not synced to disk. Hence, 2335e8386a0cSMasami Hiramatsu * disarming the breakpoint isn't needed. 2336545a0281SSteven Rostedt (VMware) * 2337545a0281SSteven Rostedt (VMware) * Note, this will also move any optimized probes 2338545a0281SSteven Rostedt (VMware) * that are pending to be removed from their 2339545a0281SSteven Rostedt (VMware) * corresponding lists to the freeing_list and 2340545a0281SSteven Rostedt (VMware) * will not be touched by the delayed 2341545a0281SSteven Rostedt (VMware) * kprobe_optimizer work handler. 2342e8386a0cSMasami Hiramatsu */ 2343e8386a0cSMasami Hiramatsu kill_kprobe(p); 2344e8386a0cSMasami Hiramatsu } 2345e8386a0cSMasami Hiramatsu } 23461e6769b0SMasami Hiramatsu if (val == MODULE_STATE_GOING) 23471e6769b0SMasami Hiramatsu remove_module_kprobe_blacklist(mod); 2348e8386a0cSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2349e8386a0cSMasami Hiramatsu return NOTIFY_DONE; 2350e8386a0cSMasami Hiramatsu } 2351e8386a0cSMasami Hiramatsu 2352e8386a0cSMasami Hiramatsu static struct notifier_block kprobe_module_nb = { 2353e8386a0cSMasami Hiramatsu .notifier_call = kprobes_module_callback, 2354e8386a0cSMasami Hiramatsu .priority = 0 2355e8386a0cSMasami Hiramatsu }; 2356e8386a0cSMasami Hiramatsu 2357376e2424SMasami Hiramatsu /* Markers of _kprobe_blacklist section */ 2358376e2424SMasami Hiramatsu extern unsigned long __start_kprobe_blacklist[]; 2359376e2424SMasami Hiramatsu extern unsigned long __stop_kprobe_blacklist[]; 2360376e2424SMasami Hiramatsu 23611da177e4SLinus Torvalds static int __init init_kprobes(void) 23621da177e4SLinus Torvalds { 23631da177e4SLinus Torvalds int i, err = 0; 23641da177e4SLinus Torvalds 23651da177e4SLinus Torvalds /* FIXME allocate the probe table, currently defined statically */ 23661da177e4SLinus Torvalds /* initialize all list heads */ 2367b94cce92SHien Nguyen for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 23681da177e4SLinus Torvalds INIT_HLIST_HEAD(&kprobe_table[i]); 2369b94cce92SHien Nguyen INIT_HLIST_HEAD(&kretprobe_inst_table[i]); 2370ec484608SThomas Gleixner raw_spin_lock_init(&(kretprobe_table_locks[i].lock)); 2371b94cce92SHien Nguyen } 23721da177e4SLinus Torvalds 2373376e2424SMasami Hiramatsu err = populate_kprobe_blacklist(__start_kprobe_blacklist, 2374376e2424SMasami Hiramatsu __stop_kprobe_blacklist); 2375376e2424SMasami Hiramatsu if (err) { 2376376e2424SMasami Hiramatsu pr_err("kprobes: failed to populate blacklist: %d\n", err); 2377376e2424SMasami Hiramatsu pr_err("Please take care of using kprobes.\n"); 23783d8d996eSSrinivasa Ds } 23793d8d996eSSrinivasa Ds 2380f438d914SMasami Hiramatsu if (kretprobe_blacklist_size) { 2381f438d914SMasami Hiramatsu /* lookup the function address from its name */ 2382f438d914SMasami Hiramatsu for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { 238349e0b465SNaveen N. Rao kretprobe_blacklist[i].addr = 2384290e3070SNaveen N. Rao kprobe_lookup_name(kretprobe_blacklist[i].name, 0); 2385f438d914SMasami Hiramatsu if (!kretprobe_blacklist[i].addr) 2386f438d914SMasami Hiramatsu printk("kretprobe: lookup failed: %s\n", 2387f438d914SMasami Hiramatsu kretprobe_blacklist[i].name); 2388f438d914SMasami Hiramatsu } 2389f438d914SMasami Hiramatsu } 2390f438d914SMasami Hiramatsu 2391b2be84dfSMasami Hiramatsu #if defined(CONFIG_OPTPROBES) 2392b2be84dfSMasami Hiramatsu #if defined(__ARCH_WANT_KPROBES_INSN_SLOT) 2393afd66255SMasami Hiramatsu /* Init kprobe_optinsn_slots */ 2394afd66255SMasami Hiramatsu kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; 2395afd66255SMasami Hiramatsu #endif 2396b2be84dfSMasami Hiramatsu /* By default, kprobes can be optimized */ 2397b2be84dfSMasami Hiramatsu kprobes_allow_optimization = true; 2398b2be84dfSMasami Hiramatsu #endif 2399afd66255SMasami Hiramatsu 2400e579abebSMasami Hiramatsu /* By default, kprobes are armed */ 2401e579abebSMasami Hiramatsu kprobes_all_disarmed = false; 2402bf8f6e5bSAnanth N Mavinakayanahalli 24036772926bSRusty Lynch err = arch_init_kprobes(); 2404802eae7cSRusty Lynch if (!err) 24051da177e4SLinus Torvalds err = register_die_notifier(&kprobe_exceptions_nb); 2406e8386a0cSMasami Hiramatsu if (!err) 2407e8386a0cSMasami Hiramatsu err = register_module_notifier(&kprobe_module_nb); 2408e8386a0cSMasami Hiramatsu 2409ef53d9c5SSrinivasa D S kprobes_initialized = (err == 0); 2410802eae7cSRusty Lynch 24118c1c9356SAnanth N Mavinakayanahalli if (!err) 24128c1c9356SAnanth N Mavinakayanahalli init_test_probes(); 24131da177e4SLinus Torvalds return err; 24141da177e4SLinus Torvalds } 241565fc965cSMasami Hiramatsu subsys_initcall(init_kprobes); 24161da177e4SLinus Torvalds 2417346fd59bSSrinivasa Ds #ifdef CONFIG_DEBUG_FS 241855479f64SMasami Hiramatsu static void report_probe(struct seq_file *pi, struct kprobe *p, 2419afd66255SMasami Hiramatsu const char *sym, int offset, char *modname, struct kprobe *pp) 2420346fd59bSSrinivasa Ds { 2421346fd59bSSrinivasa Ds char *kprobe_type; 242281365a94SMasami Hiramatsu void *addr = p->addr; 2423346fd59bSSrinivasa Ds 2424346fd59bSSrinivasa Ds if (p->pre_handler == pre_handler_kretprobe) 2425346fd59bSSrinivasa Ds kprobe_type = "r"; 2426346fd59bSSrinivasa Ds else 2427346fd59bSSrinivasa Ds kprobe_type = "k"; 2428afd66255SMasami Hiramatsu 242981365a94SMasami Hiramatsu if (!kallsyms_show_value()) 243081365a94SMasami Hiramatsu addr = NULL; 243181365a94SMasami Hiramatsu 2432346fd59bSSrinivasa Ds if (sym) 243381365a94SMasami Hiramatsu seq_printf(pi, "%px %s %s+0x%x %s ", 243481365a94SMasami Hiramatsu addr, kprobe_type, sym, offset, 2435afd66255SMasami Hiramatsu (modname ? modname : " ")); 243681365a94SMasami Hiramatsu else /* try to use %pS */ 243781365a94SMasami Hiramatsu seq_printf(pi, "%px %s %pS ", 243881365a94SMasami Hiramatsu addr, kprobe_type, p->addr); 2439afd66255SMasami Hiramatsu 2440afd66255SMasami Hiramatsu if (!pp) 2441afd66255SMasami Hiramatsu pp = p; 2442ae6aa16fSMasami Hiramatsu seq_printf(pi, "%s%s%s%s\n", 2443de5bd88dSMasami Hiramatsu (kprobe_gone(p) ? "[GONE]" : ""), 2444afd66255SMasami Hiramatsu ((kprobe_disabled(p) && !kprobe_gone(p)) ? "[DISABLED]" : ""), 2445ae6aa16fSMasami Hiramatsu (kprobe_optimized(pp) ? "[OPTIMIZED]" : ""), 2446ae6aa16fSMasami Hiramatsu (kprobe_ftrace(pp) ? "[FTRACE]" : "")); 2447346fd59bSSrinivasa Ds } 2448346fd59bSSrinivasa Ds 244955479f64SMasami Hiramatsu static void *kprobe_seq_start(struct seq_file *f, loff_t *pos) 2450346fd59bSSrinivasa Ds { 2451346fd59bSSrinivasa Ds return (*pos < KPROBE_TABLE_SIZE) ? pos : NULL; 2452346fd59bSSrinivasa Ds } 2453346fd59bSSrinivasa Ds 245455479f64SMasami Hiramatsu static void *kprobe_seq_next(struct seq_file *f, void *v, loff_t *pos) 2455346fd59bSSrinivasa Ds { 2456346fd59bSSrinivasa Ds (*pos)++; 2457346fd59bSSrinivasa Ds if (*pos >= KPROBE_TABLE_SIZE) 2458346fd59bSSrinivasa Ds return NULL; 2459346fd59bSSrinivasa Ds return pos; 2460346fd59bSSrinivasa Ds } 2461346fd59bSSrinivasa Ds 246255479f64SMasami Hiramatsu static void kprobe_seq_stop(struct seq_file *f, void *v) 2463346fd59bSSrinivasa Ds { 2464346fd59bSSrinivasa Ds /* Nothing to do */ 2465346fd59bSSrinivasa Ds } 2466346fd59bSSrinivasa Ds 246755479f64SMasami Hiramatsu static int show_kprobe_addr(struct seq_file *pi, void *v) 2468346fd59bSSrinivasa Ds { 2469346fd59bSSrinivasa Ds struct hlist_head *head; 2470346fd59bSSrinivasa Ds struct kprobe *p, *kp; 2471346fd59bSSrinivasa Ds const char *sym = NULL; 2472346fd59bSSrinivasa Ds unsigned int i = *(loff_t *) v; 2473ffb45122SAlexey Dobriyan unsigned long offset = 0; 2474ab767865SJoe Mario char *modname, namebuf[KSYM_NAME_LEN]; 2475346fd59bSSrinivasa Ds 2476346fd59bSSrinivasa Ds head = &kprobe_table[i]; 2477346fd59bSSrinivasa Ds preempt_disable(); 2478b67bfe0dSSasha Levin hlist_for_each_entry_rcu(p, head, hlist) { 2479ffb45122SAlexey Dobriyan sym = kallsyms_lookup((unsigned long)p->addr, NULL, 2480346fd59bSSrinivasa Ds &offset, &modname, namebuf); 2481afd66255SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 2482346fd59bSSrinivasa Ds list_for_each_entry_rcu(kp, &p->list, list) 2483afd66255SMasami Hiramatsu report_probe(pi, kp, sym, offset, modname, p); 2484346fd59bSSrinivasa Ds } else 2485afd66255SMasami Hiramatsu report_probe(pi, p, sym, offset, modname, NULL); 2486346fd59bSSrinivasa Ds } 2487346fd59bSSrinivasa Ds preempt_enable(); 2488346fd59bSSrinivasa Ds return 0; 2489346fd59bSSrinivasa Ds } 2490346fd59bSSrinivasa Ds 2491eac2ceceSKefeng Wang static const struct seq_operations kprobes_sops = { 2492346fd59bSSrinivasa Ds .start = kprobe_seq_start, 2493346fd59bSSrinivasa Ds .next = kprobe_seq_next, 2494346fd59bSSrinivasa Ds .stop = kprobe_seq_stop, 2495346fd59bSSrinivasa Ds .show = show_kprobe_addr 2496346fd59bSSrinivasa Ds }; 2497346fd59bSSrinivasa Ds 2498eac2ceceSKefeng Wang DEFINE_SEQ_ATTRIBUTE(kprobes); 2499346fd59bSSrinivasa Ds 250063724740SMasami Hiramatsu /* kprobes/blacklist -- shows which functions can not be probed */ 250163724740SMasami Hiramatsu static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos) 250263724740SMasami Hiramatsu { 25034fdd8887SMasami Hiramatsu mutex_lock(&kprobe_mutex); 250463724740SMasami Hiramatsu return seq_list_start(&kprobe_blacklist, *pos); 250563724740SMasami Hiramatsu } 250663724740SMasami Hiramatsu 250763724740SMasami Hiramatsu static void *kprobe_blacklist_seq_next(struct seq_file *m, void *v, loff_t *pos) 250863724740SMasami Hiramatsu { 250963724740SMasami Hiramatsu return seq_list_next(v, &kprobe_blacklist, pos); 251063724740SMasami Hiramatsu } 251163724740SMasami Hiramatsu 251263724740SMasami Hiramatsu static int kprobe_blacklist_seq_show(struct seq_file *m, void *v) 251363724740SMasami Hiramatsu { 251463724740SMasami Hiramatsu struct kprobe_blacklist_entry *ent = 251563724740SMasami Hiramatsu list_entry(v, struct kprobe_blacklist_entry, list); 251663724740SMasami Hiramatsu 2517ffb9bd68SMasami Hiramatsu /* 2518ffb9bd68SMasami Hiramatsu * If /proc/kallsyms is not showing kernel address, we won't 2519ffb9bd68SMasami Hiramatsu * show them here either. 2520ffb9bd68SMasami Hiramatsu */ 2521ffb9bd68SMasami Hiramatsu if (!kallsyms_show_value()) 2522ffb9bd68SMasami Hiramatsu seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL, 2523ffb9bd68SMasami Hiramatsu (void *)ent->start_addr); 2524ffb9bd68SMasami Hiramatsu else 2525bcbd385bSThomas Richter seq_printf(m, "0x%px-0x%px\t%ps\n", (void *)ent->start_addr, 252663724740SMasami Hiramatsu (void *)ent->end_addr, (void *)ent->start_addr); 252763724740SMasami Hiramatsu return 0; 252863724740SMasami Hiramatsu } 252963724740SMasami Hiramatsu 25304fdd8887SMasami Hiramatsu static void kprobe_blacklist_seq_stop(struct seq_file *f, void *v) 25314fdd8887SMasami Hiramatsu { 25324fdd8887SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 25334fdd8887SMasami Hiramatsu } 25344fdd8887SMasami Hiramatsu 2535eac2ceceSKefeng Wang static const struct seq_operations kprobe_blacklist_sops = { 253663724740SMasami Hiramatsu .start = kprobe_blacklist_seq_start, 253763724740SMasami Hiramatsu .next = kprobe_blacklist_seq_next, 25384fdd8887SMasami Hiramatsu .stop = kprobe_blacklist_seq_stop, 253963724740SMasami Hiramatsu .show = kprobe_blacklist_seq_show, 254063724740SMasami Hiramatsu }; 2541eac2ceceSKefeng Wang DEFINE_SEQ_ATTRIBUTE(kprobe_blacklist); 254263724740SMasami Hiramatsu 254312310e34SJessica Yu static int arm_all_kprobes(void) 2544bf8f6e5bSAnanth N Mavinakayanahalli { 2545bf8f6e5bSAnanth N Mavinakayanahalli struct hlist_head *head; 2546bf8f6e5bSAnanth N Mavinakayanahalli struct kprobe *p; 254712310e34SJessica Yu unsigned int i, total = 0, errors = 0; 254812310e34SJessica Yu int err, ret = 0; 2549bf8f6e5bSAnanth N Mavinakayanahalli 2550bf8f6e5bSAnanth N Mavinakayanahalli mutex_lock(&kprobe_mutex); 2551bf8f6e5bSAnanth N Mavinakayanahalli 2552e579abebSMasami Hiramatsu /* If kprobes are armed, just return */ 2553e579abebSMasami Hiramatsu if (!kprobes_all_disarmed) 2554bf8f6e5bSAnanth N Mavinakayanahalli goto already_enabled; 2555bf8f6e5bSAnanth N Mavinakayanahalli 2556977ad481SWang Nan /* 2557977ad481SWang Nan * optimize_kprobe() called by arm_kprobe() checks 2558977ad481SWang Nan * kprobes_all_disarmed, so set kprobes_all_disarmed before 2559977ad481SWang Nan * arm_kprobe. 2560977ad481SWang Nan */ 2561977ad481SWang Nan kprobes_all_disarmed = false; 2562afd66255SMasami Hiramatsu /* Arming kprobes doesn't optimize kprobe itself */ 2563bf8f6e5bSAnanth N Mavinakayanahalli for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 2564bf8f6e5bSAnanth N Mavinakayanahalli head = &kprobe_table[i]; 256512310e34SJessica Yu /* Arm all kprobes on a best-effort basis */ 25667e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 256712310e34SJessica Yu if (!kprobe_disabled(p)) { 256812310e34SJessica Yu err = arm_kprobe(p); 256912310e34SJessica Yu if (err) { 257012310e34SJessica Yu errors++; 257112310e34SJessica Yu ret = err; 257212310e34SJessica Yu } 257312310e34SJessica Yu total++; 257412310e34SJessica Yu } 257512310e34SJessica Yu } 2576bf8f6e5bSAnanth N Mavinakayanahalli } 2577bf8f6e5bSAnanth N Mavinakayanahalli 257812310e34SJessica Yu if (errors) 257912310e34SJessica Yu pr_warn("Kprobes globally enabled, but failed to arm %d out of %d probes\n", 258012310e34SJessica Yu errors, total); 258112310e34SJessica Yu else 258212310e34SJessica Yu pr_info("Kprobes globally enabled\n"); 2583bf8f6e5bSAnanth N Mavinakayanahalli 2584bf8f6e5bSAnanth N Mavinakayanahalli already_enabled: 2585bf8f6e5bSAnanth N Mavinakayanahalli mutex_unlock(&kprobe_mutex); 258612310e34SJessica Yu return ret; 2587bf8f6e5bSAnanth N Mavinakayanahalli } 2588bf8f6e5bSAnanth N Mavinakayanahalli 2589297f9233SJessica Yu static int disarm_all_kprobes(void) 2590bf8f6e5bSAnanth N Mavinakayanahalli { 2591bf8f6e5bSAnanth N Mavinakayanahalli struct hlist_head *head; 2592bf8f6e5bSAnanth N Mavinakayanahalli struct kprobe *p; 2593297f9233SJessica Yu unsigned int i, total = 0, errors = 0; 2594297f9233SJessica Yu int err, ret = 0; 2595bf8f6e5bSAnanth N Mavinakayanahalli 2596bf8f6e5bSAnanth N Mavinakayanahalli mutex_lock(&kprobe_mutex); 2597bf8f6e5bSAnanth N Mavinakayanahalli 2598e579abebSMasami Hiramatsu /* If kprobes are already disarmed, just return */ 25996274de49SMasami Hiramatsu if (kprobes_all_disarmed) { 26006274de49SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2601297f9233SJessica Yu return 0; 26026274de49SMasami Hiramatsu } 2603bf8f6e5bSAnanth N Mavinakayanahalli 2604e579abebSMasami Hiramatsu kprobes_all_disarmed = true; 2605afd66255SMasami Hiramatsu 2606bf8f6e5bSAnanth N Mavinakayanahalli for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 2607bf8f6e5bSAnanth N Mavinakayanahalli head = &kprobe_table[i]; 2608297f9233SJessica Yu /* Disarm all kprobes on a best-effort basis */ 26097e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 2610297f9233SJessica Yu if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) { 2611297f9233SJessica Yu err = disarm_kprobe(p, false); 2612297f9233SJessica Yu if (err) { 2613297f9233SJessica Yu errors++; 2614297f9233SJessica Yu ret = err; 2615297f9233SJessica Yu } 2616297f9233SJessica Yu total++; 2617bf8f6e5bSAnanth N Mavinakayanahalli } 2618bf8f6e5bSAnanth N Mavinakayanahalli } 2619297f9233SJessica Yu } 2620297f9233SJessica Yu 2621297f9233SJessica Yu if (errors) 2622297f9233SJessica Yu pr_warn("Kprobes globally disabled, but failed to disarm %d out of %d probes\n", 2623297f9233SJessica Yu errors, total); 2624297f9233SJessica Yu else 2625297f9233SJessica Yu pr_info("Kprobes globally disabled\n"); 2626297f9233SJessica Yu 2627bf8f6e5bSAnanth N Mavinakayanahalli mutex_unlock(&kprobe_mutex); 2628bf8f6e5bSAnanth N Mavinakayanahalli 26296274de49SMasami Hiramatsu /* Wait for disarming all kprobes by optimizer */ 26306274de49SMasami Hiramatsu wait_for_kprobe_optimizer(); 2631297f9233SJessica Yu 2632297f9233SJessica Yu return ret; 2633bf8f6e5bSAnanth N Mavinakayanahalli } 2634bf8f6e5bSAnanth N Mavinakayanahalli 2635bf8f6e5bSAnanth N Mavinakayanahalli /* 2636bf8f6e5bSAnanth N Mavinakayanahalli * XXX: The debugfs bool file interface doesn't allow for callbacks 2637bf8f6e5bSAnanth N Mavinakayanahalli * when the bool state is switched. We can reuse that facility when 2638bf8f6e5bSAnanth N Mavinakayanahalli * available 2639bf8f6e5bSAnanth N Mavinakayanahalli */ 2640bf8f6e5bSAnanth N Mavinakayanahalli static ssize_t read_enabled_file_bool(struct file *file, 2641bf8f6e5bSAnanth N Mavinakayanahalli char __user *user_buf, size_t count, loff_t *ppos) 2642bf8f6e5bSAnanth N Mavinakayanahalli { 2643bf8f6e5bSAnanth N Mavinakayanahalli char buf[3]; 2644bf8f6e5bSAnanth N Mavinakayanahalli 2645e579abebSMasami Hiramatsu if (!kprobes_all_disarmed) 2646bf8f6e5bSAnanth N Mavinakayanahalli buf[0] = '1'; 2647bf8f6e5bSAnanth N Mavinakayanahalli else 2648bf8f6e5bSAnanth N Mavinakayanahalli buf[0] = '0'; 2649bf8f6e5bSAnanth N Mavinakayanahalli buf[1] = '\n'; 2650bf8f6e5bSAnanth N Mavinakayanahalli buf[2] = 0x00; 2651bf8f6e5bSAnanth N Mavinakayanahalli return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 2652bf8f6e5bSAnanth N Mavinakayanahalli } 2653bf8f6e5bSAnanth N Mavinakayanahalli 2654bf8f6e5bSAnanth N Mavinakayanahalli static ssize_t write_enabled_file_bool(struct file *file, 2655bf8f6e5bSAnanth N Mavinakayanahalli const char __user *user_buf, size_t count, loff_t *ppos) 2656bf8f6e5bSAnanth N Mavinakayanahalli { 2657bf8f6e5bSAnanth N Mavinakayanahalli char buf[32]; 2658efeb156eSStephen Boyd size_t buf_size; 265912310e34SJessica Yu int ret = 0; 2660bf8f6e5bSAnanth N Mavinakayanahalli 2661bf8f6e5bSAnanth N Mavinakayanahalli buf_size = min(count, (sizeof(buf)-1)); 2662bf8f6e5bSAnanth N Mavinakayanahalli if (copy_from_user(buf, user_buf, buf_size)) 2663bf8f6e5bSAnanth N Mavinakayanahalli return -EFAULT; 2664bf8f6e5bSAnanth N Mavinakayanahalli 266510fb46d5SMathias Krause buf[buf_size] = '\0'; 2666bf8f6e5bSAnanth N Mavinakayanahalli switch (buf[0]) { 2667bf8f6e5bSAnanth N Mavinakayanahalli case 'y': 2668bf8f6e5bSAnanth N Mavinakayanahalli case 'Y': 2669bf8f6e5bSAnanth N Mavinakayanahalli case '1': 267012310e34SJessica Yu ret = arm_all_kprobes(); 2671bf8f6e5bSAnanth N Mavinakayanahalli break; 2672bf8f6e5bSAnanth N Mavinakayanahalli case 'n': 2673bf8f6e5bSAnanth N Mavinakayanahalli case 'N': 2674bf8f6e5bSAnanth N Mavinakayanahalli case '0': 2675297f9233SJessica Yu ret = disarm_all_kprobes(); 2676bf8f6e5bSAnanth N Mavinakayanahalli break; 267710fb46d5SMathias Krause default: 267810fb46d5SMathias Krause return -EINVAL; 2679bf8f6e5bSAnanth N Mavinakayanahalli } 2680bf8f6e5bSAnanth N Mavinakayanahalli 268112310e34SJessica Yu if (ret) 268212310e34SJessica Yu return ret; 268312310e34SJessica Yu 2684bf8f6e5bSAnanth N Mavinakayanahalli return count; 2685bf8f6e5bSAnanth N Mavinakayanahalli } 2686bf8f6e5bSAnanth N Mavinakayanahalli 2687828c0950SAlexey Dobriyan static const struct file_operations fops_kp = { 2688bf8f6e5bSAnanth N Mavinakayanahalli .read = read_enabled_file_bool, 2689bf8f6e5bSAnanth N Mavinakayanahalli .write = write_enabled_file_bool, 26906038f373SArnd Bergmann .llseek = default_llseek, 2691bf8f6e5bSAnanth N Mavinakayanahalli }; 2692bf8f6e5bSAnanth N Mavinakayanahalli 269355479f64SMasami Hiramatsu static int __init debugfs_kprobe_init(void) 2694346fd59bSSrinivasa Ds { 26958c0fd1faSGreg Kroah-Hartman struct dentry *dir; 2696bf8f6e5bSAnanth N Mavinakayanahalli unsigned int value = 1; 2697346fd59bSSrinivasa Ds 2698346fd59bSSrinivasa Ds dir = debugfs_create_dir("kprobes", NULL); 2699346fd59bSSrinivasa Ds 2700eac2ceceSKefeng Wang debugfs_create_file("list", 0400, dir, NULL, &kprobes_fops); 2701346fd59bSSrinivasa Ds 27028c0fd1faSGreg Kroah-Hartman debugfs_create_file("enabled", 0600, dir, &value, &fops_kp); 270363724740SMasami Hiramatsu 27048c0fd1faSGreg Kroah-Hartman debugfs_create_file("blacklist", 0400, dir, NULL, 2705eac2ceceSKefeng Wang &kprobe_blacklist_fops); 2706bf8f6e5bSAnanth N Mavinakayanahalli 2707346fd59bSSrinivasa Ds return 0; 2708346fd59bSSrinivasa Ds } 2709346fd59bSSrinivasa Ds 2710346fd59bSSrinivasa Ds late_initcall(debugfs_kprobe_init); 2711346fd59bSSrinivasa Ds #endif /* CONFIG_DEBUG_FS */ 2712