11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * Kernel Probes (KProbes) 41da177e4SLinus Torvalds * 51da177e4SLinus Torvalds * Copyright (C) IBM Corporation, 2002, 2004 61da177e4SLinus Torvalds * 71da177e4SLinus Torvalds * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel 81da177e4SLinus Torvalds * Probes initial implementation (includes suggestions from 91da177e4SLinus Torvalds * Rusty Russell). 101da177e4SLinus Torvalds * 2004-Aug Updated by Prasanna S Panchamukhi <prasanna@in.ibm.com> with 111da177e4SLinus Torvalds * hlists and exceptions notifier as suggested by Andi Kleen. 121da177e4SLinus Torvalds * 2004-July Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes 131da177e4SLinus Torvalds * interface to access function arguments. 141da177e4SLinus Torvalds * 2004-Sep Prasanna S Panchamukhi <prasanna@in.ibm.com> Changed Kprobes 151da177e4SLinus Torvalds * exceptions notifier to be first on the priority list. 16b94cce92SHien Nguyen * 2005-May Hien Nguyen <hien@us.ibm.com>, Jim Keniston 17b94cce92SHien Nguyen * <jkenisto@us.ibm.com> and Prasanna S Panchamukhi 18b94cce92SHien Nguyen * <prasanna@in.ibm.com> added function-return probes. 191da177e4SLinus Torvalds */ 209c89bb8eSMasami Hiramatsu 219c89bb8eSMasami Hiramatsu #define pr_fmt(fmt) "kprobes: " fmt 229c89bb8eSMasami Hiramatsu 231da177e4SLinus Torvalds #include <linux/kprobes.h> 241da177e4SLinus Torvalds #include <linux/hash.h> 251da177e4SLinus Torvalds #include <linux/init.h> 264e57b681STim Schmielau #include <linux/slab.h> 27e3869792SRandy Dunlap #include <linux/stddef.h> 289984de1aSPaul Gortmaker #include <linux/export.h> 299ec4b1f3SAnanth N Mavinakayanahalli #include <linux/moduleloader.h> 303a872d89SAnanth N Mavinakayanahalli #include <linux/kallsyms.h> 31b4c6c34aSMasami Hiramatsu #include <linux/freezer.h> 32346fd59bSSrinivasa Ds #include <linux/seq_file.h> 33346fd59bSSrinivasa Ds #include <linux/debugfs.h> 34b2be84dfSMasami Hiramatsu #include <linux/sysctl.h> 351eeb66a1SChristoph Hellwig #include <linux/kdebug.h> 364460fdadSMathieu Desnoyers #include <linux/memory.h> 374554dbcbSMasami Hiramatsu #include <linux/ftrace.h> 38afd66255SMasami Hiramatsu #include <linux/cpu.h> 39bf5438fcSJason Baron #include <linux/jump_label.h> 40fa68bd09SPeter Zijlstra #include <linux/static_call.h> 4169e49088SAdrian Hunter #include <linux/perf_event.h> 42bf8f6e5bSAnanth N Mavinakayanahalli 43bfd45be0SChristoph Hellwig #include <asm/sections.h> 441da177e4SLinus Torvalds #include <asm/cacheflush.h> 451da177e4SLinus Torvalds #include <asm/errno.h> 467c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds #define KPROBE_HASH_BITS 6 491da177e4SLinus Torvalds #define KPROBE_TABLE_SIZE (1 << KPROBE_HASH_BITS) 501da177e4SLinus Torvalds 51a737a3c6SXiaoming Ni #if !defined(CONFIG_OPTPROBES) || !defined(CONFIG_SYSCTL) 52a737a3c6SXiaoming Ni #define kprobe_sysctls_init() do { } while (0) 53a737a3c6SXiaoming Ni #endif 543a872d89SAnanth N Mavinakayanahalli 55ef53d9c5SSrinivasa D S static int kprobes_initialized; 567e6a71d8SMasami Hiramatsu /* kprobe_table can be accessed by 57223a76b2SMasami Hiramatsu * - Normal hlist traversal and RCU add/del under 'kprobe_mutex' is held. 587e6a71d8SMasami Hiramatsu * Or 597e6a71d8SMasami Hiramatsu * - RCU hlist traversal under disabling preempt (breakpoint handlers) 607e6a71d8SMasami Hiramatsu */ 611da177e4SLinus Torvalds static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; 621da177e4SLinus Torvalds 63223a76b2SMasami Hiramatsu /* NOTE: change this value only with 'kprobe_mutex' held */ 64e579abebSMasami Hiramatsu static bool kprobes_all_disarmed; 65bf8f6e5bSAnanth N Mavinakayanahalli 66223a76b2SMasami Hiramatsu /* This protects 'kprobe_table' and 'optimizing_list' */ 6743948f50SMasami Hiramatsu static DEFINE_MUTEX(kprobe_mutex); 68223a76b2SMasami Hiramatsu static DEFINE_PER_CPU(struct kprobe *, kprobe_instance); 69ef53d9c5SSrinivasa D S 70290e3070SNaveen N. Rao kprobe_opcode_t * __weak kprobe_lookup_name(const char *name, 71290e3070SNaveen N. Rao unsigned int __unused) 7249e0b465SNaveen N. Rao { 7349e0b465SNaveen N. Rao return ((kprobe_opcode_t *)(kallsyms_lookup_name(name))); 7449e0b465SNaveen N. Rao } 7549e0b465SNaveen N. Rao 76223a76b2SMasami Hiramatsu /* 77223a76b2SMasami Hiramatsu * Blacklist -- list of 'struct kprobe_blacklist_entry' to store info where 78223a76b2SMasami Hiramatsu * kprobes can not probe. 79223a76b2SMasami Hiramatsu */ 80376e2424SMasami Hiramatsu static LIST_HEAD(kprobe_blacklist); 813d8d996eSSrinivasa Ds 822d14e39dSAnil S Keshavamurthy #ifdef __ARCH_WANT_KPROBES_INSN_SLOT 839ec4b1f3SAnanth N Mavinakayanahalli /* 84223a76b2SMasami Hiramatsu * 'kprobe::ainsn.insn' points to the copy of the instruction to be 859ec4b1f3SAnanth N Mavinakayanahalli * single-stepped. x86_64, POWER4 and above have no-exec support and 869ec4b1f3SAnanth N Mavinakayanahalli * stepping on the instruction on a vmalloced/kmalloced/data page 879ec4b1f3SAnanth N Mavinakayanahalli * is a recipe for disaster 889ec4b1f3SAnanth N Mavinakayanahalli */ 899ec4b1f3SAnanth N Mavinakayanahalli struct kprobe_insn_page { 90c5cb5a2dSMasami Hiramatsu struct list_head list; 919ec4b1f3SAnanth N Mavinakayanahalli kprobe_opcode_t *insns; /* Page of instruction slots */ 92af96397dSHeiko Carstens struct kprobe_insn_cache *cache; 939ec4b1f3SAnanth N Mavinakayanahalli int nused; 94b4c6c34aSMasami Hiramatsu int ngarbage; 954610ee1dSMasami Hiramatsu char slot_used[]; 969ec4b1f3SAnanth N Mavinakayanahalli }; 979ec4b1f3SAnanth N Mavinakayanahalli 984610ee1dSMasami Hiramatsu #define KPROBE_INSN_PAGE_SIZE(slots) \ 994610ee1dSMasami Hiramatsu (offsetof(struct kprobe_insn_page, slot_used) + \ 1004610ee1dSMasami Hiramatsu (sizeof(char) * (slots))) 1014610ee1dSMasami Hiramatsu 1024610ee1dSMasami Hiramatsu static int slots_per_page(struct kprobe_insn_cache *c) 1034610ee1dSMasami Hiramatsu { 1044610ee1dSMasami Hiramatsu return PAGE_SIZE/(c->insn_size * sizeof(kprobe_opcode_t)); 1054610ee1dSMasami Hiramatsu } 1064610ee1dSMasami Hiramatsu 107ab40c5c6SMasami Hiramatsu enum kprobe_slot_state { 108ab40c5c6SMasami Hiramatsu SLOT_CLEAN = 0, 109ab40c5c6SMasami Hiramatsu SLOT_DIRTY = 1, 110ab40c5c6SMasami Hiramatsu SLOT_USED = 2, 111ab40c5c6SMasami Hiramatsu }; 112ab40c5c6SMasami Hiramatsu 11363fef14fSMasami Hiramatsu void __weak *alloc_insn_page(void) 114af96397dSHeiko Carstens { 115223a76b2SMasami Hiramatsu /* 116223a76b2SMasami Hiramatsu * Use module_alloc() so this page is within +/- 2GB of where the 117223a76b2SMasami Hiramatsu * kernel image and loaded module images reside. This is required 118223a76b2SMasami Hiramatsu * for most of the architectures. 119223a76b2SMasami Hiramatsu * (e.g. x86-64 needs this to handle the %rip-relative fixups.) 120223a76b2SMasami Hiramatsu */ 121af96397dSHeiko Carstens return module_alloc(PAGE_SIZE); 122af96397dSHeiko Carstens } 123af96397dSHeiko Carstens 12466ce7514SBarry Song static void free_insn_page(void *page) 125af96397dSHeiko Carstens { 126be1f221cSRusty Russell module_memfree(page); 127af96397dSHeiko Carstens } 128af96397dSHeiko Carstens 129c802d64aSHeiko Carstens struct kprobe_insn_cache kprobe_insn_slots = { 130c802d64aSHeiko Carstens .mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex), 131af96397dSHeiko Carstens .alloc = alloc_insn_page, 132af96397dSHeiko Carstens .free = free_insn_page, 133d002b8bcSAdrian Hunter .sym = KPROBE_INSN_PAGE_SYM, 1344610ee1dSMasami Hiramatsu .pages = LIST_HEAD_INIT(kprobe_insn_slots.pages), 1354610ee1dSMasami Hiramatsu .insn_size = MAX_INSN_SIZE, 1364610ee1dSMasami Hiramatsu .nr_garbage = 0, 1374610ee1dSMasami Hiramatsu }; 13855479f64SMasami Hiramatsu static int collect_garbage_slots(struct kprobe_insn_cache *c); 139b4c6c34aSMasami Hiramatsu 1409ec4b1f3SAnanth N Mavinakayanahalli /** 14112941560SMasami Hiramatsu * __get_insn_slot() - Find a slot on an executable page for an instruction. 1429ec4b1f3SAnanth N Mavinakayanahalli * We allocate an executable page if there's no room on existing ones. 1439ec4b1f3SAnanth N Mavinakayanahalli */ 14455479f64SMasami Hiramatsu kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c) 1459ec4b1f3SAnanth N Mavinakayanahalli { 1469ec4b1f3SAnanth N Mavinakayanahalli struct kprobe_insn_page *kip; 147c802d64aSHeiko Carstens kprobe_opcode_t *slot = NULL; 1489ec4b1f3SAnanth N Mavinakayanahalli 1495b485629SMasami Hiramatsu /* Since the slot array is not protected by rcu, we need a mutex */ 150c802d64aSHeiko Carstens mutex_lock(&c->mutex); 151b4c6c34aSMasami Hiramatsu retry: 1525b485629SMasami Hiramatsu rcu_read_lock(); 1535b485629SMasami Hiramatsu list_for_each_entry_rcu(kip, &c->pages, list) { 1544610ee1dSMasami Hiramatsu if (kip->nused < slots_per_page(c)) { 1559ec4b1f3SAnanth N Mavinakayanahalli int i; 156223a76b2SMasami Hiramatsu 1574610ee1dSMasami Hiramatsu for (i = 0; i < slots_per_page(c); i++) { 158ab40c5c6SMasami Hiramatsu if (kip->slot_used[i] == SLOT_CLEAN) { 159ab40c5c6SMasami Hiramatsu kip->slot_used[i] = SLOT_USED; 1609ec4b1f3SAnanth N Mavinakayanahalli kip->nused++; 161c802d64aSHeiko Carstens slot = kip->insns + (i * c->insn_size); 1625b485629SMasami Hiramatsu rcu_read_unlock(); 163c802d64aSHeiko Carstens goto out; 1649ec4b1f3SAnanth N Mavinakayanahalli } 1659ec4b1f3SAnanth N Mavinakayanahalli } 1664610ee1dSMasami Hiramatsu /* kip->nused is broken. Fix it. */ 1674610ee1dSMasami Hiramatsu kip->nused = slots_per_page(c); 1684610ee1dSMasami Hiramatsu WARN_ON(1); 1699ec4b1f3SAnanth N Mavinakayanahalli } 1709ec4b1f3SAnanth N Mavinakayanahalli } 1715b485629SMasami Hiramatsu rcu_read_unlock(); 1729ec4b1f3SAnanth N Mavinakayanahalli 173b4c6c34aSMasami Hiramatsu /* If there are any garbage slots, collect it and try again. */ 1744610ee1dSMasami Hiramatsu if (c->nr_garbage && collect_garbage_slots(c) == 0) 175b4c6c34aSMasami Hiramatsu goto retry; 1764610ee1dSMasami Hiramatsu 1774610ee1dSMasami Hiramatsu /* All out of space. Need to allocate a new page. */ 1784610ee1dSMasami Hiramatsu kip = kmalloc(KPROBE_INSN_PAGE_SIZE(slots_per_page(c)), GFP_KERNEL); 1796f716acdSChristoph Hellwig if (!kip) 180c802d64aSHeiko Carstens goto out; 1819ec4b1f3SAnanth N Mavinakayanahalli 182af96397dSHeiko Carstens kip->insns = c->alloc(); 1839ec4b1f3SAnanth N Mavinakayanahalli if (!kip->insns) { 1849ec4b1f3SAnanth N Mavinakayanahalli kfree(kip); 185c802d64aSHeiko Carstens goto out; 1869ec4b1f3SAnanth N Mavinakayanahalli } 187c5cb5a2dSMasami Hiramatsu INIT_LIST_HEAD(&kip->list); 1884610ee1dSMasami Hiramatsu memset(kip->slot_used, SLOT_CLEAN, slots_per_page(c)); 189ab40c5c6SMasami Hiramatsu kip->slot_used[0] = SLOT_USED; 1909ec4b1f3SAnanth N Mavinakayanahalli kip->nused = 1; 191b4c6c34aSMasami Hiramatsu kip->ngarbage = 0; 192af96397dSHeiko Carstens kip->cache = c; 1935b485629SMasami Hiramatsu list_add_rcu(&kip->list, &c->pages); 194c802d64aSHeiko Carstens slot = kip->insns; 19569e49088SAdrian Hunter 19669e49088SAdrian Hunter /* Record the perf ksymbol register event after adding the page */ 19769e49088SAdrian Hunter perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL, (unsigned long)kip->insns, 19869e49088SAdrian Hunter PAGE_SIZE, false, c->sym); 199c802d64aSHeiko Carstens out: 200c802d64aSHeiko Carstens mutex_unlock(&c->mutex); 201c802d64aSHeiko Carstens return slot; 20212941560SMasami Hiramatsu } 20312941560SMasami Hiramatsu 20429e8077aSMasami Hiramatsu /* Return true if all garbages are collected, otherwise false. */ 20529e8077aSMasami Hiramatsu static bool collect_one_slot(struct kprobe_insn_page *kip, int idx) 2069ec4b1f3SAnanth N Mavinakayanahalli { 207ab40c5c6SMasami Hiramatsu kip->slot_used[idx] = SLOT_CLEAN; 2089ec4b1f3SAnanth N Mavinakayanahalli kip->nused--; 2099ec4b1f3SAnanth N Mavinakayanahalli if (kip->nused == 0) { 2109ec4b1f3SAnanth N Mavinakayanahalli /* 2119ec4b1f3SAnanth N Mavinakayanahalli * Page is no longer in use. Free it unless 2129ec4b1f3SAnanth N Mavinakayanahalli * it's the last one. We keep the last one 2139ec4b1f3SAnanth N Mavinakayanahalli * so as not to have to set it up again the 2149ec4b1f3SAnanth N Mavinakayanahalli * next time somebody inserts a probe. 2159ec4b1f3SAnanth N Mavinakayanahalli */ 2164610ee1dSMasami Hiramatsu if (!list_is_singular(&kip->list)) { 21769e49088SAdrian Hunter /* 21869e49088SAdrian Hunter * Record perf ksymbol unregister event before removing 21969e49088SAdrian Hunter * the page. 22069e49088SAdrian Hunter */ 22169e49088SAdrian Hunter perf_event_ksymbol(PERF_RECORD_KSYMBOL_TYPE_OOL, 22269e49088SAdrian Hunter (unsigned long)kip->insns, PAGE_SIZE, true, 22369e49088SAdrian Hunter kip->cache->sym); 2245b485629SMasami Hiramatsu list_del_rcu(&kip->list); 2255b485629SMasami Hiramatsu synchronize_rcu(); 226af96397dSHeiko Carstens kip->cache->free(kip->insns); 2279ec4b1f3SAnanth N Mavinakayanahalli kfree(kip); 2289ec4b1f3SAnanth N Mavinakayanahalli } 22929e8077aSMasami Hiramatsu return true; 2309ec4b1f3SAnanth N Mavinakayanahalli } 23129e8077aSMasami Hiramatsu return false; 2329ec4b1f3SAnanth N Mavinakayanahalli } 233b4c6c34aSMasami Hiramatsu 23455479f64SMasami Hiramatsu static int collect_garbage_slots(struct kprobe_insn_cache *c) 235b4c6c34aSMasami Hiramatsu { 236c5cb5a2dSMasami Hiramatsu struct kprobe_insn_page *kip, *next; 237b4c6c34aSMasami Hiramatsu 238615d0ebbSMasami Hiramatsu /* Ensure no-one is interrupted on the garbages */ 239ae8b7ce7SPaul E. McKenney synchronize_rcu(); 240b4c6c34aSMasami Hiramatsu 2414610ee1dSMasami Hiramatsu list_for_each_entry_safe(kip, next, &c->pages, list) { 242b4c6c34aSMasami Hiramatsu int i; 243223a76b2SMasami Hiramatsu 244b4c6c34aSMasami Hiramatsu if (kip->ngarbage == 0) 245b4c6c34aSMasami Hiramatsu continue; 246b4c6c34aSMasami Hiramatsu kip->ngarbage = 0; /* we will collect all garbages */ 2474610ee1dSMasami Hiramatsu for (i = 0; i < slots_per_page(c); i++) { 2485b485629SMasami Hiramatsu if (kip->slot_used[i] == SLOT_DIRTY && collect_one_slot(kip, i)) 249b4c6c34aSMasami Hiramatsu break; 250b4c6c34aSMasami Hiramatsu } 251b4c6c34aSMasami Hiramatsu } 2524610ee1dSMasami Hiramatsu c->nr_garbage = 0; 253b4c6c34aSMasami Hiramatsu return 0; 254b4c6c34aSMasami Hiramatsu } 255b4c6c34aSMasami Hiramatsu 25655479f64SMasami Hiramatsu void __free_insn_slot(struct kprobe_insn_cache *c, 2574610ee1dSMasami Hiramatsu kprobe_opcode_t *slot, int dirty) 2584610ee1dSMasami Hiramatsu { 2594610ee1dSMasami Hiramatsu struct kprobe_insn_page *kip; 2605b485629SMasami Hiramatsu long idx; 2614610ee1dSMasami Hiramatsu 262c802d64aSHeiko Carstens mutex_lock(&c->mutex); 2635b485629SMasami Hiramatsu rcu_read_lock(); 2645b485629SMasami Hiramatsu list_for_each_entry_rcu(kip, &c->pages, list) { 2655b485629SMasami Hiramatsu idx = ((long)slot - (long)kip->insns) / 26683ff56f4SMasami Hiramatsu (c->insn_size * sizeof(kprobe_opcode_t)); 2675b485629SMasami Hiramatsu if (idx >= 0 && idx < slots_per_page(c)) 2685b485629SMasami Hiramatsu goto out; 2695b485629SMasami Hiramatsu } 2705b485629SMasami Hiramatsu /* Could not find this slot. */ 2715b485629SMasami Hiramatsu WARN_ON(1); 2725b485629SMasami Hiramatsu kip = NULL; 2735b485629SMasami Hiramatsu out: 2745b485629SMasami Hiramatsu rcu_read_unlock(); 2755b485629SMasami Hiramatsu /* Mark and sweep: this may sleep */ 2765b485629SMasami Hiramatsu if (kip) { 2775b485629SMasami Hiramatsu /* Check double free */ 2784610ee1dSMasami Hiramatsu WARN_ON(kip->slot_used[idx] != SLOT_USED); 2794610ee1dSMasami Hiramatsu if (dirty) { 2804610ee1dSMasami Hiramatsu kip->slot_used[idx] = SLOT_DIRTY; 2814610ee1dSMasami Hiramatsu kip->ngarbage++; 2824610ee1dSMasami Hiramatsu if (++c->nr_garbage > slots_per_page(c)) 2834610ee1dSMasami Hiramatsu collect_garbage_slots(c); 2845b485629SMasami Hiramatsu } else { 2854610ee1dSMasami Hiramatsu collect_one_slot(kip, idx); 2864610ee1dSMasami Hiramatsu } 2874610ee1dSMasami Hiramatsu } 288c802d64aSHeiko Carstens mutex_unlock(&c->mutex); 2894610ee1dSMasami Hiramatsu } 2904610ee1dSMasami Hiramatsu 2915b485629SMasami Hiramatsu /* 2925b485629SMasami Hiramatsu * Check given address is on the page of kprobe instruction slots. 2935b485629SMasami Hiramatsu * This will be used for checking whether the address on a stack 2945b485629SMasami Hiramatsu * is on a text area or not. 2955b485629SMasami Hiramatsu */ 2965b485629SMasami Hiramatsu bool __is_insn_slot_addr(struct kprobe_insn_cache *c, unsigned long addr) 2975b485629SMasami Hiramatsu { 2985b485629SMasami Hiramatsu struct kprobe_insn_page *kip; 2995b485629SMasami Hiramatsu bool ret = false; 3005b485629SMasami Hiramatsu 3015b485629SMasami Hiramatsu rcu_read_lock(); 3025b485629SMasami Hiramatsu list_for_each_entry_rcu(kip, &c->pages, list) { 3035b485629SMasami Hiramatsu if (addr >= (unsigned long)kip->insns && 3045b485629SMasami Hiramatsu addr < (unsigned long)kip->insns + PAGE_SIZE) { 3055b485629SMasami Hiramatsu ret = true; 3065b485629SMasami Hiramatsu break; 3075b485629SMasami Hiramatsu } 3085b485629SMasami Hiramatsu } 3095b485629SMasami Hiramatsu rcu_read_unlock(); 3105b485629SMasami Hiramatsu 3115b485629SMasami Hiramatsu return ret; 3125b485629SMasami Hiramatsu } 3135b485629SMasami Hiramatsu 314d002b8bcSAdrian Hunter int kprobe_cache_get_kallsym(struct kprobe_insn_cache *c, unsigned int *symnum, 315d002b8bcSAdrian Hunter unsigned long *value, char *type, char *sym) 316d002b8bcSAdrian Hunter { 317d002b8bcSAdrian Hunter struct kprobe_insn_page *kip; 318d002b8bcSAdrian Hunter int ret = -ERANGE; 319d002b8bcSAdrian Hunter 320d002b8bcSAdrian Hunter rcu_read_lock(); 321d002b8bcSAdrian Hunter list_for_each_entry_rcu(kip, &c->pages, list) { 322d002b8bcSAdrian Hunter if ((*symnum)--) 323d002b8bcSAdrian Hunter continue; 324223a76b2SMasami Hiramatsu strscpy(sym, c->sym, KSYM_NAME_LEN); 325d002b8bcSAdrian Hunter *type = 't'; 326d002b8bcSAdrian Hunter *value = (unsigned long)kip->insns; 327d002b8bcSAdrian Hunter ret = 0; 328d002b8bcSAdrian Hunter break; 329d002b8bcSAdrian Hunter } 330d002b8bcSAdrian Hunter rcu_read_unlock(); 331d002b8bcSAdrian Hunter 332d002b8bcSAdrian Hunter return ret; 333d002b8bcSAdrian Hunter } 334d002b8bcSAdrian Hunter 335afd66255SMasami Hiramatsu #ifdef CONFIG_OPTPROBES 3367ee3e97eSChristophe Leroy void __weak *alloc_optinsn_page(void) 3377ee3e97eSChristophe Leroy { 3387ee3e97eSChristophe Leroy return alloc_insn_page(); 3397ee3e97eSChristophe Leroy } 3407ee3e97eSChristophe Leroy 3417ee3e97eSChristophe Leroy void __weak free_optinsn_page(void *page) 3427ee3e97eSChristophe Leroy { 3437ee3e97eSChristophe Leroy free_insn_page(page); 3447ee3e97eSChristophe Leroy } 3457ee3e97eSChristophe Leroy 346afd66255SMasami Hiramatsu /* For optimized_kprobe buffer */ 347c802d64aSHeiko Carstens struct kprobe_insn_cache kprobe_optinsn_slots = { 348c802d64aSHeiko Carstens .mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex), 3497ee3e97eSChristophe Leroy .alloc = alloc_optinsn_page, 3507ee3e97eSChristophe Leroy .free = free_optinsn_page, 351d002b8bcSAdrian Hunter .sym = KPROBE_OPTINSN_PAGE_SYM, 352afd66255SMasami Hiramatsu .pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages), 353afd66255SMasami Hiramatsu /* .insn_size is initialized later */ 354afd66255SMasami Hiramatsu .nr_garbage = 0, 355afd66255SMasami Hiramatsu }; 356afd66255SMasami Hiramatsu #endif 3572d14e39dSAnil S Keshavamurthy #endif 3589ec4b1f3SAnanth N Mavinakayanahalli 359e6584523SAnanth N Mavinakayanahalli /* We have preemption disabled.. so it is safe to use __ versions */ 360e6584523SAnanth N Mavinakayanahalli static inline void set_kprobe_instance(struct kprobe *kp) 361e6584523SAnanth N Mavinakayanahalli { 362b76834bcSChristoph Lameter __this_cpu_write(kprobe_instance, kp); 363e6584523SAnanth N Mavinakayanahalli } 364e6584523SAnanth N Mavinakayanahalli 365e6584523SAnanth N Mavinakayanahalli static inline void reset_kprobe_instance(void) 366e6584523SAnanth N Mavinakayanahalli { 367b76834bcSChristoph Lameter __this_cpu_write(kprobe_instance, NULL); 368e6584523SAnanth N Mavinakayanahalli } 369e6584523SAnanth N Mavinakayanahalli 3703516a460SAnanth N Mavinakayanahalli /* 3713516a460SAnanth N Mavinakayanahalli * This routine is called either: 372223a76b2SMasami Hiramatsu * - under the 'kprobe_mutex' - during kprobe_[un]register(). 3733516a460SAnanth N Mavinakayanahalli * OR 374223a76b2SMasami Hiramatsu * - with preemption disabled - from architecture specific code. 3753516a460SAnanth N Mavinakayanahalli */ 376820aede0SMasami Hiramatsu struct kprobe *get_kprobe(void *addr) 3771da177e4SLinus Torvalds { 3781da177e4SLinus Torvalds struct hlist_head *head; 3793516a460SAnanth N Mavinakayanahalli struct kprobe *p; 3801da177e4SLinus Torvalds 3811da177e4SLinus Torvalds head = &kprobe_table[hash_ptr(addr, KPROBE_HASH_BITS)]; 3826743ad43SMasami Hiramatsu hlist_for_each_entry_rcu(p, head, hlist, 3836743ad43SMasami Hiramatsu lockdep_is_held(&kprobe_mutex)) { 3841da177e4SLinus Torvalds if (p->addr == addr) 3851da177e4SLinus Torvalds return p; 3861da177e4SLinus Torvalds } 387afd66255SMasami Hiramatsu 3881da177e4SLinus Torvalds return NULL; 3891da177e4SLinus Torvalds } 390820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(get_kprobe); 3911da177e4SLinus Torvalds 392820aede0SMasami Hiramatsu static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs); 393afd66255SMasami Hiramatsu 394223a76b2SMasami Hiramatsu /* Return true if 'p' is an aggregator */ 39529e8077aSMasami Hiramatsu static inline bool kprobe_aggrprobe(struct kprobe *p) 396afd66255SMasami Hiramatsu { 397afd66255SMasami Hiramatsu return p->pre_handler == aggr_pre_handler; 398afd66255SMasami Hiramatsu } 399afd66255SMasami Hiramatsu 400223a76b2SMasami Hiramatsu /* Return true if 'p' is unused */ 40129e8077aSMasami Hiramatsu static inline bool kprobe_unused(struct kprobe *p) 4026274de49SMasami Hiramatsu { 4036274de49SMasami Hiramatsu return kprobe_aggrprobe(p) && kprobe_disabled(p) && 4046274de49SMasami Hiramatsu list_empty(&p->list); 4056274de49SMasami Hiramatsu } 4066274de49SMasami Hiramatsu 407223a76b2SMasami Hiramatsu /* Keep all fields in the kprobe consistent. */ 4086d8e40a8SMasami Hiramatsu static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p) 409afd66255SMasami Hiramatsu { 4106d8e40a8SMasami Hiramatsu memcpy(&p->opcode, &ap->opcode, sizeof(kprobe_opcode_t)); 4116d8e40a8SMasami Hiramatsu memcpy(&p->ainsn, &ap->ainsn, sizeof(struct arch_specific_insn)); 412afd66255SMasami Hiramatsu } 413afd66255SMasami Hiramatsu 414afd66255SMasami Hiramatsu #ifdef CONFIG_OPTPROBES 415223a76b2SMasami Hiramatsu /* NOTE: This is protected by 'kprobe_mutex'. */ 416b2be84dfSMasami Hiramatsu static bool kprobes_allow_optimization; 417b2be84dfSMasami Hiramatsu 418afd66255SMasami Hiramatsu /* 419223a76b2SMasami Hiramatsu * Call all 'kprobe::pre_handler' on the list, but ignores its return value. 420afd66255SMasami Hiramatsu * This must be called from arch-dep optimized caller. 421afd66255SMasami Hiramatsu */ 422820aede0SMasami Hiramatsu void opt_pre_handler(struct kprobe *p, struct pt_regs *regs) 423afd66255SMasami Hiramatsu { 424afd66255SMasami Hiramatsu struct kprobe *kp; 425afd66255SMasami Hiramatsu 426afd66255SMasami Hiramatsu list_for_each_entry_rcu(kp, &p->list, list) { 427afd66255SMasami Hiramatsu if (kp->pre_handler && likely(!kprobe_disabled(kp))) { 428afd66255SMasami Hiramatsu set_kprobe_instance(kp); 4294f3a8714SNaveen N. Rao kp->pre_handler(kp, regs); 430afd66255SMasami Hiramatsu } 431afd66255SMasami Hiramatsu reset_kprobe_instance(); 432afd66255SMasami Hiramatsu } 433afd66255SMasami Hiramatsu } 434820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(opt_pre_handler); 435afd66255SMasami Hiramatsu 4366274de49SMasami Hiramatsu /* Free optimized instructions and optimized_kprobe */ 43755479f64SMasami Hiramatsu static void free_aggr_kprobe(struct kprobe *p) 4386274de49SMasami Hiramatsu { 4396274de49SMasami Hiramatsu struct optimized_kprobe *op; 4406274de49SMasami Hiramatsu 4416274de49SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 4426274de49SMasami Hiramatsu arch_remove_optimized_kprobe(op); 4436274de49SMasami Hiramatsu arch_remove_kprobe(p); 4446274de49SMasami Hiramatsu kfree(op); 4456274de49SMasami Hiramatsu } 4466274de49SMasami Hiramatsu 447223a76b2SMasami Hiramatsu /* Return true if the kprobe is ready for optimization. */ 448afd66255SMasami Hiramatsu static inline int kprobe_optready(struct kprobe *p) 449afd66255SMasami Hiramatsu { 450afd66255SMasami Hiramatsu struct optimized_kprobe *op; 451afd66255SMasami Hiramatsu 452afd66255SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 453afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 454afd66255SMasami Hiramatsu return arch_prepared_optinsn(&op->optinsn); 455afd66255SMasami Hiramatsu } 456afd66255SMasami Hiramatsu 457afd66255SMasami Hiramatsu return 0; 458afd66255SMasami Hiramatsu } 459afd66255SMasami Hiramatsu 460223a76b2SMasami Hiramatsu /* Return true if the kprobe is disarmed. Note: p must be on hash list */ 46129e8077aSMasami Hiramatsu static inline bool kprobe_disarmed(struct kprobe *p) 4626274de49SMasami Hiramatsu { 4636274de49SMasami Hiramatsu struct optimized_kprobe *op; 4646274de49SMasami Hiramatsu 4656274de49SMasami Hiramatsu /* If kprobe is not aggr/opt probe, just return kprobe is disabled */ 4666274de49SMasami Hiramatsu if (!kprobe_aggrprobe(p)) 4676274de49SMasami Hiramatsu return kprobe_disabled(p); 4686274de49SMasami Hiramatsu 4696274de49SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 4706274de49SMasami Hiramatsu 4716274de49SMasami Hiramatsu return kprobe_disabled(p) && list_empty(&op->list); 4726274de49SMasami Hiramatsu } 4736274de49SMasami Hiramatsu 474223a76b2SMasami Hiramatsu /* Return true if the probe is queued on (un)optimizing lists */ 47529e8077aSMasami Hiramatsu static bool kprobe_queued(struct kprobe *p) 4766274de49SMasami Hiramatsu { 4776274de49SMasami Hiramatsu struct optimized_kprobe *op; 4786274de49SMasami Hiramatsu 4796274de49SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 4806274de49SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 4816274de49SMasami Hiramatsu if (!list_empty(&op->list)) 48229e8077aSMasami Hiramatsu return true; 4836274de49SMasami Hiramatsu } 48429e8077aSMasami Hiramatsu return false; 4856274de49SMasami Hiramatsu } 4866274de49SMasami Hiramatsu 487afd66255SMasami Hiramatsu /* 488afd66255SMasami Hiramatsu * Return an optimized kprobe whose optimizing code replaces 489223a76b2SMasami Hiramatsu * instructions including 'addr' (exclude breakpoint). 490afd66255SMasami Hiramatsu */ 491c42421e2SMasami Hiramatsu static struct kprobe *get_optimized_kprobe(kprobe_opcode_t *addr) 492afd66255SMasami Hiramatsu { 493afd66255SMasami Hiramatsu int i; 494afd66255SMasami Hiramatsu struct kprobe *p = NULL; 495afd66255SMasami Hiramatsu struct optimized_kprobe *op; 496afd66255SMasami Hiramatsu 497afd66255SMasami Hiramatsu /* Don't check i == 0, since that is a breakpoint case. */ 498c42421e2SMasami Hiramatsu for (i = 1; !p && i < MAX_OPTIMIZED_LENGTH / sizeof(kprobe_opcode_t); i++) 499c42421e2SMasami Hiramatsu p = get_kprobe(addr - i); 500afd66255SMasami Hiramatsu 501afd66255SMasami Hiramatsu if (p && kprobe_optready(p)) { 502afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 503afd66255SMasami Hiramatsu if (arch_within_optimized_kprobe(op, addr)) 504afd66255SMasami Hiramatsu return p; 505afd66255SMasami Hiramatsu } 506afd66255SMasami Hiramatsu 507afd66255SMasami Hiramatsu return NULL; 508afd66255SMasami Hiramatsu } 509afd66255SMasami Hiramatsu 510223a76b2SMasami Hiramatsu /* Optimization staging list, protected by 'kprobe_mutex' */ 511afd66255SMasami Hiramatsu static LIST_HEAD(optimizing_list); 5126274de49SMasami Hiramatsu static LIST_HEAD(unoptimizing_list); 5137b959fc5SMasami Hiramatsu static LIST_HEAD(freeing_list); 514afd66255SMasami Hiramatsu 515afd66255SMasami Hiramatsu static void kprobe_optimizer(struct work_struct *work); 516afd66255SMasami Hiramatsu static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); 517afd66255SMasami Hiramatsu #define OPTIMIZE_DELAY 5 518afd66255SMasami Hiramatsu 51961f4e13fSMasami Hiramatsu /* 52061f4e13fSMasami Hiramatsu * Optimize (replace a breakpoint with a jump) kprobes listed on 521223a76b2SMasami Hiramatsu * 'optimizing_list'. 52261f4e13fSMasami Hiramatsu */ 52355479f64SMasami Hiramatsu static void do_optimize_kprobes(void) 524afd66255SMasami Hiramatsu { 525f1c6ece2SAndrea Righi lockdep_assert_held(&text_mutex); 526afd66255SMasami Hiramatsu /* 527223a76b2SMasami Hiramatsu * The optimization/unoptimization refers 'online_cpus' via 528223a76b2SMasami Hiramatsu * stop_machine() and cpu-hotplug modifies the 'online_cpus'. 529223a76b2SMasami Hiramatsu * And same time, 'text_mutex' will be held in cpu-hotplug and here. 530223a76b2SMasami Hiramatsu * This combination can cause a deadlock (cpu-hotplug tries to lock 531223a76b2SMasami Hiramatsu * 'text_mutex' but stop_machine() can not be done because 532223a76b2SMasami Hiramatsu * the 'online_cpus' has been changed) 533223a76b2SMasami Hiramatsu * To avoid this deadlock, caller must have locked cpu-hotplug 534223a76b2SMasami Hiramatsu * for preventing cpu-hotplug outside of 'text_mutex' locking. 535afd66255SMasami Hiramatsu */ 5362d1e38f5SThomas Gleixner lockdep_assert_cpus_held(); 5372d1e38f5SThomas Gleixner 5382d1e38f5SThomas Gleixner /* Optimization never be done when disarmed */ 5392d1e38f5SThomas Gleixner if (kprobes_all_disarmed || !kprobes_allow_optimization || 5402d1e38f5SThomas Gleixner list_empty(&optimizing_list)) 5412d1e38f5SThomas Gleixner return; 5422d1e38f5SThomas Gleixner 543cd7ebe22SMasami Hiramatsu arch_optimize_kprobes(&optimizing_list); 54461f4e13fSMasami Hiramatsu } 54561f4e13fSMasami Hiramatsu 5466274de49SMasami Hiramatsu /* 5476274de49SMasami Hiramatsu * Unoptimize (replace a jump with a breakpoint and remove the breakpoint 548223a76b2SMasami Hiramatsu * if need) kprobes listed on 'unoptimizing_list'. 5496274de49SMasami Hiramatsu */ 55055479f64SMasami Hiramatsu static void do_unoptimize_kprobes(void) 5516274de49SMasami Hiramatsu { 5526274de49SMasami Hiramatsu struct optimized_kprobe *op, *tmp; 5536274de49SMasami Hiramatsu 554f1c6ece2SAndrea Righi lockdep_assert_held(&text_mutex); 5552d1e38f5SThomas Gleixner /* See comment in do_optimize_kprobes() */ 5562d1e38f5SThomas Gleixner lockdep_assert_cpus_held(); 5572d1e38f5SThomas Gleixner 5586274de49SMasami Hiramatsu /* Unoptimization must be done anytime */ 5596274de49SMasami Hiramatsu if (list_empty(&unoptimizing_list)) 5606274de49SMasami Hiramatsu return; 5616274de49SMasami Hiramatsu 5627b959fc5SMasami Hiramatsu arch_unoptimize_kprobes(&unoptimizing_list, &freeing_list); 563223a76b2SMasami Hiramatsu /* Loop on 'freeing_list' for disarming */ 5647b959fc5SMasami Hiramatsu list_for_each_entry_safe(op, tmp, &freeing_list, list) { 565f66c0447SMasami Hiramatsu /* Switching from detour code to origin */ 566f66c0447SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 5676274de49SMasami Hiramatsu /* Disarm probes if marked disabled */ 5686274de49SMasami Hiramatsu if (kprobe_disabled(&op->kp)) 5696274de49SMasami Hiramatsu arch_disarm_kprobe(&op->kp); 5706274de49SMasami Hiramatsu if (kprobe_unused(&op->kp)) { 5716274de49SMasami Hiramatsu /* 5726274de49SMasami Hiramatsu * Remove unused probes from hash list. After waiting 5736274de49SMasami Hiramatsu * for synchronization, these probes are reclaimed. 574223a76b2SMasami Hiramatsu * (reclaiming is done by do_free_cleaned_kprobes().) 5756274de49SMasami Hiramatsu */ 5766274de49SMasami Hiramatsu hlist_del_rcu(&op->kp.hlist); 5776274de49SMasami Hiramatsu } else 5786274de49SMasami Hiramatsu list_del_init(&op->list); 5796274de49SMasami Hiramatsu } 5806274de49SMasami Hiramatsu } 5816274de49SMasami Hiramatsu 582223a76b2SMasami Hiramatsu /* Reclaim all kprobes on the 'freeing_list' */ 58355479f64SMasami Hiramatsu static void do_free_cleaned_kprobes(void) 5846274de49SMasami Hiramatsu { 5856274de49SMasami Hiramatsu struct optimized_kprobe *op, *tmp; 5866274de49SMasami Hiramatsu 5877b959fc5SMasami Hiramatsu list_for_each_entry_safe(op, tmp, &freeing_list, list) { 5886274de49SMasami Hiramatsu list_del_init(&op->list); 589cbdd96f5SMasami Hiramatsu if (WARN_ON_ONCE(!kprobe_unused(&op->kp))) { 590cbdd96f5SMasami Hiramatsu /* 591cbdd96f5SMasami Hiramatsu * This must not happen, but if there is a kprobe 592cbdd96f5SMasami Hiramatsu * still in use, keep it on kprobes hash list. 593cbdd96f5SMasami Hiramatsu */ 594cbdd96f5SMasami Hiramatsu continue; 595cbdd96f5SMasami Hiramatsu } 5966274de49SMasami Hiramatsu free_aggr_kprobe(&op->kp); 5976274de49SMasami Hiramatsu } 5986274de49SMasami Hiramatsu } 5996274de49SMasami Hiramatsu 6006274de49SMasami Hiramatsu /* Start optimizer after OPTIMIZE_DELAY passed */ 60155479f64SMasami Hiramatsu static void kick_kprobe_optimizer(void) 6026274de49SMasami Hiramatsu { 6036274de49SMasami Hiramatsu schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY); 6046274de49SMasami Hiramatsu } 6056274de49SMasami Hiramatsu 60661f4e13fSMasami Hiramatsu /* Kprobe jump optimizer */ 60755479f64SMasami Hiramatsu static void kprobe_optimizer(struct work_struct *work) 60861f4e13fSMasami Hiramatsu { 60972ef3794SSteven Rostedt mutex_lock(&kprobe_mutex); 6102d1e38f5SThomas Gleixner cpus_read_lock(); 611f1c6ece2SAndrea Righi mutex_lock(&text_mutex); 61261f4e13fSMasami Hiramatsu 61361f4e13fSMasami Hiramatsu /* 6146274de49SMasami Hiramatsu * Step 1: Unoptimize kprobes and collect cleaned (unused and disarmed) 6156274de49SMasami Hiramatsu * kprobes before waiting for quiesence period. 6166274de49SMasami Hiramatsu */ 6177b959fc5SMasami Hiramatsu do_unoptimize_kprobes(); 6186274de49SMasami Hiramatsu 6196274de49SMasami Hiramatsu /* 620a30b85dfSMasami Hiramatsu * Step 2: Wait for quiesence period to ensure all potentially 621a30b85dfSMasami Hiramatsu * preempted tasks to have normally scheduled. Because optprobe 622a30b85dfSMasami Hiramatsu * may modify multiple instructions, there is a chance that Nth 623a30b85dfSMasami Hiramatsu * instruction is preempted. In that case, such tasks can return 624a30b85dfSMasami Hiramatsu * to 2nd-Nth byte of jump instruction. This wait is for avoiding it. 625a30b85dfSMasami Hiramatsu * Note that on non-preemptive kernel, this is transparently converted 626a30b85dfSMasami Hiramatsu * to synchronoze_sched() to wait for all interrupts to have completed. 62761f4e13fSMasami Hiramatsu */ 628a30b85dfSMasami Hiramatsu synchronize_rcu_tasks(); 62961f4e13fSMasami Hiramatsu 6306274de49SMasami Hiramatsu /* Step 3: Optimize kprobes after quiesence period */ 63161f4e13fSMasami Hiramatsu do_optimize_kprobes(); 6326274de49SMasami Hiramatsu 6336274de49SMasami Hiramatsu /* Step 4: Free cleaned kprobes after quiesence period */ 6347b959fc5SMasami Hiramatsu do_free_cleaned_kprobes(); 6356274de49SMasami Hiramatsu 636f1c6ece2SAndrea Righi mutex_unlock(&text_mutex); 6372d1e38f5SThomas Gleixner cpus_read_unlock(); 6386274de49SMasami Hiramatsu 639cd7ebe22SMasami Hiramatsu /* Step 5: Kick optimizer again if needed */ 640f984ba4eSMasami Hiramatsu if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) 641cd7ebe22SMasami Hiramatsu kick_kprobe_optimizer(); 6421a0aa991SMasami Hiramatsu 6431a0aa991SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 6446274de49SMasami Hiramatsu } 6456274de49SMasami Hiramatsu 6466274de49SMasami Hiramatsu /* Wait for completing optimization and unoptimization */ 64730e7d894SThomas Gleixner void wait_for_kprobe_optimizer(void) 6486274de49SMasami Hiramatsu { 649ad72b3beSTejun Heo mutex_lock(&kprobe_mutex); 650ad72b3beSTejun Heo 651ad72b3beSTejun Heo while (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) { 652ad72b3beSTejun Heo mutex_unlock(&kprobe_mutex); 653ad72b3beSTejun Heo 654223a76b2SMasami Hiramatsu /* This will also make 'optimizing_work' execute immmediately */ 655ad72b3beSTejun Heo flush_delayed_work(&optimizing_work); 656223a76b2SMasami Hiramatsu /* 'optimizing_work' might not have been queued yet, relax */ 657ad72b3beSTejun Heo cpu_relax(); 658ad72b3beSTejun Heo 659ad72b3beSTejun Heo mutex_lock(&kprobe_mutex); 660ad72b3beSTejun Heo } 661ad72b3beSTejun Heo 662ad72b3beSTejun Heo mutex_unlock(&kprobe_mutex); 663afd66255SMasami Hiramatsu } 664afd66255SMasami Hiramatsu 665e4add247SMasami Hiramatsu static bool optprobe_queued_unopt(struct optimized_kprobe *op) 666e4add247SMasami Hiramatsu { 667e4add247SMasami Hiramatsu struct optimized_kprobe *_op; 668e4add247SMasami Hiramatsu 669e4add247SMasami Hiramatsu list_for_each_entry(_op, &unoptimizing_list, list) { 670e4add247SMasami Hiramatsu if (op == _op) 671e4add247SMasami Hiramatsu return true; 672e4add247SMasami Hiramatsu } 673e4add247SMasami Hiramatsu 674e4add247SMasami Hiramatsu return false; 675e4add247SMasami Hiramatsu } 676e4add247SMasami Hiramatsu 677afd66255SMasami Hiramatsu /* Optimize kprobe if p is ready to be optimized */ 67855479f64SMasami Hiramatsu static void optimize_kprobe(struct kprobe *p) 679afd66255SMasami Hiramatsu { 680afd66255SMasami Hiramatsu struct optimized_kprobe *op; 681afd66255SMasami Hiramatsu 682afd66255SMasami Hiramatsu /* Check if the kprobe is disabled or not ready for optimization. */ 683b2be84dfSMasami Hiramatsu if (!kprobe_optready(p) || !kprobes_allow_optimization || 684afd66255SMasami Hiramatsu (kprobe_disabled(p) || kprobes_all_disarmed)) 685afd66255SMasami Hiramatsu return; 686afd66255SMasami Hiramatsu 687223a76b2SMasami Hiramatsu /* kprobes with 'post_handler' can not be optimized */ 688059053a2SMasami Hiramatsu if (p->post_handler) 689afd66255SMasami Hiramatsu return; 690afd66255SMasami Hiramatsu 691afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 692afd66255SMasami Hiramatsu 693afd66255SMasami Hiramatsu /* Check there is no other kprobes at the optimized instructions */ 694afd66255SMasami Hiramatsu if (arch_check_optimized_kprobe(op) < 0) 695afd66255SMasami Hiramatsu return; 696afd66255SMasami Hiramatsu 697afd66255SMasami Hiramatsu /* Check if it is already optimized. */ 698e4add247SMasami Hiramatsu if (op->kp.flags & KPROBE_FLAG_OPTIMIZED) { 699e4add247SMasami Hiramatsu if (optprobe_queued_unopt(op)) { 7006274de49SMasami Hiramatsu /* This is under unoptimizing. Just dequeue the probe */ 7016274de49SMasami Hiramatsu list_del_init(&op->list); 702e4add247SMasami Hiramatsu } 703e4add247SMasami Hiramatsu return; 704e4add247SMasami Hiramatsu } 705e4add247SMasami Hiramatsu op->kp.flags |= KPROBE_FLAG_OPTIMIZED; 706e4add247SMasami Hiramatsu 707223a76b2SMasami Hiramatsu /* 708223a76b2SMasami Hiramatsu * On the 'unoptimizing_list' and 'optimizing_list', 709223a76b2SMasami Hiramatsu * 'op' must have OPTIMIZED flag 710223a76b2SMasami Hiramatsu */ 711e4add247SMasami Hiramatsu if (WARN_ON_ONCE(!list_empty(&op->list))) 712e4add247SMasami Hiramatsu return; 713e4add247SMasami Hiramatsu 714afd66255SMasami Hiramatsu list_add(&op->list, &optimizing_list); 7156274de49SMasami Hiramatsu kick_kprobe_optimizer(); 7166274de49SMasami Hiramatsu } 7176274de49SMasami Hiramatsu 7186274de49SMasami Hiramatsu /* Short cut to direct unoptimizing */ 71955479f64SMasami Hiramatsu static void force_unoptimize_kprobe(struct optimized_kprobe *op) 7206274de49SMasami Hiramatsu { 7212d1e38f5SThomas Gleixner lockdep_assert_cpus_held(); 7226274de49SMasami Hiramatsu arch_unoptimize_kprobe(op); 723f66c0447SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 724afd66255SMasami Hiramatsu } 725afd66255SMasami Hiramatsu 726afd66255SMasami Hiramatsu /* Unoptimize a kprobe if p is optimized */ 72755479f64SMasami Hiramatsu static void unoptimize_kprobe(struct kprobe *p, bool force) 728afd66255SMasami Hiramatsu { 729afd66255SMasami Hiramatsu struct optimized_kprobe *op; 730afd66255SMasami Hiramatsu 7316274de49SMasami Hiramatsu if (!kprobe_aggrprobe(p) || kprobe_disarmed(p)) 7326274de49SMasami Hiramatsu return; /* This is not an optprobe nor optimized */ 7336274de49SMasami Hiramatsu 734afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 735e4add247SMasami Hiramatsu if (!kprobe_optimized(p)) 736e4add247SMasami Hiramatsu return; 737e4add247SMasami Hiramatsu 738e4add247SMasami Hiramatsu if (!list_empty(&op->list)) { 739e4add247SMasami Hiramatsu if (optprobe_queued_unopt(op)) { 740e4add247SMasami Hiramatsu /* Queued in unoptimizing queue */ 741e4add247SMasami Hiramatsu if (force) { 7426274de49SMasami Hiramatsu /* 743e4add247SMasami Hiramatsu * Forcibly unoptimize the kprobe here, and queue it 744e4add247SMasami Hiramatsu * in the freeing list for release afterwards. 7456274de49SMasami Hiramatsu */ 7466274de49SMasami Hiramatsu force_unoptimize_kprobe(op); 747e4add247SMasami Hiramatsu list_move(&op->list, &freeing_list); 748e4add247SMasami Hiramatsu } 749e4add247SMasami Hiramatsu } else { 750e4add247SMasami Hiramatsu /* Dequeue from the optimizing queue */ 751e4add247SMasami Hiramatsu list_del_init(&op->list); 752e4add247SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 7536274de49SMasami Hiramatsu } 7546274de49SMasami Hiramatsu return; 7556274de49SMasami Hiramatsu } 7566274de49SMasami Hiramatsu 7576274de49SMasami Hiramatsu /* Optimized kprobe case */ 758e4add247SMasami Hiramatsu if (force) { 7596274de49SMasami Hiramatsu /* Forcibly update the code: this is a special case */ 7606274de49SMasami Hiramatsu force_unoptimize_kprobe(op); 761e4add247SMasami Hiramatsu } else { 7626274de49SMasami Hiramatsu list_add(&op->list, &unoptimizing_list); 7636274de49SMasami Hiramatsu kick_kprobe_optimizer(); 764afd66255SMasami Hiramatsu } 765afd66255SMasami Hiramatsu } 766afd66255SMasami Hiramatsu 7670490cd1fSMasami Hiramatsu /* Cancel unoptimizing for reusing */ 768819319fcSMasami Hiramatsu static int reuse_unused_kprobe(struct kprobe *ap) 7690490cd1fSMasami Hiramatsu { 7700490cd1fSMasami Hiramatsu struct optimized_kprobe *op; 7710490cd1fSMasami Hiramatsu 7720490cd1fSMasami Hiramatsu /* 7730490cd1fSMasami Hiramatsu * Unused kprobe MUST be on the way of delayed unoptimizing (means 7740490cd1fSMasami Hiramatsu * there is still a relative jump) and disabled. 7750490cd1fSMasami Hiramatsu */ 7760490cd1fSMasami Hiramatsu op = container_of(ap, struct optimized_kprobe, kp); 7774458515bSMasami Hiramatsu WARN_ON_ONCE(list_empty(&op->list)); 7780490cd1fSMasami Hiramatsu /* Enable the probe again */ 7790490cd1fSMasami Hiramatsu ap->flags &= ~KPROBE_FLAG_DISABLED; 780223a76b2SMasami Hiramatsu /* Optimize it again. (remove from 'op->list') */ 7815f843ed4SMasami Hiramatsu if (!kprobe_optready(ap)) 7825f843ed4SMasami Hiramatsu return -EINVAL; 783819319fcSMasami Hiramatsu 7840490cd1fSMasami Hiramatsu optimize_kprobe(ap); 785819319fcSMasami Hiramatsu return 0; 7860490cd1fSMasami Hiramatsu } 7870490cd1fSMasami Hiramatsu 788afd66255SMasami Hiramatsu /* Remove optimized instructions */ 78955479f64SMasami Hiramatsu static void kill_optimized_kprobe(struct kprobe *p) 790afd66255SMasami Hiramatsu { 791afd66255SMasami Hiramatsu struct optimized_kprobe *op; 792afd66255SMasami Hiramatsu 793afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 7946274de49SMasami Hiramatsu if (!list_empty(&op->list)) 7956274de49SMasami Hiramatsu /* Dequeue from the (un)optimization queue */ 796afd66255SMasami Hiramatsu list_del_init(&op->list); 797afd66255SMasami Hiramatsu op->kp.flags &= ~KPROBE_FLAG_OPTIMIZED; 7987b959fc5SMasami Hiramatsu 7997b959fc5SMasami Hiramatsu if (kprobe_unused(p)) { 8007b959fc5SMasami Hiramatsu /* Enqueue if it is unused */ 8017b959fc5SMasami Hiramatsu list_add(&op->list, &freeing_list); 8027b959fc5SMasami Hiramatsu /* 8037b959fc5SMasami Hiramatsu * Remove unused probes from the hash list. After waiting 8047b959fc5SMasami Hiramatsu * for synchronization, this probe is reclaimed. 8057b959fc5SMasami Hiramatsu * (reclaiming is done by do_free_cleaned_kprobes().) 8067b959fc5SMasami Hiramatsu */ 8077b959fc5SMasami Hiramatsu hlist_del_rcu(&op->kp.hlist); 8087b959fc5SMasami Hiramatsu } 8097b959fc5SMasami Hiramatsu 8106274de49SMasami Hiramatsu /* Don't touch the code, because it is already freed. */ 811afd66255SMasami Hiramatsu arch_remove_optimized_kprobe(op); 812afd66255SMasami Hiramatsu } 813afd66255SMasami Hiramatsu 814a460246cSMasami Hiramatsu static inline 815a460246cSMasami Hiramatsu void __prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) 816a460246cSMasami Hiramatsu { 817a460246cSMasami Hiramatsu if (!kprobe_ftrace(p)) 818a460246cSMasami Hiramatsu arch_prepare_optimized_kprobe(op, p); 819a460246cSMasami Hiramatsu } 820a460246cSMasami Hiramatsu 821afd66255SMasami Hiramatsu /* Try to prepare optimized instructions */ 82255479f64SMasami Hiramatsu static void prepare_optimized_kprobe(struct kprobe *p) 823afd66255SMasami Hiramatsu { 824afd66255SMasami Hiramatsu struct optimized_kprobe *op; 825afd66255SMasami Hiramatsu 826afd66255SMasami Hiramatsu op = container_of(p, struct optimized_kprobe, kp); 827a460246cSMasami Hiramatsu __prepare_optimized_kprobe(op, p); 828afd66255SMasami Hiramatsu } 829afd66255SMasami Hiramatsu 830223a76b2SMasami Hiramatsu /* Allocate new optimized_kprobe and try to prepare optimized instructions. */ 83155479f64SMasami Hiramatsu static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) 832afd66255SMasami Hiramatsu { 833afd66255SMasami Hiramatsu struct optimized_kprobe *op; 834afd66255SMasami Hiramatsu 835afd66255SMasami Hiramatsu op = kzalloc(sizeof(struct optimized_kprobe), GFP_KERNEL); 836afd66255SMasami Hiramatsu if (!op) 837afd66255SMasami Hiramatsu return NULL; 838afd66255SMasami Hiramatsu 839afd66255SMasami Hiramatsu INIT_LIST_HEAD(&op->list); 840afd66255SMasami Hiramatsu op->kp.addr = p->addr; 841a460246cSMasami Hiramatsu __prepare_optimized_kprobe(op, p); 842afd66255SMasami Hiramatsu 843afd66255SMasami Hiramatsu return &op->kp; 844afd66255SMasami Hiramatsu } 845afd66255SMasami Hiramatsu 84655479f64SMasami Hiramatsu static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p); 847afd66255SMasami Hiramatsu 848afd66255SMasami Hiramatsu /* 849223a76b2SMasami Hiramatsu * Prepare an optimized_kprobe and optimize it. 850223a76b2SMasami Hiramatsu * NOTE: 'p' must be a normal registered kprobe. 851afd66255SMasami Hiramatsu */ 85255479f64SMasami Hiramatsu static void try_to_optimize_kprobe(struct kprobe *p) 853afd66255SMasami Hiramatsu { 854afd66255SMasami Hiramatsu struct kprobe *ap; 855afd66255SMasami Hiramatsu struct optimized_kprobe *op; 856afd66255SMasami Hiramatsu 857223a76b2SMasami Hiramatsu /* Impossible to optimize ftrace-based kprobe. */ 858ae6aa16fSMasami Hiramatsu if (kprobe_ftrace(p)) 859ae6aa16fSMasami Hiramatsu return; 860ae6aa16fSMasami Hiramatsu 861223a76b2SMasami Hiramatsu /* For preparing optimization, jump_label_text_reserved() is called. */ 8622d1e38f5SThomas Gleixner cpus_read_lock(); 86325764288SMasami Hiramatsu jump_label_lock(); 86425764288SMasami Hiramatsu mutex_lock(&text_mutex); 86525764288SMasami Hiramatsu 866afd66255SMasami Hiramatsu ap = alloc_aggr_kprobe(p); 867afd66255SMasami Hiramatsu if (!ap) 86825764288SMasami Hiramatsu goto out; 869afd66255SMasami Hiramatsu 870afd66255SMasami Hiramatsu op = container_of(ap, struct optimized_kprobe, kp); 871afd66255SMasami Hiramatsu if (!arch_prepared_optinsn(&op->optinsn)) { 872223a76b2SMasami Hiramatsu /* If failed to setup optimizing, fallback to kprobe. */ 8736274de49SMasami Hiramatsu arch_remove_optimized_kprobe(op); 8746274de49SMasami Hiramatsu kfree(op); 87525764288SMasami Hiramatsu goto out; 876afd66255SMasami Hiramatsu } 877afd66255SMasami Hiramatsu 878afd66255SMasami Hiramatsu init_aggr_kprobe(ap, p); 879223a76b2SMasami Hiramatsu optimize_kprobe(ap); /* This just kicks optimizer thread. */ 88025764288SMasami Hiramatsu 88125764288SMasami Hiramatsu out: 88225764288SMasami Hiramatsu mutex_unlock(&text_mutex); 88325764288SMasami Hiramatsu jump_label_unlock(); 8842d1e38f5SThomas Gleixner cpus_read_unlock(); 885afd66255SMasami Hiramatsu } 886afd66255SMasami Hiramatsu 88755479f64SMasami Hiramatsu static void optimize_all_kprobes(void) 888b2be84dfSMasami Hiramatsu { 889b2be84dfSMasami Hiramatsu struct hlist_head *head; 890b2be84dfSMasami Hiramatsu struct kprobe *p; 891b2be84dfSMasami Hiramatsu unsigned int i; 892b2be84dfSMasami Hiramatsu 8935c51543bSMasami Hiramatsu mutex_lock(&kprobe_mutex); 894223a76b2SMasami Hiramatsu /* If optimization is already allowed, just return. */ 895b2be84dfSMasami Hiramatsu if (kprobes_allow_optimization) 8965c51543bSMasami Hiramatsu goto out; 897b2be84dfSMasami Hiramatsu 8982d1e38f5SThomas Gleixner cpus_read_lock(); 899b2be84dfSMasami Hiramatsu kprobes_allow_optimization = true; 900b2be84dfSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 901b2be84dfSMasami Hiramatsu head = &kprobe_table[i]; 9027e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) 903b2be84dfSMasami Hiramatsu if (!kprobe_disabled(p)) 904b2be84dfSMasami Hiramatsu optimize_kprobe(p); 905b2be84dfSMasami Hiramatsu } 9062d1e38f5SThomas Gleixner cpus_read_unlock(); 9079c89bb8eSMasami Hiramatsu pr_info("kprobe jump-optimization is enabled. All kprobes are optimized if possible.\n"); 9085c51543bSMasami Hiramatsu out: 9095c51543bSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 910b2be84dfSMasami Hiramatsu } 911b2be84dfSMasami Hiramatsu 912c85c9a2cSMasami Hiramatsu #ifdef CONFIG_SYSCTL 91355479f64SMasami Hiramatsu static void unoptimize_all_kprobes(void) 914b2be84dfSMasami Hiramatsu { 915b2be84dfSMasami Hiramatsu struct hlist_head *head; 916b2be84dfSMasami Hiramatsu struct kprobe *p; 917b2be84dfSMasami Hiramatsu unsigned int i; 918b2be84dfSMasami Hiramatsu 9195c51543bSMasami Hiramatsu mutex_lock(&kprobe_mutex); 920223a76b2SMasami Hiramatsu /* If optimization is already prohibited, just return. */ 9215c51543bSMasami Hiramatsu if (!kprobes_allow_optimization) { 9225c51543bSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 923b2be84dfSMasami Hiramatsu return; 9245c51543bSMasami Hiramatsu } 925b2be84dfSMasami Hiramatsu 9262d1e38f5SThomas Gleixner cpus_read_lock(); 927b2be84dfSMasami Hiramatsu kprobes_allow_optimization = false; 928b2be84dfSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 929b2be84dfSMasami Hiramatsu head = &kprobe_table[i]; 9307e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 931b2be84dfSMasami Hiramatsu if (!kprobe_disabled(p)) 9326274de49SMasami Hiramatsu unoptimize_kprobe(p, false); 933b2be84dfSMasami Hiramatsu } 934b2be84dfSMasami Hiramatsu } 9352d1e38f5SThomas Gleixner cpus_read_unlock(); 9365c51543bSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 9375c51543bSMasami Hiramatsu 938223a76b2SMasami Hiramatsu /* Wait for unoptimizing completion. */ 9396274de49SMasami Hiramatsu wait_for_kprobe_optimizer(); 9409c89bb8eSMasami Hiramatsu pr_info("kprobe jump-optimization is disabled. All kprobes are based on software breakpoint.\n"); 941b2be84dfSMasami Hiramatsu } 942b2be84dfSMasami Hiramatsu 9435c51543bSMasami Hiramatsu static DEFINE_MUTEX(kprobe_sysctl_mutex); 944a737a3c6SXiaoming Ni static int sysctl_kprobes_optimization; 945a737a3c6SXiaoming Ni static int proc_kprobes_optimization_handler(struct ctl_table *table, 946a737a3c6SXiaoming Ni int write, void *buffer, 947a737a3c6SXiaoming Ni size_t *length, loff_t *ppos) 948b2be84dfSMasami Hiramatsu { 949b2be84dfSMasami Hiramatsu int ret; 950b2be84dfSMasami Hiramatsu 9515c51543bSMasami Hiramatsu mutex_lock(&kprobe_sysctl_mutex); 952b2be84dfSMasami Hiramatsu sysctl_kprobes_optimization = kprobes_allow_optimization ? 1 : 0; 953b2be84dfSMasami Hiramatsu ret = proc_dointvec_minmax(table, write, buffer, length, ppos); 954b2be84dfSMasami Hiramatsu 955b2be84dfSMasami Hiramatsu if (sysctl_kprobes_optimization) 956b2be84dfSMasami Hiramatsu optimize_all_kprobes(); 957b2be84dfSMasami Hiramatsu else 958b2be84dfSMasami Hiramatsu unoptimize_all_kprobes(); 9595c51543bSMasami Hiramatsu mutex_unlock(&kprobe_sysctl_mutex); 960b2be84dfSMasami Hiramatsu 961b2be84dfSMasami Hiramatsu return ret; 962b2be84dfSMasami Hiramatsu } 963a737a3c6SXiaoming Ni 964a737a3c6SXiaoming Ni static struct ctl_table kprobe_sysctls[] = { 965a737a3c6SXiaoming Ni { 966a737a3c6SXiaoming Ni .procname = "kprobes-optimization", 967a737a3c6SXiaoming Ni .data = &sysctl_kprobes_optimization, 968a737a3c6SXiaoming Ni .maxlen = sizeof(int), 969a737a3c6SXiaoming Ni .mode = 0644, 970a737a3c6SXiaoming Ni .proc_handler = proc_kprobes_optimization_handler, 971a737a3c6SXiaoming Ni .extra1 = SYSCTL_ZERO, 972a737a3c6SXiaoming Ni .extra2 = SYSCTL_ONE, 973a737a3c6SXiaoming Ni }, 974a737a3c6SXiaoming Ni {} 975a737a3c6SXiaoming Ni }; 976a737a3c6SXiaoming Ni 977a737a3c6SXiaoming Ni static void __init kprobe_sysctls_init(void) 978a737a3c6SXiaoming Ni { 979a737a3c6SXiaoming Ni register_sysctl_init("debug", kprobe_sysctls); 980a737a3c6SXiaoming Ni } 981b2be84dfSMasami Hiramatsu #endif /* CONFIG_SYSCTL */ 982b2be84dfSMasami Hiramatsu 98357d4e317SMasami Hiramatsu /* Put a breakpoint for a probe. */ 98455479f64SMasami Hiramatsu static void __arm_kprobe(struct kprobe *p) 985afd66255SMasami Hiramatsu { 9866d8e40a8SMasami Hiramatsu struct kprobe *_p; 987afd66255SMasami Hiramatsu 98857d4e317SMasami Hiramatsu lockdep_assert_held(&text_mutex); 98957d4e317SMasami Hiramatsu 990223a76b2SMasami Hiramatsu /* Find the overlapping optimized kprobes. */ 991c42421e2SMasami Hiramatsu _p = get_optimized_kprobe(p->addr); 9926d8e40a8SMasami Hiramatsu if (unlikely(_p)) 9936274de49SMasami Hiramatsu /* Fallback to unoptimized kprobe */ 9946274de49SMasami Hiramatsu unoptimize_kprobe(_p, true); 995afd66255SMasami Hiramatsu 996afd66255SMasami Hiramatsu arch_arm_kprobe(p); 997afd66255SMasami Hiramatsu optimize_kprobe(p); /* Try to optimize (add kprobe to a list) */ 998afd66255SMasami Hiramatsu } 999afd66255SMasami Hiramatsu 100057d4e317SMasami Hiramatsu /* Remove the breakpoint of a probe. */ 100155479f64SMasami Hiramatsu static void __disarm_kprobe(struct kprobe *p, bool reopt) 1002afd66255SMasami Hiramatsu { 10036d8e40a8SMasami Hiramatsu struct kprobe *_p; 1004afd66255SMasami Hiramatsu 100557d4e317SMasami Hiramatsu lockdep_assert_held(&text_mutex); 100657d4e317SMasami Hiramatsu 100769d54b91SWang Nan /* Try to unoptimize */ 100869d54b91SWang Nan unoptimize_kprobe(p, kprobes_all_disarmed); 1009afd66255SMasami Hiramatsu 10106274de49SMasami Hiramatsu if (!kprobe_queued(p)) { 10116274de49SMasami Hiramatsu arch_disarm_kprobe(p); 1012223a76b2SMasami Hiramatsu /* If another kprobe was blocked, re-optimize it. */ 1013c42421e2SMasami Hiramatsu _p = get_optimized_kprobe(p->addr); 10146274de49SMasami Hiramatsu if (unlikely(_p) && reopt) 10156d8e40a8SMasami Hiramatsu optimize_kprobe(_p); 1016afd66255SMasami Hiramatsu } 1017223a76b2SMasami Hiramatsu /* 1018223a76b2SMasami Hiramatsu * TODO: Since unoptimization and real disarming will be done by 1019223a76b2SMasami Hiramatsu * the worker thread, we can not check whether another probe are 1020223a76b2SMasami Hiramatsu * unoptimized because of this probe here. It should be re-optimized 1021223a76b2SMasami Hiramatsu * by the worker thread. 1022223a76b2SMasami Hiramatsu */ 10236274de49SMasami Hiramatsu } 1024afd66255SMasami Hiramatsu 1025afd66255SMasami Hiramatsu #else /* !CONFIG_OPTPROBES */ 1026afd66255SMasami Hiramatsu 1027afd66255SMasami Hiramatsu #define optimize_kprobe(p) do {} while (0) 10286274de49SMasami Hiramatsu #define unoptimize_kprobe(p, f) do {} while (0) 1029afd66255SMasami Hiramatsu #define kill_optimized_kprobe(p) do {} while (0) 1030afd66255SMasami Hiramatsu #define prepare_optimized_kprobe(p) do {} while (0) 1031afd66255SMasami Hiramatsu #define try_to_optimize_kprobe(p) do {} while (0) 1032afd66255SMasami Hiramatsu #define __arm_kprobe(p) arch_arm_kprobe(p) 10336274de49SMasami Hiramatsu #define __disarm_kprobe(p, o) arch_disarm_kprobe(p) 10346274de49SMasami Hiramatsu #define kprobe_disarmed(p) kprobe_disabled(p) 10356274de49SMasami Hiramatsu #define wait_for_kprobe_optimizer() do {} while (0) 1036afd66255SMasami Hiramatsu 1037819319fcSMasami Hiramatsu static int reuse_unused_kprobe(struct kprobe *ap) 10380490cd1fSMasami Hiramatsu { 1039819319fcSMasami Hiramatsu /* 1040819319fcSMasami Hiramatsu * If the optimized kprobe is NOT supported, the aggr kprobe is 1041819319fcSMasami Hiramatsu * released at the same time that the last aggregated kprobe is 1042819319fcSMasami Hiramatsu * unregistered. 1043819319fcSMasami Hiramatsu * Thus there should be no chance to reuse unused kprobe. 1044819319fcSMasami Hiramatsu */ 10459c89bb8eSMasami Hiramatsu WARN_ON_ONCE(1); 1046819319fcSMasami Hiramatsu return -EINVAL; 10470490cd1fSMasami Hiramatsu } 10480490cd1fSMasami Hiramatsu 104955479f64SMasami Hiramatsu static void free_aggr_kprobe(struct kprobe *p) 1050afd66255SMasami Hiramatsu { 10516274de49SMasami Hiramatsu arch_remove_kprobe(p); 1052afd66255SMasami Hiramatsu kfree(p); 1053afd66255SMasami Hiramatsu } 1054afd66255SMasami Hiramatsu 105555479f64SMasami Hiramatsu static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) 1056afd66255SMasami Hiramatsu { 1057afd66255SMasami Hiramatsu return kzalloc(sizeof(struct kprobe), GFP_KERNEL); 1058afd66255SMasami Hiramatsu } 1059afd66255SMasami Hiramatsu #endif /* CONFIG_OPTPROBES */ 1060afd66255SMasami Hiramatsu 1061e7dbfe34SMasami Hiramatsu #ifdef CONFIG_KPROBES_ON_FTRACE 1062ae6aa16fSMasami Hiramatsu static struct ftrace_ops kprobe_ftrace_ops __read_mostly = { 1063e5253896SMasami Hiramatsu .func = kprobe_ftrace_handler, 10640bc11ed5SMasami Hiramatsu .flags = FTRACE_OPS_FL_SAVE_REGS, 10650bc11ed5SMasami Hiramatsu }; 10660bc11ed5SMasami Hiramatsu 10670bc11ed5SMasami Hiramatsu static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = { 10680bc11ed5SMasami Hiramatsu .func = kprobe_ftrace_handler, 10691d70be34SMasami Hiramatsu .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY, 1070ae6aa16fSMasami Hiramatsu }; 10710bc11ed5SMasami Hiramatsu 10720bc11ed5SMasami Hiramatsu static int kprobe_ipmodify_enabled; 1073ae6aa16fSMasami Hiramatsu static int kprobe_ftrace_enabled; 1074ae6aa16fSMasami Hiramatsu 10750bc11ed5SMasami Hiramatsu static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, 10760bc11ed5SMasami Hiramatsu int *cnt) 1077ae6aa16fSMasami Hiramatsu { 107812310e34SJessica Yu int ret = 0; 1079ae6aa16fSMasami Hiramatsu 108057d4e317SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 108157d4e317SMasami Hiramatsu 10820bc11ed5SMasami Hiramatsu ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 0, 0); 10839c89bb8eSMasami Hiramatsu if (WARN_ONCE(ret < 0, "Failed to arm kprobe-ftrace at %pS (error %d)\n", p->addr, ret)) 108412310e34SJessica Yu return ret; 108512310e34SJessica Yu 10860bc11ed5SMasami Hiramatsu if (*cnt == 0) { 10870bc11ed5SMasami Hiramatsu ret = register_ftrace_function(ops); 10889c89bb8eSMasami Hiramatsu if (WARN(ret < 0, "Failed to register kprobe-ftrace (error %d)\n", ret)) 108912310e34SJessica Yu goto err_ftrace; 109012310e34SJessica Yu } 109112310e34SJessica Yu 10920bc11ed5SMasami Hiramatsu (*cnt)++; 109312310e34SJessica Yu return ret; 109412310e34SJessica Yu 109512310e34SJessica Yu err_ftrace: 109612310e34SJessica Yu /* 10970bc11ed5SMasami Hiramatsu * At this point, sinec ops is not registered, we should be sefe from 10980bc11ed5SMasami Hiramatsu * registering empty filter. 109912310e34SJessica Yu */ 11000bc11ed5SMasami Hiramatsu ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0); 110112310e34SJessica Yu return ret; 1102ae6aa16fSMasami Hiramatsu } 1103ae6aa16fSMasami Hiramatsu 11040bc11ed5SMasami Hiramatsu static int arm_kprobe_ftrace(struct kprobe *p) 11050bc11ed5SMasami Hiramatsu { 11060bc11ed5SMasami Hiramatsu bool ipmodify = (p->post_handler != NULL); 11070bc11ed5SMasami Hiramatsu 11080bc11ed5SMasami Hiramatsu return __arm_kprobe_ftrace(p, 11090bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, 11100bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); 11110bc11ed5SMasami Hiramatsu } 11120bc11ed5SMasami Hiramatsu 11130bc11ed5SMasami Hiramatsu static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, 11140bc11ed5SMasami Hiramatsu int *cnt) 1115ae6aa16fSMasami Hiramatsu { 1116297f9233SJessica Yu int ret = 0; 1117297f9233SJessica Yu 111857d4e317SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 111957d4e317SMasami Hiramatsu 11200bc11ed5SMasami Hiramatsu if (*cnt == 1) { 11210bc11ed5SMasami Hiramatsu ret = unregister_ftrace_function(ops); 11229c89bb8eSMasami Hiramatsu if (WARN(ret < 0, "Failed to unregister kprobe-ftrace (error %d)\n", ret)) 1123297f9233SJessica Yu return ret; 1124297f9233SJessica Yu } 1125ae6aa16fSMasami Hiramatsu 11260bc11ed5SMasami Hiramatsu (*cnt)--; 1127297f9233SJessica Yu 11280bc11ed5SMasami Hiramatsu ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 1, 0); 11299c89bb8eSMasami Hiramatsu WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (error %d)\n", 11304458515bSMasami Hiramatsu p->addr, ret); 1131297f9233SJessica Yu return ret; 1132ae6aa16fSMasami Hiramatsu } 11330bc11ed5SMasami Hiramatsu 11340bc11ed5SMasami Hiramatsu static int disarm_kprobe_ftrace(struct kprobe *p) 11350bc11ed5SMasami Hiramatsu { 11360bc11ed5SMasami Hiramatsu bool ipmodify = (p->post_handler != NULL); 11370bc11ed5SMasami Hiramatsu 11380bc11ed5SMasami Hiramatsu return __disarm_kprobe_ftrace(p, 11390bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_ops : &kprobe_ftrace_ops, 11400bc11ed5SMasami Hiramatsu ipmodify ? &kprobe_ipmodify_enabled : &kprobe_ftrace_enabled); 11410bc11ed5SMasami Hiramatsu } 1142e7dbfe34SMasami Hiramatsu #else /* !CONFIG_KPROBES_ON_FTRACE */ 114310de795aSMuchun Song static inline int arm_kprobe_ftrace(struct kprobe *p) 114410de795aSMuchun Song { 114510de795aSMuchun Song return -ENODEV; 114610de795aSMuchun Song } 114710de795aSMuchun Song 114810de795aSMuchun Song static inline int disarm_kprobe_ftrace(struct kprobe *p) 114910de795aSMuchun Song { 115010de795aSMuchun Song return -ENODEV; 115110de795aSMuchun Song } 1152ae6aa16fSMasami Hiramatsu #endif 1153ae6aa16fSMasami Hiramatsu 115402afb8d6SPunit Agrawal static int prepare_kprobe(struct kprobe *p) 115502afb8d6SPunit Agrawal { 115602afb8d6SPunit Agrawal /* Must ensure p->addr is really on ftrace */ 115702afb8d6SPunit Agrawal if (kprobe_ftrace(p)) 115802afb8d6SPunit Agrawal return arch_prepare_kprobe_ftrace(p); 115902afb8d6SPunit Agrawal 116002afb8d6SPunit Agrawal return arch_prepare_kprobe(p); 116102afb8d6SPunit Agrawal } 116202afb8d6SPunit Agrawal 116312310e34SJessica Yu static int arm_kprobe(struct kprobe *kp) 1164201517a7SMasami Hiramatsu { 116512310e34SJessica Yu if (unlikely(kprobe_ftrace(kp))) 116612310e34SJessica Yu return arm_kprobe_ftrace(kp); 116712310e34SJessica Yu 11682d1e38f5SThomas Gleixner cpus_read_lock(); 1169201517a7SMasami Hiramatsu mutex_lock(&text_mutex); 1170afd66255SMasami Hiramatsu __arm_kprobe(kp); 1171201517a7SMasami Hiramatsu mutex_unlock(&text_mutex); 11722d1e38f5SThomas Gleixner cpus_read_unlock(); 117312310e34SJessica Yu 117412310e34SJessica Yu return 0; 1175201517a7SMasami Hiramatsu } 1176201517a7SMasami Hiramatsu 1177297f9233SJessica Yu static int disarm_kprobe(struct kprobe *kp, bool reopt) 1178201517a7SMasami Hiramatsu { 1179297f9233SJessica Yu if (unlikely(kprobe_ftrace(kp))) 1180297f9233SJessica Yu return disarm_kprobe_ftrace(kp); 11812d1e38f5SThomas Gleixner 11822d1e38f5SThomas Gleixner cpus_read_lock(); 1183201517a7SMasami Hiramatsu mutex_lock(&text_mutex); 1184ae6aa16fSMasami Hiramatsu __disarm_kprobe(kp, reopt); 1185201517a7SMasami Hiramatsu mutex_unlock(&text_mutex); 11862d1e38f5SThomas Gleixner cpus_read_unlock(); 1187297f9233SJessica Yu 1188297f9233SJessica Yu return 0; 1189201517a7SMasami Hiramatsu } 1190201517a7SMasami Hiramatsu 119164f562c6SAnanth N Mavinakayanahalli /* 119264f562c6SAnanth N Mavinakayanahalli * Aggregate handlers for multiple kprobes support - these handlers 119364f562c6SAnanth N Mavinakayanahalli * take care of invoking the individual kprobe handlers on p->list 119464f562c6SAnanth N Mavinakayanahalli */ 1195820aede0SMasami Hiramatsu static int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs) 119664f562c6SAnanth N Mavinakayanahalli { 119764f562c6SAnanth N Mavinakayanahalli struct kprobe *kp; 119864f562c6SAnanth N Mavinakayanahalli 11993516a460SAnanth N Mavinakayanahalli list_for_each_entry_rcu(kp, &p->list, list) { 1200de5bd88dSMasami Hiramatsu if (kp->pre_handler && likely(!kprobe_disabled(kp))) { 1201e6584523SAnanth N Mavinakayanahalli set_kprobe_instance(kp); 12028b0914eaSPrasanna S Panchamukhi if (kp->pre_handler(kp, regs)) 12038b0914eaSPrasanna S Panchamukhi return 1; 120464f562c6SAnanth N Mavinakayanahalli } 1205e6584523SAnanth N Mavinakayanahalli reset_kprobe_instance(); 120664f562c6SAnanth N Mavinakayanahalli } 120764f562c6SAnanth N Mavinakayanahalli return 0; 120864f562c6SAnanth N Mavinakayanahalli } 1209820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(aggr_pre_handler); 121064f562c6SAnanth N Mavinakayanahalli 1211820aede0SMasami Hiramatsu static void aggr_post_handler(struct kprobe *p, struct pt_regs *regs, 121264f562c6SAnanth N Mavinakayanahalli unsigned long flags) 121364f562c6SAnanth N Mavinakayanahalli { 121464f562c6SAnanth N Mavinakayanahalli struct kprobe *kp; 121564f562c6SAnanth N Mavinakayanahalli 12163516a460SAnanth N Mavinakayanahalli list_for_each_entry_rcu(kp, &p->list, list) { 1217de5bd88dSMasami Hiramatsu if (kp->post_handler && likely(!kprobe_disabled(kp))) { 1218e6584523SAnanth N Mavinakayanahalli set_kprobe_instance(kp); 121964f562c6SAnanth N Mavinakayanahalli kp->post_handler(kp, regs, flags); 1220e6584523SAnanth N Mavinakayanahalli reset_kprobe_instance(); 122164f562c6SAnanth N Mavinakayanahalli } 122264f562c6SAnanth N Mavinakayanahalli } 122364f562c6SAnanth N Mavinakayanahalli } 1224820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(aggr_post_handler); 122564f562c6SAnanth N Mavinakayanahalli 1226223a76b2SMasami Hiramatsu /* Walks the list and increments 'nmissed' if 'p' has child probes. */ 1227820aede0SMasami Hiramatsu void kprobes_inc_nmissed_count(struct kprobe *p) 1228bf8d5c52SKeshavamurthy Anil S { 1229bf8d5c52SKeshavamurthy Anil S struct kprobe *kp; 1230223a76b2SMasami Hiramatsu 1231afd66255SMasami Hiramatsu if (!kprobe_aggrprobe(p)) { 1232bf8d5c52SKeshavamurthy Anil S p->nmissed++; 1233bf8d5c52SKeshavamurthy Anil S } else { 1234bf8d5c52SKeshavamurthy Anil S list_for_each_entry_rcu(kp, &p->list, list) 1235bf8d5c52SKeshavamurthy Anil S kp->nmissed++; 1236bf8d5c52SKeshavamurthy Anil S } 1237bf8d5c52SKeshavamurthy Anil S } 1238820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(kprobes_inc_nmissed_count); 1239bf8d5c52SKeshavamurthy Anil S 124073f9b911SMasami Hiramatsu static struct kprobe kprobe_busy = { 124173f9b911SMasami Hiramatsu .addr = (void *) get_kprobe, 124273f9b911SMasami Hiramatsu }; 124373f9b911SMasami Hiramatsu 124473f9b911SMasami Hiramatsu void kprobe_busy_begin(void) 124573f9b911SMasami Hiramatsu { 124673f9b911SMasami Hiramatsu struct kprobe_ctlblk *kcb; 124773f9b911SMasami Hiramatsu 124873f9b911SMasami Hiramatsu preempt_disable(); 124973f9b911SMasami Hiramatsu __this_cpu_write(current_kprobe, &kprobe_busy); 125073f9b911SMasami Hiramatsu kcb = get_kprobe_ctlblk(); 125173f9b911SMasami Hiramatsu kcb->kprobe_status = KPROBE_HIT_ACTIVE; 125273f9b911SMasami Hiramatsu } 125373f9b911SMasami Hiramatsu 125473f9b911SMasami Hiramatsu void kprobe_busy_end(void) 125573f9b911SMasami Hiramatsu { 125673f9b911SMasami Hiramatsu __this_cpu_write(current_kprobe, NULL); 125773f9b911SMasami Hiramatsu preempt_enable(); 125873f9b911SMasami Hiramatsu } 125973f9b911SMasami Hiramatsu 1260223a76b2SMasami Hiramatsu /* Add the new probe to 'ap->list'. */ 126155479f64SMasami Hiramatsu static int add_new_kprobe(struct kprobe *ap, struct kprobe *p) 12628b0914eaSPrasanna S Panchamukhi { 1263059053a2SMasami Hiramatsu if (p->post_handler) 12646274de49SMasami Hiramatsu unoptimize_kprobe(ap, true); /* Fall back to normal kprobe */ 1265afd66255SMasami Hiramatsu 1266b918e5e6SMasami Hiramatsu list_add_rcu(&p->list, &ap->list); 1267b918e5e6SMasami Hiramatsu if (p->post_handler && !ap->post_handler) 1268b918e5e6SMasami Hiramatsu ap->post_handler = aggr_post_handler; 1269de5bd88dSMasami Hiramatsu 12708b0914eaSPrasanna S Panchamukhi return 0; 12718b0914eaSPrasanna S Panchamukhi } 12728b0914eaSPrasanna S Panchamukhi 12738b0914eaSPrasanna S Panchamukhi /* 1274223a76b2SMasami Hiramatsu * Fill in the required fields of the aggregator kprobe. Replace the 1275223a76b2SMasami Hiramatsu * earlier kprobe in the hlist with the aggregator kprobe. 127664f562c6SAnanth N Mavinakayanahalli */ 127755479f64SMasami Hiramatsu static void init_aggr_kprobe(struct kprobe *ap, struct kprobe *p) 127864f562c6SAnanth N Mavinakayanahalli { 1279223a76b2SMasami Hiramatsu /* Copy the insn slot of 'p' to 'ap'. */ 12808b0914eaSPrasanna S Panchamukhi copy_kprobe(p, ap); 1281a9ad965eSbibo, mao flush_insn_slot(ap); 128264f562c6SAnanth N Mavinakayanahalli ap->addr = p->addr; 1283afd66255SMasami Hiramatsu ap->flags = p->flags & ~KPROBE_FLAG_OPTIMIZED; 128464f562c6SAnanth N Mavinakayanahalli ap->pre_handler = aggr_pre_handler; 1285e8386a0cSMasami Hiramatsu /* We don't care the kprobe which has gone. */ 1286e8386a0cSMasami Hiramatsu if (p->post_handler && !kprobe_gone(p)) 128736721656Smao, bibo ap->post_handler = aggr_post_handler; 128864f562c6SAnanth N Mavinakayanahalli 128964f562c6SAnanth N Mavinakayanahalli INIT_LIST_HEAD(&ap->list); 1290afd66255SMasami Hiramatsu INIT_HLIST_NODE(&ap->hlist); 129164f562c6SAnanth N Mavinakayanahalli 1292afd66255SMasami Hiramatsu list_add_rcu(&p->list, &ap->list); 1293adad0f33SKeshavamurthy Anil S hlist_replace_rcu(&p->hlist, &ap->hlist); 129464f562c6SAnanth N Mavinakayanahalli } 129564f562c6SAnanth N Mavinakayanahalli 129664f562c6SAnanth N Mavinakayanahalli /* 1297223a76b2SMasami Hiramatsu * This registers the second or subsequent kprobe at the same address. 129864f562c6SAnanth N Mavinakayanahalli */ 129955479f64SMasami Hiramatsu static int register_aggr_kprobe(struct kprobe *orig_p, struct kprobe *p) 130064f562c6SAnanth N Mavinakayanahalli { 130164f562c6SAnanth N Mavinakayanahalli int ret = 0; 13026d8e40a8SMasami Hiramatsu struct kprobe *ap = orig_p; 130364f562c6SAnanth N Mavinakayanahalli 13042d1e38f5SThomas Gleixner cpus_read_lock(); 13052d1e38f5SThomas Gleixner 130625764288SMasami Hiramatsu /* For preparing optimization, jump_label_text_reserved() is called */ 130725764288SMasami Hiramatsu jump_label_lock(); 130825764288SMasami Hiramatsu mutex_lock(&text_mutex); 130925764288SMasami Hiramatsu 13106d8e40a8SMasami Hiramatsu if (!kprobe_aggrprobe(orig_p)) { 1311223a76b2SMasami Hiramatsu /* If 'orig_p' is not an 'aggr_kprobe', create new one. */ 13126d8e40a8SMasami Hiramatsu ap = alloc_aggr_kprobe(orig_p); 131325764288SMasami Hiramatsu if (!ap) { 131425764288SMasami Hiramatsu ret = -ENOMEM; 131525764288SMasami Hiramatsu goto out; 131625764288SMasami Hiramatsu } 13176d8e40a8SMasami Hiramatsu init_aggr_kprobe(ap, orig_p); 1318819319fcSMasami Hiramatsu } else if (kprobe_unused(ap)) { 13190490cd1fSMasami Hiramatsu /* This probe is going to die. Rescue it */ 1320819319fcSMasami Hiramatsu ret = reuse_unused_kprobe(ap); 1321819319fcSMasami Hiramatsu if (ret) 1322819319fcSMasami Hiramatsu goto out; 1323819319fcSMasami Hiramatsu } 1324b918e5e6SMasami Hiramatsu 1325b918e5e6SMasami Hiramatsu if (kprobe_gone(ap)) { 1326e8386a0cSMasami Hiramatsu /* 1327e8386a0cSMasami Hiramatsu * Attempting to insert new probe at the same location that 1328e8386a0cSMasami Hiramatsu * had a probe in the module vaddr area which already 1329e8386a0cSMasami Hiramatsu * freed. So, the instruction slot has already been 1330e8386a0cSMasami Hiramatsu * released. We need a new slot for the new probe. 1331e8386a0cSMasami Hiramatsu */ 1332b918e5e6SMasami Hiramatsu ret = arch_prepare_kprobe(ap); 1333e8386a0cSMasami Hiramatsu if (ret) 1334b918e5e6SMasami Hiramatsu /* 1335b918e5e6SMasami Hiramatsu * Even if fail to allocate new slot, don't need to 1336223a76b2SMasami Hiramatsu * free the 'ap'. It will be used next time, or 1337223a76b2SMasami Hiramatsu * freed by unregister_kprobe(). 1338b918e5e6SMasami Hiramatsu */ 133925764288SMasami Hiramatsu goto out; 1340de5bd88dSMasami Hiramatsu 1341afd66255SMasami Hiramatsu /* Prepare optimized instructions if possible. */ 1342afd66255SMasami Hiramatsu prepare_optimized_kprobe(ap); 1343afd66255SMasami Hiramatsu 1344e8386a0cSMasami Hiramatsu /* 1345de5bd88dSMasami Hiramatsu * Clear gone flag to prevent allocating new slot again, and 1346de5bd88dSMasami Hiramatsu * set disabled flag because it is not armed yet. 1347e8386a0cSMasami Hiramatsu */ 1348de5bd88dSMasami Hiramatsu ap->flags = (ap->flags & ~KPROBE_FLAG_GONE) 1349de5bd88dSMasami Hiramatsu | KPROBE_FLAG_DISABLED; 1350e8386a0cSMasami Hiramatsu } 1351b918e5e6SMasami Hiramatsu 1352223a76b2SMasami Hiramatsu /* Copy the insn slot of 'p' to 'ap'. */ 1353b918e5e6SMasami Hiramatsu copy_kprobe(ap, p); 135425764288SMasami Hiramatsu ret = add_new_kprobe(ap, p); 135525764288SMasami Hiramatsu 135625764288SMasami Hiramatsu out: 135725764288SMasami Hiramatsu mutex_unlock(&text_mutex); 135825764288SMasami Hiramatsu jump_label_unlock(); 13592d1e38f5SThomas Gleixner cpus_read_unlock(); 136025764288SMasami Hiramatsu 136125764288SMasami Hiramatsu if (ret == 0 && kprobe_disabled(ap) && !kprobe_disabled(p)) { 136225764288SMasami Hiramatsu ap->flags &= ~KPROBE_FLAG_DISABLED; 136312310e34SJessica Yu if (!kprobes_all_disarmed) { 136425764288SMasami Hiramatsu /* Arm the breakpoint again. */ 136512310e34SJessica Yu ret = arm_kprobe(ap); 136612310e34SJessica Yu if (ret) { 136712310e34SJessica Yu ap->flags |= KPROBE_FLAG_DISABLED; 136812310e34SJessica Yu list_del_rcu(&p->list); 1369ae8b7ce7SPaul E. McKenney synchronize_rcu(); 137012310e34SJessica Yu } 137112310e34SJessica Yu } 137225764288SMasami Hiramatsu } 137325764288SMasami Hiramatsu return ret; 137464f562c6SAnanth N Mavinakayanahalli } 137564f562c6SAnanth N Mavinakayanahalli 1376be8f2743SMasami Hiramatsu bool __weak arch_within_kprobe_blacklist(unsigned long addr) 1377be8f2743SMasami Hiramatsu { 1378223a76b2SMasami Hiramatsu /* The '__kprobes' functions and entry code must not be probed. */ 1379be8f2743SMasami Hiramatsu return addr >= (unsigned long)__kprobes_text_start && 1380be8f2743SMasami Hiramatsu addr < (unsigned long)__kprobes_text_end; 1381be8f2743SMasami Hiramatsu } 1382be8f2743SMasami Hiramatsu 13836143c6fbSMasami Hiramatsu static bool __within_kprobe_blacklist(unsigned long addr) 1384d0aaff97SPrasanna S Panchamukhi { 1385376e2424SMasami Hiramatsu struct kprobe_blacklist_entry *ent; 13863d8d996eSSrinivasa Ds 1387be8f2743SMasami Hiramatsu if (arch_within_kprobe_blacklist(addr)) 1388376e2424SMasami Hiramatsu return true; 13893d8d996eSSrinivasa Ds /* 1390223a76b2SMasami Hiramatsu * If 'kprobe_blacklist' is defined, check the address and 1391223a76b2SMasami Hiramatsu * reject any probe registration in the prohibited area. 13923d8d996eSSrinivasa Ds */ 1393376e2424SMasami Hiramatsu list_for_each_entry(ent, &kprobe_blacklist, list) { 1394376e2424SMasami Hiramatsu if (addr >= ent->start_addr && addr < ent->end_addr) 1395376e2424SMasami Hiramatsu return true; 13963d8d996eSSrinivasa Ds } 13976143c6fbSMasami Hiramatsu return false; 13986143c6fbSMasami Hiramatsu } 1399376e2424SMasami Hiramatsu 14006143c6fbSMasami Hiramatsu bool within_kprobe_blacklist(unsigned long addr) 14016143c6fbSMasami Hiramatsu { 14026143c6fbSMasami Hiramatsu char symname[KSYM_NAME_LEN], *p; 14036143c6fbSMasami Hiramatsu 14046143c6fbSMasami Hiramatsu if (__within_kprobe_blacklist(addr)) 14056143c6fbSMasami Hiramatsu return true; 14066143c6fbSMasami Hiramatsu 14076143c6fbSMasami Hiramatsu /* Check if the address is on a suffixed-symbol */ 14086143c6fbSMasami Hiramatsu if (!lookup_symbol_name(addr, symname)) { 14096143c6fbSMasami Hiramatsu p = strchr(symname, '.'); 14106143c6fbSMasami Hiramatsu if (!p) 14116143c6fbSMasami Hiramatsu return false; 14126143c6fbSMasami Hiramatsu *p = '\0'; 14136143c6fbSMasami Hiramatsu addr = (unsigned long)kprobe_lookup_name(symname, 0); 14146143c6fbSMasami Hiramatsu if (addr) 14156143c6fbSMasami Hiramatsu return __within_kprobe_blacklist(addr); 14166143c6fbSMasami Hiramatsu } 1417376e2424SMasami Hiramatsu return false; 1418d0aaff97SPrasanna S Panchamukhi } 1419d0aaff97SPrasanna S Panchamukhi 1420b2a5cd69SMasami Hiramatsu /* 1421cc66bb91SPeter Zijlstra * arch_adjust_kprobe_addr - adjust the address 1422cc66bb91SPeter Zijlstra * @addr: symbol base address 1423cc66bb91SPeter Zijlstra * @offset: offset within the symbol 1424cc66bb91SPeter Zijlstra * @on_func_entry: was this @addr+@offset on the function entry 1425cc66bb91SPeter Zijlstra * 1426cc66bb91SPeter Zijlstra * Typically returns @addr + @offset, except for special cases where the 1427cc66bb91SPeter Zijlstra * function might be prefixed by a CFI landing pad, in that case any offset 1428cc66bb91SPeter Zijlstra * inside the landing pad is mapped to the first 'real' instruction of the 1429cc66bb91SPeter Zijlstra * symbol. 1430cc66bb91SPeter Zijlstra * 1431cc66bb91SPeter Zijlstra * Specifically, for things like IBT/BTI, skip the resp. ENDBR/BTI.C 1432cc66bb91SPeter Zijlstra * instruction at +0. 1433cc66bb91SPeter Zijlstra */ 1434cc66bb91SPeter Zijlstra kprobe_opcode_t *__weak arch_adjust_kprobe_addr(unsigned long addr, 1435cc66bb91SPeter Zijlstra unsigned long offset, 1436cc66bb91SPeter Zijlstra bool *on_func_entry) 1437cc66bb91SPeter Zijlstra { 1438cc66bb91SPeter Zijlstra *on_func_entry = !offset; 1439cc66bb91SPeter Zijlstra return (kprobe_opcode_t *)(addr + offset); 1440cc66bb91SPeter Zijlstra } 1441cc66bb91SPeter Zijlstra 1442cc66bb91SPeter Zijlstra /* 1443223a76b2SMasami Hiramatsu * If 'symbol_name' is specified, look it up and add the 'offset' 1444b2a5cd69SMasami Hiramatsu * to it. This way, we can specify a relative address to a symbol. 1445bc81d48dSMasami Hiramatsu * This returns encoded errors if it fails to look up symbol or invalid 1446bc81d48dSMasami Hiramatsu * combination of parameters. 1447b2a5cd69SMasami Hiramatsu */ 1448cc66bb91SPeter Zijlstra static kprobe_opcode_t * 1449cc66bb91SPeter Zijlstra _kprobe_addr(kprobe_opcode_t *addr, const char *symbol_name, 1450cc66bb91SPeter Zijlstra unsigned long offset, bool *on_func_entry) 1451b2a5cd69SMasami Hiramatsu { 14521d585e70SNaveen N. Rao if ((symbol_name && addr) || (!symbol_name && !addr)) 1453bc81d48dSMasami Hiramatsu goto invalid; 1454bc81d48dSMasami Hiramatsu 14551d585e70SNaveen N. Rao if (symbol_name) { 1456cc66bb91SPeter Zijlstra /* 1457cc66bb91SPeter Zijlstra * Input: @sym + @offset 1458cc66bb91SPeter Zijlstra * Output: @addr + @offset 1459cc66bb91SPeter Zijlstra * 1460cc66bb91SPeter Zijlstra * NOTE: kprobe_lookup_name() does *NOT* fold the offset 1461cc66bb91SPeter Zijlstra * argument into it's output! 1462cc66bb91SPeter Zijlstra */ 14637246f600SLinus Torvalds addr = kprobe_lookup_name(symbol_name, offset); 1464bc81d48dSMasami Hiramatsu if (!addr) 1465bc81d48dSMasami Hiramatsu return ERR_PTR(-ENOENT); 1466b2a5cd69SMasami Hiramatsu } 1467b2a5cd69SMasami Hiramatsu 1468cc66bb91SPeter Zijlstra /* 1469cc66bb91SPeter Zijlstra * So here we have @addr + @offset, displace it into a new 1470cc66bb91SPeter Zijlstra * @addr' + @offset' where @addr' is the symbol start address. 1471cc66bb91SPeter Zijlstra */ 1472cc66bb91SPeter Zijlstra addr = (void *)addr + offset; 1473cc66bb91SPeter Zijlstra if (!kallsyms_lookup_size_offset((unsigned long)addr, NULL, &offset)) 1474cc66bb91SPeter Zijlstra return ERR_PTR(-ENOENT); 1475cc66bb91SPeter Zijlstra addr = (void *)addr - offset; 1476cc66bb91SPeter Zijlstra 1477cc66bb91SPeter Zijlstra /* 1478cc66bb91SPeter Zijlstra * Then ask the architecture to re-combine them, taking care of 1479cc66bb91SPeter Zijlstra * magical function entry details while telling us if this was indeed 1480cc66bb91SPeter Zijlstra * at the start of the function. 1481cc66bb91SPeter Zijlstra */ 1482cc66bb91SPeter Zijlstra addr = arch_adjust_kprobe_addr((unsigned long)addr, offset, on_func_entry); 1483bc81d48dSMasami Hiramatsu if (addr) 1484bc81d48dSMasami Hiramatsu return addr; 1485bc81d48dSMasami Hiramatsu 1486bc81d48dSMasami Hiramatsu invalid: 1487bc81d48dSMasami Hiramatsu return ERR_PTR(-EINVAL); 1488b2a5cd69SMasami Hiramatsu } 1489b2a5cd69SMasami Hiramatsu 14901d585e70SNaveen N. Rao static kprobe_opcode_t *kprobe_addr(struct kprobe *p) 14911d585e70SNaveen N. Rao { 1492cc66bb91SPeter Zijlstra bool on_func_entry; 1493cc66bb91SPeter Zijlstra return _kprobe_addr(p->addr, p->symbol_name, p->offset, &on_func_entry); 14941d585e70SNaveen N. Rao } 14951d585e70SNaveen N. Rao 1496223a76b2SMasami Hiramatsu /* 1497223a76b2SMasami Hiramatsu * Check the 'p' is valid and return the aggregator kprobe 1498223a76b2SMasami Hiramatsu * at the same address. 1499223a76b2SMasami Hiramatsu */ 150055479f64SMasami Hiramatsu static struct kprobe *__get_valid_kprobe(struct kprobe *p) 15011f0ab409SAnanth N Mavinakayanahalli { 15026d8e40a8SMasami Hiramatsu struct kprobe *ap, *list_p; 15031f0ab409SAnanth N Mavinakayanahalli 15047e6a71d8SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 15057e6a71d8SMasami Hiramatsu 15066d8e40a8SMasami Hiramatsu ap = get_kprobe(p->addr); 15076d8e40a8SMasami Hiramatsu if (unlikely(!ap)) 15081f0ab409SAnanth N Mavinakayanahalli return NULL; 15091f0ab409SAnanth N Mavinakayanahalli 15106d8e40a8SMasami Hiramatsu if (p != ap) { 15117e6a71d8SMasami Hiramatsu list_for_each_entry(list_p, &ap->list, list) 15121f0ab409SAnanth N Mavinakayanahalli if (list_p == p) 15131f0ab409SAnanth N Mavinakayanahalli /* kprobe p is a valid probe */ 15141f0ab409SAnanth N Mavinakayanahalli goto valid; 15151f0ab409SAnanth N Mavinakayanahalli return NULL; 15161f0ab409SAnanth N Mavinakayanahalli } 15171f0ab409SAnanth N Mavinakayanahalli valid: 15186d8e40a8SMasami Hiramatsu return ap; 15191f0ab409SAnanth N Mavinakayanahalli } 15201f0ab409SAnanth N Mavinakayanahalli 152133b1d146SMasami Hiramatsu /* 152233b1d146SMasami Hiramatsu * Warn and return error if the kprobe is being re-registered since 152333b1d146SMasami Hiramatsu * there must be a software bug. 152433b1d146SMasami Hiramatsu */ 152533b1d146SMasami Hiramatsu static inline int warn_kprobe_rereg(struct kprobe *p) 15261f0ab409SAnanth N Mavinakayanahalli { 15271f0ab409SAnanth N Mavinakayanahalli int ret = 0; 15281f0ab409SAnanth N Mavinakayanahalli 15291f0ab409SAnanth N Mavinakayanahalli mutex_lock(&kprobe_mutex); 153033b1d146SMasami Hiramatsu if (WARN_ON_ONCE(__get_valid_kprobe(p))) 15311f0ab409SAnanth N Mavinakayanahalli ret = -EINVAL; 15321f0ab409SAnanth N Mavinakayanahalli mutex_unlock(&kprobe_mutex); 15336d8e40a8SMasami Hiramatsu 15341f0ab409SAnanth N Mavinakayanahalli return ret; 15351f0ab409SAnanth N Mavinakayanahalli } 15361f0ab409SAnanth N Mavinakayanahalli 15374402deaeSPunit Agrawal static int check_ftrace_location(struct kprobe *p) 15381da177e4SLinus Torvalds { 1539aebfd125SPeter Zijlstra unsigned long addr = (unsigned long)p->addr; 1540ae6aa16fSMasami Hiramatsu 1541aebfd125SPeter Zijlstra if (ftrace_location(addr) == addr) { 1542e7dbfe34SMasami Hiramatsu #ifdef CONFIG_KPROBES_ON_FTRACE 1543ae6aa16fSMasami Hiramatsu p->flags |= KPROBE_FLAG_FTRACE; 1544e7dbfe34SMasami Hiramatsu #else /* !CONFIG_KPROBES_ON_FTRACE */ 1545ae6aa16fSMasami Hiramatsu return -EINVAL; 1546ae6aa16fSMasami Hiramatsu #endif 1547ae6aa16fSMasami Hiramatsu } 1548f7f242ffSHeiko Carstens return 0; 1549f7f242ffSHeiko Carstens } 1550f7fa6ef0SMasami Hiramatsu 1551f7f242ffSHeiko Carstens static int check_kprobe_address_safe(struct kprobe *p, 1552f7f242ffSHeiko Carstens struct module **probed_mod) 1553f7f242ffSHeiko Carstens { 1554f7f242ffSHeiko Carstens int ret; 1555f7f242ffSHeiko Carstens 15564402deaeSPunit Agrawal ret = check_ftrace_location(p); 1557f7f242ffSHeiko Carstens if (ret) 1558f7f242ffSHeiko Carstens return ret; 1559f7fa6ef0SMasami Hiramatsu jump_label_lock(); 1560f7fa6ef0SMasami Hiramatsu preempt_disable(); 1561f7fa6ef0SMasami Hiramatsu 1562f7fa6ef0SMasami Hiramatsu /* Ensure it is not in reserved area nor out of text */ 156328f6c37aSChen Zhongjin if (!(core_kernel_text((unsigned long) p->addr) || 156428f6c37aSChen Zhongjin is_module_text_address((unsigned long) p->addr)) || 1565376e2424SMasami Hiramatsu within_kprobe_blacklist((unsigned long) p->addr) || 1566e336b402SMasami Hiramatsu jump_label_text_reserved(p->addr, p->addr) || 1567fa68bd09SPeter Zijlstra static_call_text_reserved(p->addr, p->addr) || 1568e336b402SMasami Hiramatsu find_bug((unsigned long)p->addr)) { 1569f7fa6ef0SMasami Hiramatsu ret = -EINVAL; 1570f7fa6ef0SMasami Hiramatsu goto out; 1571f7fa6ef0SMasami Hiramatsu } 1572f7fa6ef0SMasami Hiramatsu 1573223a76b2SMasami Hiramatsu /* Check if 'p' is probing a module. */ 1574f7fa6ef0SMasami Hiramatsu *probed_mod = __module_text_address((unsigned long) p->addr); 1575f7fa6ef0SMasami Hiramatsu if (*probed_mod) { 1576f7fa6ef0SMasami Hiramatsu /* 1577f7fa6ef0SMasami Hiramatsu * We must hold a refcount of the probed module while updating 1578f7fa6ef0SMasami Hiramatsu * its code to prohibit unexpected unloading. 1579f7fa6ef0SMasami Hiramatsu */ 1580f7fa6ef0SMasami Hiramatsu if (unlikely(!try_module_get(*probed_mod))) { 1581f7fa6ef0SMasami Hiramatsu ret = -ENOENT; 1582f7fa6ef0SMasami Hiramatsu goto out; 1583f7fa6ef0SMasami Hiramatsu } 1584f7fa6ef0SMasami Hiramatsu 1585f7fa6ef0SMasami Hiramatsu /* 1586223a76b2SMasami Hiramatsu * If the module freed '.init.text', we couldn't insert 1587f7fa6ef0SMasami Hiramatsu * kprobes in there. 1588f7fa6ef0SMasami Hiramatsu */ 1589f7fa6ef0SMasami Hiramatsu if (within_module_init((unsigned long)p->addr, *probed_mod) && 1590f7fa6ef0SMasami Hiramatsu (*probed_mod)->state != MODULE_STATE_COMING) { 1591f7fa6ef0SMasami Hiramatsu module_put(*probed_mod); 1592f7fa6ef0SMasami Hiramatsu *probed_mod = NULL; 1593f7fa6ef0SMasami Hiramatsu ret = -ENOENT; 1594f7fa6ef0SMasami Hiramatsu } 1595f7fa6ef0SMasami Hiramatsu } 1596f7fa6ef0SMasami Hiramatsu out: 1597f7fa6ef0SMasami Hiramatsu preempt_enable(); 1598f7fa6ef0SMasami Hiramatsu jump_label_unlock(); 1599f7fa6ef0SMasami Hiramatsu 1600f7fa6ef0SMasami Hiramatsu return ret; 1601f7fa6ef0SMasami Hiramatsu } 1602f7fa6ef0SMasami Hiramatsu 160355479f64SMasami Hiramatsu int register_kprobe(struct kprobe *p) 1604f7fa6ef0SMasami Hiramatsu { 1605f7fa6ef0SMasami Hiramatsu int ret; 160664f562c6SAnanth N Mavinakayanahalli struct kprobe *old_p; 1607df019b1dSKeshavamurthy Anil S struct module *probed_mod; 1608b2a5cd69SMasami Hiramatsu kprobe_opcode_t *addr; 1609*bf7a87f1SJiri Olsa bool on_func_entry; 16101da177e4SLinus Torvalds 1611f7fa6ef0SMasami Hiramatsu /* Adjust probe address from symbol */ 1612*bf7a87f1SJiri Olsa addr = _kprobe_addr(p->addr, p->symbol_name, p->offset, &on_func_entry); 1613bc81d48dSMasami Hiramatsu if (IS_ERR(addr)) 1614bc81d48dSMasami Hiramatsu return PTR_ERR(addr); 1615b2a5cd69SMasami Hiramatsu p->addr = addr; 16163a872d89SAnanth N Mavinakayanahalli 161733b1d146SMasami Hiramatsu ret = warn_kprobe_rereg(p); 16181f0ab409SAnanth N Mavinakayanahalli if (ret) 16191f0ab409SAnanth N Mavinakayanahalli return ret; 16201f0ab409SAnanth N Mavinakayanahalli 1621de5bd88dSMasami Hiramatsu /* User can pass only KPROBE_FLAG_DISABLED to register_kprobe */ 1622de5bd88dSMasami Hiramatsu p->flags &= KPROBE_FLAG_DISABLED; 16233516a460SAnanth N Mavinakayanahalli p->nmissed = 0; 16249861668fSMasami Hiramatsu INIT_LIST_HEAD(&p->list); 1625afd66255SMasami Hiramatsu 1626f7fa6ef0SMasami Hiramatsu ret = check_kprobe_address_safe(p, &probed_mod); 1627f7fa6ef0SMasami Hiramatsu if (ret) 1628f7fa6ef0SMasami Hiramatsu return ret; 1629f7fa6ef0SMasami Hiramatsu 1630f7fa6ef0SMasami Hiramatsu mutex_lock(&kprobe_mutex); 1631afd66255SMasami Hiramatsu 1632*bf7a87f1SJiri Olsa if (on_func_entry) 1633*bf7a87f1SJiri Olsa p->flags |= KPROBE_FLAG_ON_FUNC_ENTRY; 1634*bf7a87f1SJiri Olsa 163564f562c6SAnanth N Mavinakayanahalli old_p = get_kprobe(p->addr); 163664f562c6SAnanth N Mavinakayanahalli if (old_p) { 1637223a76b2SMasami 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 1676223a76b2SMasami Hiramatsu /* Check if all probes on the 'ap' are disabled. */ 167729e8077aSMasami Hiramatsu static bool 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 /* 1686223a76b2SMasami Hiramatsu * Since there is an active probe on the list, 1687223a76b2SMasami Hiramatsu * we can't disable this 'ap'. 16886f0f1dd7SMasami Hiramatsu */ 168929e8077aSMasami Hiramatsu return false; 16906f0f1dd7SMasami Hiramatsu 169129e8077aSMasami Hiramatsu return true; 16926f0f1dd7SMasami Hiramatsu } 16936f0f1dd7SMasami Hiramatsu 169455479f64SMasami Hiramatsu static struct kprobe *__disable_kprobe(struct kprobe *p) 16956f0f1dd7SMasami Hiramatsu { 16966f0f1dd7SMasami Hiramatsu struct kprobe *orig_p; 1697297f9233SJessica Yu int ret; 16986f0f1dd7SMasami Hiramatsu 169957d4e317SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 170057d4e317SMasami Hiramatsu 17016f0f1dd7SMasami Hiramatsu /* Get an original kprobe for return */ 17026f0f1dd7SMasami Hiramatsu orig_p = __get_valid_kprobe(p); 17036f0f1dd7SMasami Hiramatsu if (unlikely(orig_p == NULL)) 1704297f9233SJessica Yu return ERR_PTR(-EINVAL); 17056f0f1dd7SMasami Hiramatsu 17066f0f1dd7SMasami Hiramatsu if (!kprobe_disabled(p)) { 17076f0f1dd7SMasami Hiramatsu /* Disable probe if it is a child probe */ 17086f0f1dd7SMasami Hiramatsu if (p != orig_p) 17096f0f1dd7SMasami Hiramatsu p->flags |= KPROBE_FLAG_DISABLED; 17106f0f1dd7SMasami Hiramatsu 17116f0f1dd7SMasami Hiramatsu /* Try to disarm and disable this/parent probe */ 17126f0f1dd7SMasami Hiramatsu if (p == orig_p || aggr_kprobe_disabled(orig_p)) { 171369d54b91SWang Nan /* 17149c80e799SKuniyuki Iwashima * Don't be lazy here. Even if 'kprobes_all_disarmed' 17159c80e799SKuniyuki Iwashima * is false, 'orig_p' might not have been armed yet. 17169c80e799SKuniyuki Iwashima * Note arm_all_kprobes() __tries__ to arm all kprobes 17179c80e799SKuniyuki Iwashima * on the best effort basis. 171869d54b91SWang Nan */ 17199c80e799SKuniyuki Iwashima if (!kprobes_all_disarmed && !kprobe_disabled(orig_p)) { 1720297f9233SJessica Yu ret = disarm_kprobe(orig_p, true); 1721297f9233SJessica Yu if (ret) { 1722297f9233SJessica Yu p->flags &= ~KPROBE_FLAG_DISABLED; 1723297f9233SJessica Yu return ERR_PTR(ret); 1724297f9233SJessica Yu } 1725297f9233SJessica Yu } 17266f0f1dd7SMasami Hiramatsu orig_p->flags |= KPROBE_FLAG_DISABLED; 17276f0f1dd7SMasami Hiramatsu } 17286f0f1dd7SMasami Hiramatsu } 17296f0f1dd7SMasami Hiramatsu 17306f0f1dd7SMasami Hiramatsu return orig_p; 17316f0f1dd7SMasami Hiramatsu } 17326f0f1dd7SMasami Hiramatsu 17339861668fSMasami Hiramatsu /* 17349861668fSMasami Hiramatsu * Unregister a kprobe without a scheduler synchronization. 17359861668fSMasami Hiramatsu */ 173655479f64SMasami Hiramatsu static int __unregister_kprobe_top(struct kprobe *p) 1737df019b1dSKeshavamurthy Anil S { 17386d8e40a8SMasami Hiramatsu struct kprobe *ap, *list_p; 173964f562c6SAnanth N Mavinakayanahalli 17406f0f1dd7SMasami Hiramatsu /* Disable kprobe. This will disarm it if needed. */ 17416f0f1dd7SMasami Hiramatsu ap = __disable_kprobe(p); 1742297f9233SJessica Yu if (IS_ERR(ap)) 1743297f9233SJessica Yu return PTR_ERR(ap); 17449861668fSMasami Hiramatsu 17456f0f1dd7SMasami Hiramatsu if (ap == p) 1746bf8f6e5bSAnanth N Mavinakayanahalli /* 17476f0f1dd7SMasami Hiramatsu * This probe is an independent(and non-optimized) kprobe 17486f0f1dd7SMasami Hiramatsu * (not an aggrprobe). Remove from the hash list. 1749bf8f6e5bSAnanth N Mavinakayanahalli */ 17506f0f1dd7SMasami Hiramatsu goto disarmed; 17516f0f1dd7SMasami Hiramatsu 17526f0f1dd7SMasami Hiramatsu /* Following process expects this probe is an aggrprobe */ 17536f0f1dd7SMasami Hiramatsu WARN_ON(!kprobe_aggrprobe(ap)); 17546f0f1dd7SMasami Hiramatsu 17556274de49SMasami Hiramatsu if (list_is_singular(&ap->list) && kprobe_disarmed(ap)) 17566274de49SMasami Hiramatsu /* 17576274de49SMasami Hiramatsu * !disarmed could be happen if the probe is under delayed 17586274de49SMasami Hiramatsu * unoptimizing. 17596274de49SMasami Hiramatsu */ 17606f0f1dd7SMasami Hiramatsu goto disarmed; 17616f0f1dd7SMasami Hiramatsu else { 17626f0f1dd7SMasami Hiramatsu /* If disabling probe has special handlers, update aggrprobe */ 1763e8386a0cSMasami Hiramatsu if (p->post_handler && !kprobe_gone(p)) { 17647e6a71d8SMasami Hiramatsu list_for_each_entry(list_p, &ap->list, list) { 17659861668fSMasami Hiramatsu if ((list_p != p) && (list_p->post_handler)) 17669861668fSMasami Hiramatsu goto noclean; 17679861668fSMasami Hiramatsu } 17686d8e40a8SMasami Hiramatsu ap->post_handler = NULL; 17699861668fSMasami Hiramatsu } 17709861668fSMasami Hiramatsu noclean: 17716f0f1dd7SMasami Hiramatsu /* 17726f0f1dd7SMasami Hiramatsu * Remove from the aggrprobe: this path will do nothing in 17736f0f1dd7SMasami Hiramatsu * __unregister_kprobe_bottom(). 17746f0f1dd7SMasami Hiramatsu */ 177549a2a1b8SAnil S Keshavamurthy list_del_rcu(&p->list); 17766f0f1dd7SMasami Hiramatsu if (!kprobe_disabled(ap) && !kprobes_all_disarmed) 17776f0f1dd7SMasami Hiramatsu /* 17786f0f1dd7SMasami Hiramatsu * Try to optimize this probe again, because post 17796f0f1dd7SMasami Hiramatsu * handler may have been changed. 17806f0f1dd7SMasami Hiramatsu */ 17816d8e40a8SMasami Hiramatsu optimize_kprobe(ap); 1782afd66255SMasami Hiramatsu } 17836f0f1dd7SMasami Hiramatsu return 0; 17846f0f1dd7SMasami Hiramatsu 17856f0f1dd7SMasami Hiramatsu disarmed: 17866f0f1dd7SMasami Hiramatsu hlist_del_rcu(&ap->hlist); 17879861668fSMasami Hiramatsu return 0; 178849a2a1b8SAnil S Keshavamurthy } 178949a2a1b8SAnil S Keshavamurthy 179055479f64SMasami Hiramatsu static void __unregister_kprobe_bottom(struct kprobe *p) 17919861668fSMasami Hiramatsu { 17926d8e40a8SMasami Hiramatsu struct kprobe *ap; 17933516a460SAnanth N Mavinakayanahalli 1794e8386a0cSMasami Hiramatsu if (list_empty(&p->list)) 17956274de49SMasami Hiramatsu /* This is an independent kprobe */ 1796e8386a0cSMasami Hiramatsu arch_remove_kprobe(p); 1797e8386a0cSMasami Hiramatsu else if (list_is_singular(&p->list)) { 17986274de49SMasami Hiramatsu /* This is the last child of an aggrprobe */ 17996d8e40a8SMasami Hiramatsu ap = list_entry(p->list.next, struct kprobe, list); 18009861668fSMasami Hiramatsu list_del(&p->list); 18016d8e40a8SMasami Hiramatsu free_aggr_kprobe(ap); 180249a2a1b8SAnil S Keshavamurthy } 18036274de49SMasami Hiramatsu /* Otherwise, do nothing. */ 18049861668fSMasami Hiramatsu } 18059861668fSMasami Hiramatsu 180655479f64SMasami Hiramatsu int register_kprobes(struct kprobe **kps, int num) 18079861668fSMasami Hiramatsu { 18089861668fSMasami Hiramatsu int i, ret = 0; 18099861668fSMasami Hiramatsu 18109861668fSMasami Hiramatsu if (num <= 0) 18119861668fSMasami Hiramatsu return -EINVAL; 18129861668fSMasami Hiramatsu for (i = 0; i < num; i++) { 181349ad2fd7SMasami Hiramatsu ret = register_kprobe(kps[i]); 181467dddaadSMasami Hiramatsu if (ret < 0) { 181567dddaadSMasami Hiramatsu if (i > 0) 18169861668fSMasami Hiramatsu unregister_kprobes(kps, i); 181736721656Smao, bibo break; 181836721656Smao, bibo } 181936721656Smao, bibo } 18209861668fSMasami Hiramatsu return ret; 182136721656Smao, bibo } 182299081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kprobes); 18239861668fSMasami Hiramatsu 182455479f64SMasami Hiramatsu void unregister_kprobe(struct kprobe *p) 18259861668fSMasami Hiramatsu { 18269861668fSMasami Hiramatsu unregister_kprobes(&p, 1); 18279861668fSMasami Hiramatsu } 182899081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kprobe); 18299861668fSMasami Hiramatsu 183055479f64SMasami Hiramatsu void unregister_kprobes(struct kprobe **kps, int num) 18319861668fSMasami Hiramatsu { 18329861668fSMasami Hiramatsu int i; 18339861668fSMasami Hiramatsu 18349861668fSMasami Hiramatsu if (num <= 0) 18359861668fSMasami Hiramatsu return; 18369861668fSMasami Hiramatsu mutex_lock(&kprobe_mutex); 18379861668fSMasami Hiramatsu for (i = 0; i < num; i++) 18389861668fSMasami Hiramatsu if (__unregister_kprobe_top(kps[i]) < 0) 18399861668fSMasami Hiramatsu kps[i]->addr = NULL; 184036721656Smao, bibo mutex_unlock(&kprobe_mutex); 18419861668fSMasami Hiramatsu 1842ae8b7ce7SPaul E. McKenney synchronize_rcu(); 18439861668fSMasami Hiramatsu for (i = 0; i < num; i++) 18449861668fSMasami Hiramatsu if (kps[i]->addr) 18459861668fSMasami Hiramatsu __unregister_kprobe_bottom(kps[i]); 18461da177e4SLinus Torvalds } 184799081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kprobes); 18481da177e4SLinus Torvalds 18495f6bee34SNaveen N. Rao int __weak kprobe_exceptions_notify(struct notifier_block *self, 1850fc62d020SNaveen N. Rao unsigned long val, void *data) 1851fc62d020SNaveen N. Rao { 1852fc62d020SNaveen N. Rao return NOTIFY_DONE; 1853fc62d020SNaveen N. Rao } 18545f6bee34SNaveen N. Rao NOKPROBE_SYMBOL(kprobe_exceptions_notify); 1855fc62d020SNaveen N. Rao 18561da177e4SLinus Torvalds static struct notifier_block kprobe_exceptions_nb = { 18571da177e4SLinus Torvalds .notifier_call = kprobe_exceptions_notify, 18583d5631e0SAnil S Keshavamurthy .priority = 0x7fffffff /* we need to be notified first */ 18593d5631e0SAnil S Keshavamurthy }; 18603d5631e0SAnil S Keshavamurthy 18619edddaa2SAnanth N Mavinakayanahalli #ifdef CONFIG_KRETPROBES 186266ada2ccSMasami Hiramatsu 186373f9b911SMasami Hiramatsu #if !defined(CONFIG_KRETPROBE_ON_RETHOOK) 186443994049SMasami Hiramatsu static void free_rp_inst_rcu(struct rcu_head *head) 186543994049SMasami Hiramatsu { 186643994049SMasami Hiramatsu struct kretprobe_instance *ri = container_of(head, struct kretprobe_instance, rcu); 186743994049SMasami Hiramatsu 186843994049SMasami Hiramatsu if (refcount_dec_and_test(&ri->rph->ref)) 186943994049SMasami Hiramatsu kfree(ri->rph); 187043994049SMasami Hiramatsu kfree(ri); 187143994049SMasami Hiramatsu } 187243994049SMasami Hiramatsu NOKPROBE_SYMBOL(free_rp_inst_rcu); 187343994049SMasami Hiramatsu 187443994049SMasami Hiramatsu static void recycle_rp_inst(struct kretprobe_instance *ri) 187543994049SMasami Hiramatsu { 187643994049SMasami Hiramatsu struct kretprobe *rp = get_kretprobe(ri); 187743994049SMasami Hiramatsu 187843994049SMasami Hiramatsu if (likely(rp)) 187943994049SMasami Hiramatsu freelist_add(&ri->freelist, &rp->freelist); 188043994049SMasami Hiramatsu else 188143994049SMasami Hiramatsu call_rcu(&ri->rcu, free_rp_inst_rcu); 188243994049SMasami Hiramatsu } 188343994049SMasami Hiramatsu NOKPROBE_SYMBOL(recycle_rp_inst); 188443994049SMasami Hiramatsu 188543994049SMasami Hiramatsu /* 188643994049SMasami Hiramatsu * This function is called from delayed_put_task_struct() when a task is 188743994049SMasami Hiramatsu * dead and cleaned up to recycle any kretprobe instances associated with 188843994049SMasami Hiramatsu * this task. These left over instances represent probed functions that 188943994049SMasami Hiramatsu * have been called but will never return. 189043994049SMasami Hiramatsu */ 189143994049SMasami Hiramatsu void kprobe_flush_task(struct task_struct *tk) 189243994049SMasami Hiramatsu { 189343994049SMasami Hiramatsu struct kretprobe_instance *ri; 189443994049SMasami Hiramatsu struct llist_node *node; 189543994049SMasami Hiramatsu 189643994049SMasami Hiramatsu /* Early boot, not yet initialized. */ 189743994049SMasami Hiramatsu if (unlikely(!kprobes_initialized)) 189843994049SMasami Hiramatsu return; 189943994049SMasami Hiramatsu 190043994049SMasami Hiramatsu kprobe_busy_begin(); 190143994049SMasami Hiramatsu 190243994049SMasami Hiramatsu node = __llist_del_all(&tk->kretprobe_instances); 190343994049SMasami Hiramatsu while (node) { 190443994049SMasami Hiramatsu ri = container_of(node, struct kretprobe_instance, llist); 190543994049SMasami Hiramatsu node = node->next; 190643994049SMasami Hiramatsu 190743994049SMasami Hiramatsu recycle_rp_inst(ri); 190843994049SMasami Hiramatsu } 190943994049SMasami Hiramatsu 191043994049SMasami Hiramatsu kprobe_busy_end(); 191143994049SMasami Hiramatsu } 191243994049SMasami Hiramatsu NOKPROBE_SYMBOL(kprobe_flush_task); 191343994049SMasami Hiramatsu 191443994049SMasami Hiramatsu static inline void free_rp_inst(struct kretprobe *rp) 191543994049SMasami Hiramatsu { 191643994049SMasami Hiramatsu struct kretprobe_instance *ri; 191743994049SMasami Hiramatsu struct freelist_node *node; 191843994049SMasami Hiramatsu int count = 0; 191943994049SMasami Hiramatsu 192043994049SMasami Hiramatsu node = rp->freelist.head; 192143994049SMasami Hiramatsu while (node) { 192243994049SMasami Hiramatsu ri = container_of(node, struct kretprobe_instance, freelist); 192343994049SMasami Hiramatsu node = node->next; 192443994049SMasami Hiramatsu 192543994049SMasami Hiramatsu kfree(ri); 192643994049SMasami Hiramatsu count++; 192743994049SMasami Hiramatsu } 192843994049SMasami Hiramatsu 192943994049SMasami Hiramatsu if (refcount_sub_and_test(count, &rp->rph->ref)) { 193043994049SMasami Hiramatsu kfree(rp->rph); 193143994049SMasami Hiramatsu rp->rph = NULL; 193243994049SMasami Hiramatsu } 193343994049SMasami Hiramatsu } 193443994049SMasami Hiramatsu 193503bac0dfSMasami Hiramatsu /* This assumes the 'tsk' is the current task or the is not running. */ 193603bac0dfSMasami Hiramatsu static kprobe_opcode_t *__kretprobe_find_ret_addr(struct task_struct *tsk, 193703bac0dfSMasami Hiramatsu struct llist_node **cur) 193803bac0dfSMasami Hiramatsu { 193903bac0dfSMasami Hiramatsu struct kretprobe_instance *ri = NULL; 194003bac0dfSMasami Hiramatsu struct llist_node *node = *cur; 194103bac0dfSMasami Hiramatsu 194203bac0dfSMasami Hiramatsu if (!node) 194303bac0dfSMasami Hiramatsu node = tsk->kretprobe_instances.first; 194403bac0dfSMasami Hiramatsu else 194503bac0dfSMasami Hiramatsu node = node->next; 194603bac0dfSMasami Hiramatsu 194703bac0dfSMasami Hiramatsu while (node) { 194803bac0dfSMasami Hiramatsu ri = container_of(node, struct kretprobe_instance, llist); 194903bac0dfSMasami Hiramatsu if (ri->ret_addr != kretprobe_trampoline_addr()) { 195003bac0dfSMasami Hiramatsu *cur = node; 195103bac0dfSMasami Hiramatsu return ri->ret_addr; 195203bac0dfSMasami Hiramatsu } 195303bac0dfSMasami Hiramatsu node = node->next; 195403bac0dfSMasami Hiramatsu } 195503bac0dfSMasami Hiramatsu return NULL; 195603bac0dfSMasami Hiramatsu } 195703bac0dfSMasami Hiramatsu NOKPROBE_SYMBOL(__kretprobe_find_ret_addr); 195803bac0dfSMasami Hiramatsu 195903bac0dfSMasami Hiramatsu /** 196003bac0dfSMasami Hiramatsu * kretprobe_find_ret_addr -- Find correct return address modified by kretprobe 196103bac0dfSMasami Hiramatsu * @tsk: Target task 196203bac0dfSMasami Hiramatsu * @fp: A frame pointer 196303bac0dfSMasami Hiramatsu * @cur: a storage of the loop cursor llist_node pointer for next call 196403bac0dfSMasami Hiramatsu * 196503bac0dfSMasami Hiramatsu * Find the correct return address modified by a kretprobe on @tsk in unsigned 196603bac0dfSMasami Hiramatsu * long type. If it finds the return address, this returns that address value, 196703bac0dfSMasami Hiramatsu * or this returns 0. 196803bac0dfSMasami Hiramatsu * The @tsk must be 'current' or a task which is not running. @fp is a hint 196903bac0dfSMasami Hiramatsu * to get the currect return address - which is compared with the 197003bac0dfSMasami Hiramatsu * kretprobe_instance::fp field. The @cur is a loop cursor for searching the 197103bac0dfSMasami Hiramatsu * kretprobe return addresses on the @tsk. The '*@cur' should be NULL at the 197203bac0dfSMasami Hiramatsu * first call, but '@cur' itself must NOT NULL. 197303bac0dfSMasami Hiramatsu */ 197403bac0dfSMasami Hiramatsu unsigned long kretprobe_find_ret_addr(struct task_struct *tsk, void *fp, 197503bac0dfSMasami Hiramatsu struct llist_node **cur) 197603bac0dfSMasami Hiramatsu { 197703bac0dfSMasami Hiramatsu struct kretprobe_instance *ri = NULL; 197803bac0dfSMasami Hiramatsu kprobe_opcode_t *ret; 197903bac0dfSMasami Hiramatsu 198003bac0dfSMasami Hiramatsu if (WARN_ON_ONCE(!cur)) 198103bac0dfSMasami Hiramatsu return 0; 198203bac0dfSMasami Hiramatsu 198303bac0dfSMasami Hiramatsu do { 198403bac0dfSMasami Hiramatsu ret = __kretprobe_find_ret_addr(tsk, cur); 198503bac0dfSMasami Hiramatsu if (!ret) 198603bac0dfSMasami Hiramatsu break; 198703bac0dfSMasami Hiramatsu ri = container_of(*cur, struct kretprobe_instance, llist); 198803bac0dfSMasami Hiramatsu } while (ri->fp != fp); 198903bac0dfSMasami Hiramatsu 199003bac0dfSMasami Hiramatsu return (unsigned long)ret; 199103bac0dfSMasami Hiramatsu } 199203bac0dfSMasami Hiramatsu NOKPROBE_SYMBOL(kretprobe_find_ret_addr); 199303bac0dfSMasami Hiramatsu 1994bf094cffSMasami Hiramatsu void __weak arch_kretprobe_fixup_return(struct pt_regs *regs, 1995bf094cffSMasami Hiramatsu kprobe_opcode_t *correct_ret_addr) 1996bf094cffSMasami Hiramatsu { 1997bf094cffSMasami Hiramatsu /* 1998bf094cffSMasami Hiramatsu * Do nothing by default. Please fill this to update the fake return 1999bf094cffSMasami Hiramatsu * address on the stack with the correct one on each arch if possible. 2000bf094cffSMasami Hiramatsu */ 2001bf094cffSMasami Hiramatsu } 2002bf094cffSMasami Hiramatsu 200366ada2ccSMasami Hiramatsu unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, 200466ada2ccSMasami Hiramatsu void *frame_pointer) 200566ada2ccSMasami Hiramatsu { 200666ada2ccSMasami Hiramatsu kprobe_opcode_t *correct_ret_addr = NULL; 2007d741bf41SPeter Zijlstra struct kretprobe_instance *ri = NULL; 200803bac0dfSMasami Hiramatsu struct llist_node *first, *node = NULL; 2009d741bf41SPeter Zijlstra struct kretprobe *rp; 201066ada2ccSMasami Hiramatsu 201103bac0dfSMasami Hiramatsu /* Find correct address and all nodes for this frame. */ 201203bac0dfSMasami Hiramatsu correct_ret_addr = __kretprobe_find_ret_addr(current, &node); 201303bac0dfSMasami Hiramatsu if (!correct_ret_addr) { 20149c89bb8eSMasami Hiramatsu pr_err("kretprobe: Return address not found, not execute handler. Maybe there is a bug in the kernel.\n"); 2015d741bf41SPeter Zijlstra BUG_ON(1); 201603bac0dfSMasami Hiramatsu } 201766ada2ccSMasami Hiramatsu 2018df91c5bcSMasami Hiramatsu /* 2019df91c5bcSMasami Hiramatsu * Set the return address as the instruction pointer, because if the 2020df91c5bcSMasami Hiramatsu * user handler calls stack_trace_save_regs() with this 'regs', 2021df91c5bcSMasami Hiramatsu * the stack trace will start from the instruction pointer. 2022df91c5bcSMasami Hiramatsu */ 2023df91c5bcSMasami Hiramatsu instruction_pointer_set(regs, (unsigned long)correct_ret_addr); 202466ada2ccSMasami Hiramatsu 202503bac0dfSMasami Hiramatsu /* Run the user handler of the nodes. */ 202603bac0dfSMasami Hiramatsu first = current->kretprobe_instances.first; 2027d741bf41SPeter Zijlstra while (first) { 2028d741bf41SPeter Zijlstra ri = container_of(first, struct kretprobe_instance, llist); 202903bac0dfSMasami Hiramatsu 203003bac0dfSMasami Hiramatsu if (WARN_ON_ONCE(ri->fp != frame_pointer)) 203103bac0dfSMasami Hiramatsu break; 2032d741bf41SPeter Zijlstra 2033d741bf41SPeter Zijlstra rp = get_kretprobe(ri); 2034d741bf41SPeter Zijlstra if (rp && rp->handler) { 203566ada2ccSMasami Hiramatsu struct kprobe *prev = kprobe_running(); 203666ada2ccSMasami Hiramatsu 2037d741bf41SPeter Zijlstra __this_cpu_write(current_kprobe, &rp->kp); 203866ada2ccSMasami Hiramatsu ri->ret_addr = correct_ret_addr; 2039d741bf41SPeter Zijlstra rp->handler(ri, regs); 204066ada2ccSMasami Hiramatsu __this_cpu_write(current_kprobe, prev); 204166ada2ccSMasami Hiramatsu } 204203bac0dfSMasami Hiramatsu if (first == node) 204303bac0dfSMasami Hiramatsu break; 204403bac0dfSMasami Hiramatsu 204503bac0dfSMasami Hiramatsu first = first->next; 204603bac0dfSMasami Hiramatsu } 204703bac0dfSMasami Hiramatsu 2048bf094cffSMasami Hiramatsu arch_kretprobe_fixup_return(regs, correct_ret_addr); 2049bf094cffSMasami Hiramatsu 205003bac0dfSMasami Hiramatsu /* Unlink all nodes for this frame. */ 205103bac0dfSMasami Hiramatsu first = current->kretprobe_instances.first; 205203bac0dfSMasami Hiramatsu current->kretprobe_instances.first = node->next; 205303bac0dfSMasami Hiramatsu node->next = NULL; 205403bac0dfSMasami Hiramatsu 205503bac0dfSMasami Hiramatsu /* Recycle free instances. */ 205603bac0dfSMasami Hiramatsu while (first) { 205703bac0dfSMasami Hiramatsu ri = container_of(first, struct kretprobe_instance, llist); 205803bac0dfSMasami Hiramatsu first = first->next; 205966ada2ccSMasami Hiramatsu 2060b3388178SMasami Hiramatsu recycle_rp_inst(ri); 206166ada2ccSMasami Hiramatsu } 206266ada2ccSMasami Hiramatsu 206366ada2ccSMasami Hiramatsu return (unsigned long)correct_ret_addr; 206466ada2ccSMasami Hiramatsu } 206566ada2ccSMasami Hiramatsu NOKPROBE_SYMBOL(__kretprobe_trampoline_handler) 206666ada2ccSMasami Hiramatsu 2067e65cefe8SAdrian Bunk /* 2068e65cefe8SAdrian Bunk * This kprobe pre_handler is registered with every kretprobe. When probe 2069e65cefe8SAdrian Bunk * hits it will set up the return probe. 2070e65cefe8SAdrian Bunk */ 2071820aede0SMasami Hiramatsu static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) 2072e65cefe8SAdrian Bunk { 2073e65cefe8SAdrian Bunk struct kretprobe *rp = container_of(p, struct kretprobe, kp); 20744c4308cbSChristoph Hellwig struct kretprobe_instance *ri; 20756e426e0fSPeter Zijlstra struct freelist_node *fn; 20764c4308cbSChristoph Hellwig 20776e426e0fSPeter Zijlstra fn = freelist_try_get(&rp->freelist); 20786e426e0fSPeter Zijlstra if (!fn) { 20796e426e0fSPeter Zijlstra rp->nmissed++; 20806e426e0fSPeter Zijlstra return 0; 20816e426e0fSPeter Zijlstra } 20826e426e0fSPeter Zijlstra 20836e426e0fSPeter Zijlstra ri = container_of(fn, struct kretprobe_instance, freelist); 2084ef53d9c5SSrinivasa D S 208555ca6140SJiang Liu if (rp->entry_handler && rp->entry_handler(ri, regs)) { 20866e426e0fSPeter Zijlstra freelist_add(&ri->freelist, &rp->freelist); 2087f47cd9b5SAbhishek Sagar return 0; 208855ca6140SJiang Liu } 2089f47cd9b5SAbhishek Sagar 20904c4308cbSChristoph Hellwig arch_prepare_kretprobe(ri, regs); 20914c4308cbSChristoph Hellwig 2092d741bf41SPeter Zijlstra __llist_add(&ri->llist, ¤t->kretprobe_instances); 2093d741bf41SPeter Zijlstra 2094e65cefe8SAdrian Bunk return 0; 2095e65cefe8SAdrian Bunk } 2096820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(pre_handler_kretprobe); 209773f9b911SMasami Hiramatsu #else /* CONFIG_KRETPROBE_ON_RETHOOK */ 209873f9b911SMasami Hiramatsu /* 209973f9b911SMasami Hiramatsu * This kprobe pre_handler is registered with every kretprobe. When probe 210073f9b911SMasami Hiramatsu * hits it will set up the return probe. 210173f9b911SMasami Hiramatsu */ 210273f9b911SMasami Hiramatsu static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) 210373f9b911SMasami Hiramatsu { 210473f9b911SMasami Hiramatsu struct kretprobe *rp = container_of(p, struct kretprobe, kp); 210573f9b911SMasami Hiramatsu struct kretprobe_instance *ri; 210673f9b911SMasami Hiramatsu struct rethook_node *rhn; 210773f9b911SMasami Hiramatsu 210873f9b911SMasami Hiramatsu rhn = rethook_try_get(rp->rh); 210973f9b911SMasami Hiramatsu if (!rhn) { 211073f9b911SMasami Hiramatsu rp->nmissed++; 211173f9b911SMasami Hiramatsu return 0; 211273f9b911SMasami Hiramatsu } 211373f9b911SMasami Hiramatsu 211473f9b911SMasami Hiramatsu ri = container_of(rhn, struct kretprobe_instance, node); 211573f9b911SMasami Hiramatsu 211673f9b911SMasami Hiramatsu if (rp->entry_handler && rp->entry_handler(ri, regs)) 211773f9b911SMasami Hiramatsu rethook_recycle(rhn); 211873f9b911SMasami Hiramatsu else 211973f9b911SMasami Hiramatsu rethook_hook(rhn, regs, kprobe_ftrace(p)); 212073f9b911SMasami Hiramatsu 212173f9b911SMasami Hiramatsu return 0; 212273f9b911SMasami Hiramatsu } 212373f9b911SMasami Hiramatsu NOKPROBE_SYMBOL(pre_handler_kretprobe); 212473f9b911SMasami Hiramatsu 212573f9b911SMasami Hiramatsu static void kretprobe_rethook_handler(struct rethook_node *rh, void *data, 212673f9b911SMasami Hiramatsu struct pt_regs *regs) 212773f9b911SMasami Hiramatsu { 212873f9b911SMasami Hiramatsu struct kretprobe *rp = (struct kretprobe *)data; 212973f9b911SMasami Hiramatsu struct kretprobe_instance *ri; 213073f9b911SMasami Hiramatsu struct kprobe_ctlblk *kcb; 213173f9b911SMasami Hiramatsu 213273f9b911SMasami Hiramatsu /* The data must NOT be null. This means rethook data structure is broken. */ 21331d661ed5SAdam Zabrocki if (WARN_ON_ONCE(!data) || !rp->handler) 213473f9b911SMasami Hiramatsu return; 213573f9b911SMasami Hiramatsu 213673f9b911SMasami Hiramatsu __this_cpu_write(current_kprobe, &rp->kp); 213773f9b911SMasami Hiramatsu kcb = get_kprobe_ctlblk(); 213873f9b911SMasami Hiramatsu kcb->kprobe_status = KPROBE_HIT_ACTIVE; 213973f9b911SMasami Hiramatsu 214073f9b911SMasami Hiramatsu ri = container_of(rh, struct kretprobe_instance, node); 214173f9b911SMasami Hiramatsu rp->handler(ri, regs); 214273f9b911SMasami Hiramatsu 214373f9b911SMasami Hiramatsu __this_cpu_write(current_kprobe, NULL); 214473f9b911SMasami Hiramatsu } 214573f9b911SMasami Hiramatsu NOKPROBE_SYMBOL(kretprobe_rethook_handler); 214673f9b911SMasami Hiramatsu 214773f9b911SMasami Hiramatsu #endif /* !CONFIG_KRETPROBE_ON_RETHOOK */ 2148e65cefe8SAdrian Bunk 214997c753e6SMasami Hiramatsu /** 215097c753e6SMasami Hiramatsu * kprobe_on_func_entry() -- check whether given address is function entry 215197c753e6SMasami Hiramatsu * @addr: Target address 215297c753e6SMasami Hiramatsu * @sym: Target symbol name 215397c753e6SMasami Hiramatsu * @offset: The offset from the symbol or the address 215497c753e6SMasami Hiramatsu * 215597c753e6SMasami Hiramatsu * This checks whether the given @addr+@offset or @sym+@offset is on the 215697c753e6SMasami Hiramatsu * function entry address or not. 215797c753e6SMasami Hiramatsu * This returns 0 if it is the function entry, or -EINVAL if it is not. 215897c753e6SMasami Hiramatsu * And also it returns -ENOENT if it fails the symbol or address lookup. 215997c753e6SMasami Hiramatsu * Caller must pass @addr or @sym (either one must be NULL), or this 216097c753e6SMasami Hiramatsu * returns -EINVAL. 216197c753e6SMasami Hiramatsu */ 216297c753e6SMasami Hiramatsu int kprobe_on_func_entry(kprobe_opcode_t *addr, const char *sym, unsigned long offset) 21631d585e70SNaveen N. Rao { 2164cc66bb91SPeter Zijlstra bool on_func_entry; 2165cc66bb91SPeter Zijlstra kprobe_opcode_t *kp_addr = _kprobe_addr(addr, sym, offset, &on_func_entry); 21661d585e70SNaveen N. Rao 21671d585e70SNaveen N. Rao if (IS_ERR(kp_addr)) 216897c753e6SMasami Hiramatsu return PTR_ERR(kp_addr); 21691d585e70SNaveen N. Rao 2170cc66bb91SPeter Zijlstra if (!on_func_entry) 217197c753e6SMasami Hiramatsu return -EINVAL; 217297c753e6SMasami Hiramatsu 217397c753e6SMasami Hiramatsu return 0; 21741d585e70SNaveen N. Rao } 21751d585e70SNaveen N. Rao 217655479f64SMasami Hiramatsu int register_kretprobe(struct kretprobe *rp) 2177b94cce92SHien Nguyen { 217897c753e6SMasami Hiramatsu int ret; 2179b94cce92SHien Nguyen struct kretprobe_instance *inst; 2180b94cce92SHien Nguyen int i; 2181b2a5cd69SMasami Hiramatsu void *addr; 218290ec5e89SNaveen N. Rao 218397c753e6SMasami Hiramatsu ret = kprobe_on_func_entry(rp->kp.addr, rp->kp.symbol_name, rp->kp.offset); 218497c753e6SMasami Hiramatsu if (ret) 218597c753e6SMasami Hiramatsu return ret; 2186f438d914SMasami Hiramatsu 2187223a76b2SMasami Hiramatsu /* If only 'rp->kp.addr' is specified, check reregistering kprobes */ 218833b1d146SMasami Hiramatsu if (rp->kp.addr && warn_kprobe_rereg(&rp->kp)) 21890188b878SWang ShaoBo return -EINVAL; 21900188b878SWang ShaoBo 2191f438d914SMasami Hiramatsu if (kretprobe_blacklist_size) { 2192b2a5cd69SMasami Hiramatsu addr = kprobe_addr(&rp->kp); 2193bc81d48dSMasami Hiramatsu if (IS_ERR(addr)) 2194bc81d48dSMasami Hiramatsu return PTR_ERR(addr); 2195f438d914SMasami Hiramatsu 2196f438d914SMasami Hiramatsu for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { 2197f438d914SMasami Hiramatsu if (kretprobe_blacklist[i].addr == addr) 2198f438d914SMasami Hiramatsu return -EINVAL; 2199f438d914SMasami Hiramatsu } 2200f438d914SMasami Hiramatsu } 2201b94cce92SHien Nguyen 22026bbfa441SMasami Hiramatsu if (rp->data_size > KRETPROBE_MAX_DATA_SIZE) 22036bbfa441SMasami Hiramatsu return -E2BIG; 22046bbfa441SMasami Hiramatsu 2205b94cce92SHien Nguyen rp->kp.pre_handler = pre_handler_kretprobe; 22067522a842SAnanth N Mavinakayanahalli rp->kp.post_handler = NULL; 2207b94cce92SHien Nguyen 2208b94cce92SHien Nguyen /* Pre-allocate memory for max kretprobe instances */ 2209b94cce92SHien Nguyen if (rp->maxactive <= 0) { 221092616606SThomas Gleixner #ifdef CONFIG_PREEMPTION 2211c2ef6661SHeiko Carstens rp->maxactive = max_t(unsigned int, 10, 2*num_possible_cpus()); 2212b94cce92SHien Nguyen #else 22134dae560fSAnanth N Mavinakayanahalli rp->maxactive = num_possible_cpus(); 2214b94cce92SHien Nguyen #endif 2215b94cce92SHien Nguyen } 221673f9b911SMasami Hiramatsu #ifdef CONFIG_KRETPROBE_ON_RETHOOK 221773f9b911SMasami Hiramatsu rp->rh = rethook_alloc((void *)rp, kretprobe_rethook_handler); 221873f9b911SMasami Hiramatsu if (!rp->rh) 221973f9b911SMasami Hiramatsu return -ENOMEM; 222073f9b911SMasami Hiramatsu 222173f9b911SMasami Hiramatsu for (i = 0; i < rp->maxactive; i++) { 222273f9b911SMasami Hiramatsu inst = kzalloc(sizeof(struct kretprobe_instance) + 222373f9b911SMasami Hiramatsu rp->data_size, GFP_KERNEL); 222473f9b911SMasami Hiramatsu if (inst == NULL) { 222573f9b911SMasami Hiramatsu rethook_free(rp->rh); 222673f9b911SMasami Hiramatsu rp->rh = NULL; 222773f9b911SMasami Hiramatsu return -ENOMEM; 222873f9b911SMasami Hiramatsu } 222973f9b911SMasami Hiramatsu rethook_add_node(rp->rh, &inst->node); 223073f9b911SMasami Hiramatsu } 223173f9b911SMasami Hiramatsu rp->nmissed = 0; 223273f9b911SMasami Hiramatsu /* Establish function entry probe point */ 223373f9b911SMasami Hiramatsu ret = register_kprobe(&rp->kp); 223473f9b911SMasami Hiramatsu if (ret != 0) { 223573f9b911SMasami Hiramatsu rethook_free(rp->rh); 223673f9b911SMasami Hiramatsu rp->rh = NULL; 223773f9b911SMasami Hiramatsu } 223873f9b911SMasami Hiramatsu #else /* !CONFIG_KRETPROBE_ON_RETHOOK */ 22396e426e0fSPeter Zijlstra rp->freelist.head = NULL; 2240d741bf41SPeter Zijlstra rp->rph = kzalloc(sizeof(struct kretprobe_holder), GFP_KERNEL); 2241d741bf41SPeter Zijlstra if (!rp->rph) 2242d741bf41SPeter Zijlstra return -ENOMEM; 2243d741bf41SPeter Zijlstra 2244d741bf41SPeter Zijlstra rp->rph->rp = rp; 2245b94cce92SHien Nguyen for (i = 0; i < rp->maxactive; i++) { 2246d741bf41SPeter Zijlstra inst = kzalloc(sizeof(struct kretprobe_instance) + 2247f47cd9b5SAbhishek Sagar rp->data_size, GFP_KERNEL); 2248b94cce92SHien Nguyen if (inst == NULL) { 2249d741bf41SPeter Zijlstra refcount_set(&rp->rph->ref, i); 2250b94cce92SHien Nguyen free_rp_inst(rp); 2251b94cce92SHien Nguyen return -ENOMEM; 2252b94cce92SHien Nguyen } 2253d741bf41SPeter Zijlstra inst->rph = rp->rph; 22546e426e0fSPeter Zijlstra freelist_add(&inst->freelist, &rp->freelist); 2255b94cce92SHien Nguyen } 2256d741bf41SPeter Zijlstra refcount_set(&rp->rph->ref, i); 2257b94cce92SHien Nguyen 2258b94cce92SHien Nguyen rp->nmissed = 0; 2259b94cce92SHien Nguyen /* Establish function entry probe point */ 226049ad2fd7SMasami Hiramatsu ret = register_kprobe(&rp->kp); 22614a296e07SMasami Hiramatsu if (ret != 0) 2262b94cce92SHien Nguyen free_rp_inst(rp); 226373f9b911SMasami Hiramatsu #endif 2264b94cce92SHien Nguyen return ret; 2265b94cce92SHien Nguyen } 226699081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobe); 2267b94cce92SHien Nguyen 226855479f64SMasami Hiramatsu int register_kretprobes(struct kretprobe **rps, int num) 22694a296e07SMasami Hiramatsu { 22704a296e07SMasami Hiramatsu int ret = 0, i; 22714a296e07SMasami Hiramatsu 22724a296e07SMasami Hiramatsu if (num <= 0) 22734a296e07SMasami Hiramatsu return -EINVAL; 22744a296e07SMasami Hiramatsu for (i = 0; i < num; i++) { 227549ad2fd7SMasami Hiramatsu ret = register_kretprobe(rps[i]); 227667dddaadSMasami Hiramatsu if (ret < 0) { 227767dddaadSMasami Hiramatsu if (i > 0) 22784a296e07SMasami Hiramatsu unregister_kretprobes(rps, i); 22794a296e07SMasami Hiramatsu break; 22804a296e07SMasami Hiramatsu } 22814a296e07SMasami Hiramatsu } 22824a296e07SMasami Hiramatsu return ret; 22834a296e07SMasami Hiramatsu } 228499081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobes); 22854a296e07SMasami Hiramatsu 228655479f64SMasami Hiramatsu void unregister_kretprobe(struct kretprobe *rp) 22874a296e07SMasami Hiramatsu { 22884a296e07SMasami Hiramatsu unregister_kretprobes(&rp, 1); 22894a296e07SMasami Hiramatsu } 229099081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobe); 22914a296e07SMasami Hiramatsu 229255479f64SMasami Hiramatsu void unregister_kretprobes(struct kretprobe **rps, int num) 22934a296e07SMasami Hiramatsu { 22944a296e07SMasami Hiramatsu int i; 22954a296e07SMasami Hiramatsu 22964a296e07SMasami Hiramatsu if (num <= 0) 22974a296e07SMasami Hiramatsu return; 22984a296e07SMasami Hiramatsu mutex_lock(&kprobe_mutex); 2299d741bf41SPeter Zijlstra for (i = 0; i < num; i++) { 23004a296e07SMasami Hiramatsu if (__unregister_kprobe_top(&rps[i]->kp) < 0) 23014a296e07SMasami Hiramatsu rps[i]->kp.addr = NULL; 230273f9b911SMasami Hiramatsu #ifdef CONFIG_KRETPROBE_ON_RETHOOK 230373f9b911SMasami Hiramatsu rethook_free(rps[i]->rh); 230473f9b911SMasami Hiramatsu #else 2305d741bf41SPeter Zijlstra rps[i]->rph->rp = NULL; 230673f9b911SMasami Hiramatsu #endif 2307d741bf41SPeter Zijlstra } 23084a296e07SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 23094a296e07SMasami Hiramatsu 2310ae8b7ce7SPaul E. McKenney synchronize_rcu(); 23114a296e07SMasami Hiramatsu for (i = 0; i < num; i++) { 23124a296e07SMasami Hiramatsu if (rps[i]->kp.addr) { 23134a296e07SMasami Hiramatsu __unregister_kprobe_bottom(&rps[i]->kp); 231473f9b911SMasami Hiramatsu #ifndef CONFIG_KRETPROBE_ON_RETHOOK 2315d741bf41SPeter Zijlstra free_rp_inst(rps[i]); 231673f9b911SMasami Hiramatsu #endif 23174a296e07SMasami Hiramatsu } 23184a296e07SMasami Hiramatsu } 23194a296e07SMasami Hiramatsu } 232099081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobes); 23214a296e07SMasami Hiramatsu 23229edddaa2SAnanth N Mavinakayanahalli #else /* CONFIG_KRETPROBES */ 232355479f64SMasami Hiramatsu int register_kretprobe(struct kretprobe *rp) 2324b94cce92SHien Nguyen { 2325223a76b2SMasami Hiramatsu return -EOPNOTSUPP; 2326b94cce92SHien Nguyen } 232799081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobe); 2328b94cce92SHien Nguyen 232955479f64SMasami Hiramatsu int register_kretprobes(struct kretprobe **rps, int num) 23304a296e07SMasami Hiramatsu { 2331223a76b2SMasami Hiramatsu return -EOPNOTSUPP; 23324a296e07SMasami Hiramatsu } 233399081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(register_kretprobes); 233499081ab5SMasami Hiramatsu 233555479f64SMasami Hiramatsu void unregister_kretprobe(struct kretprobe *rp) 23364a296e07SMasami Hiramatsu { 23374a296e07SMasami Hiramatsu } 233899081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobe); 23394a296e07SMasami Hiramatsu 234055479f64SMasami Hiramatsu void unregister_kretprobes(struct kretprobe **rps, int num) 23414a296e07SMasami Hiramatsu { 23424a296e07SMasami Hiramatsu } 234399081ab5SMasami Hiramatsu EXPORT_SYMBOL_GPL(unregister_kretprobes); 23444a296e07SMasami Hiramatsu 2345820aede0SMasami Hiramatsu static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) 2346346fd59bSSrinivasa Ds { 2347346fd59bSSrinivasa Ds return 0; 2348346fd59bSSrinivasa Ds } 2349820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(pre_handler_kretprobe); 23504a296e07SMasami Hiramatsu 23519edddaa2SAnanth N Mavinakayanahalli #endif /* CONFIG_KRETPROBES */ 2352b94cce92SHien Nguyen 2353e8386a0cSMasami Hiramatsu /* Set the kprobe gone and remove its instruction buffer. */ 235455479f64SMasami Hiramatsu static void kill_kprobe(struct kprobe *p) 2355e8386a0cSMasami Hiramatsu { 2356e8386a0cSMasami Hiramatsu struct kprobe *kp; 2357de5bd88dSMasami Hiramatsu 23587e6a71d8SMasami Hiramatsu lockdep_assert_held(&kprobe_mutex); 23597e6a71d8SMasami Hiramatsu 2360e8386a0cSMasami Hiramatsu p->flags |= KPROBE_FLAG_GONE; 2361afd66255SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 2362e8386a0cSMasami Hiramatsu /* 2363e8386a0cSMasami Hiramatsu * If this is an aggr_kprobe, we have to list all the 2364e8386a0cSMasami Hiramatsu * chained probes and mark them GONE. 2365e8386a0cSMasami Hiramatsu */ 23667e6a71d8SMasami Hiramatsu list_for_each_entry(kp, &p->list, list) 2367e8386a0cSMasami Hiramatsu kp->flags |= KPROBE_FLAG_GONE; 2368e8386a0cSMasami Hiramatsu p->post_handler = NULL; 2369afd66255SMasami Hiramatsu kill_optimized_kprobe(p); 2370e8386a0cSMasami Hiramatsu } 2371e8386a0cSMasami Hiramatsu /* 2372e8386a0cSMasami Hiramatsu * Here, we can remove insn_slot safely, because no thread calls 2373e8386a0cSMasami Hiramatsu * the original probed function (which will be freed soon) any more. 2374e8386a0cSMasami Hiramatsu */ 2375e8386a0cSMasami Hiramatsu arch_remove_kprobe(p); 23760cb2f137SMuchun Song 23770cb2f137SMuchun Song /* 23780cb2f137SMuchun Song * The module is going away. We should disarm the kprobe which 2379bcb53209SMasami Hiramatsu * is using ftrace, because ftrace framework is still available at 2380223a76b2SMasami Hiramatsu * 'MODULE_STATE_GOING' notification. 23810cb2f137SMuchun Song */ 2382bcb53209SMasami Hiramatsu if (kprobe_ftrace(p) && !kprobe_disabled(p) && !kprobes_all_disarmed) 23830cb2f137SMuchun Song disarm_kprobe_ftrace(p); 2384e8386a0cSMasami Hiramatsu } 2385e8386a0cSMasami Hiramatsu 2386c0614829SMasami Hiramatsu /* Disable one kprobe */ 238755479f64SMasami Hiramatsu int disable_kprobe(struct kprobe *kp) 2388c0614829SMasami Hiramatsu { 2389c0614829SMasami Hiramatsu int ret = 0; 2390297f9233SJessica Yu struct kprobe *p; 2391c0614829SMasami Hiramatsu 2392c0614829SMasami Hiramatsu mutex_lock(&kprobe_mutex); 2393c0614829SMasami Hiramatsu 23946f0f1dd7SMasami Hiramatsu /* Disable this kprobe */ 2395297f9233SJessica Yu p = __disable_kprobe(kp); 2396297f9233SJessica Yu if (IS_ERR(p)) 2397297f9233SJessica Yu ret = PTR_ERR(p); 2398c0614829SMasami Hiramatsu 2399c0614829SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2400c0614829SMasami Hiramatsu return ret; 2401c0614829SMasami Hiramatsu } 2402c0614829SMasami Hiramatsu EXPORT_SYMBOL_GPL(disable_kprobe); 2403c0614829SMasami Hiramatsu 2404c0614829SMasami Hiramatsu /* Enable one kprobe */ 240555479f64SMasami Hiramatsu int enable_kprobe(struct kprobe *kp) 2406c0614829SMasami Hiramatsu { 2407c0614829SMasami Hiramatsu int ret = 0; 2408c0614829SMasami Hiramatsu struct kprobe *p; 2409c0614829SMasami Hiramatsu 2410c0614829SMasami Hiramatsu mutex_lock(&kprobe_mutex); 2411c0614829SMasami Hiramatsu 2412c0614829SMasami Hiramatsu /* Check whether specified probe is valid. */ 2413c0614829SMasami Hiramatsu p = __get_valid_kprobe(kp); 2414c0614829SMasami Hiramatsu if (unlikely(p == NULL)) { 2415c0614829SMasami Hiramatsu ret = -EINVAL; 2416c0614829SMasami Hiramatsu goto out; 2417c0614829SMasami Hiramatsu } 2418c0614829SMasami Hiramatsu 2419c0614829SMasami Hiramatsu if (kprobe_gone(kp)) { 2420c0614829SMasami Hiramatsu /* This kprobe has gone, we couldn't enable it. */ 2421c0614829SMasami Hiramatsu ret = -EINVAL; 2422c0614829SMasami Hiramatsu goto out; 2423c0614829SMasami Hiramatsu } 2424c0614829SMasami Hiramatsu 2425c0614829SMasami Hiramatsu if (p != kp) 2426c0614829SMasami Hiramatsu kp->flags &= ~KPROBE_FLAG_DISABLED; 2427c0614829SMasami Hiramatsu 2428c0614829SMasami Hiramatsu if (!kprobes_all_disarmed && kprobe_disabled(p)) { 2429c0614829SMasami Hiramatsu p->flags &= ~KPROBE_FLAG_DISABLED; 243012310e34SJessica Yu ret = arm_kprobe(p); 243112310e34SJessica Yu if (ret) 243212310e34SJessica Yu p->flags |= KPROBE_FLAG_DISABLED; 2433c0614829SMasami Hiramatsu } 2434c0614829SMasami Hiramatsu out: 2435c0614829SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2436c0614829SMasami Hiramatsu return ret; 2437c0614829SMasami Hiramatsu } 2438c0614829SMasami Hiramatsu EXPORT_SYMBOL_GPL(enable_kprobe); 2439c0614829SMasami Hiramatsu 24404458515bSMasami Hiramatsu /* Caller must NOT call this in usual path. This is only for critical case */ 2441820aede0SMasami Hiramatsu void dump_kprobe(struct kprobe *kp) 244224851d24SFrederic Weisbecker { 24439c89bb8eSMasami Hiramatsu pr_err("Dump kprobe:\n.symbol_name = %s, .offset = %x, .addr = %pS\n", 24444458515bSMasami Hiramatsu kp->symbol_name, kp->offset, kp->addr); 244524851d24SFrederic Weisbecker } 2446820aede0SMasami Hiramatsu NOKPROBE_SYMBOL(dump_kprobe); 244724851d24SFrederic Weisbecker 2448fb1a59faSMasami Hiramatsu int kprobe_add_ksym_blacklist(unsigned long entry) 2449fb1a59faSMasami Hiramatsu { 2450fb1a59faSMasami Hiramatsu struct kprobe_blacklist_entry *ent; 2451fb1a59faSMasami Hiramatsu unsigned long offset = 0, size = 0; 2452fb1a59faSMasami Hiramatsu 2453fb1a59faSMasami Hiramatsu if (!kernel_text_address(entry) || 2454fb1a59faSMasami Hiramatsu !kallsyms_lookup_size_offset(entry, &size, &offset)) 2455fb1a59faSMasami Hiramatsu return -EINVAL; 2456fb1a59faSMasami Hiramatsu 2457fb1a59faSMasami Hiramatsu ent = kmalloc(sizeof(*ent), GFP_KERNEL); 2458fb1a59faSMasami Hiramatsu if (!ent) 2459fb1a59faSMasami Hiramatsu return -ENOMEM; 2460fb1a59faSMasami Hiramatsu ent->start_addr = entry; 2461fb1a59faSMasami Hiramatsu ent->end_addr = entry + size; 2462fb1a59faSMasami Hiramatsu INIT_LIST_HEAD(&ent->list); 2463fb1a59faSMasami Hiramatsu list_add_tail(&ent->list, &kprobe_blacklist); 2464fb1a59faSMasami Hiramatsu 2465fb1a59faSMasami Hiramatsu return (int)size; 2466fb1a59faSMasami Hiramatsu } 2467fb1a59faSMasami Hiramatsu 2468fb1a59faSMasami Hiramatsu /* Add all symbols in given area into kprobe blacklist */ 2469fb1a59faSMasami Hiramatsu int kprobe_add_area_blacklist(unsigned long start, unsigned long end) 2470fb1a59faSMasami Hiramatsu { 2471fb1a59faSMasami Hiramatsu unsigned long entry; 2472fb1a59faSMasami Hiramatsu int ret = 0; 2473fb1a59faSMasami Hiramatsu 2474fb1a59faSMasami Hiramatsu for (entry = start; entry < end; entry += ret) { 2475fb1a59faSMasami Hiramatsu ret = kprobe_add_ksym_blacklist(entry); 2476fb1a59faSMasami Hiramatsu if (ret < 0) 2477fb1a59faSMasami Hiramatsu return ret; 2478fb1a59faSMasami Hiramatsu if (ret == 0) /* In case of alias symbol */ 2479fb1a59faSMasami Hiramatsu ret = 1; 2480fb1a59faSMasami Hiramatsu } 2481fb1a59faSMasami Hiramatsu return 0; 2482fb1a59faSMasami Hiramatsu } 2483fb1a59faSMasami Hiramatsu 24841e6769b0SMasami Hiramatsu /* Remove all symbols in given area from kprobe blacklist */ 24851e6769b0SMasami Hiramatsu static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end) 24861e6769b0SMasami Hiramatsu { 24871e6769b0SMasami Hiramatsu struct kprobe_blacklist_entry *ent, *n; 24881e6769b0SMasami Hiramatsu 24891e6769b0SMasami Hiramatsu list_for_each_entry_safe(ent, n, &kprobe_blacklist, list) { 24901e6769b0SMasami Hiramatsu if (ent->start_addr < start || ent->start_addr >= end) 24911e6769b0SMasami Hiramatsu continue; 24921e6769b0SMasami Hiramatsu list_del(&ent->list); 24931e6769b0SMasami Hiramatsu kfree(ent); 24941e6769b0SMasami Hiramatsu } 24951e6769b0SMasami Hiramatsu } 24961e6769b0SMasami Hiramatsu 249716db6264SMasami Hiramatsu static void kprobe_remove_ksym_blacklist(unsigned long entry) 249816db6264SMasami Hiramatsu { 249916db6264SMasami Hiramatsu kprobe_remove_area_blacklist(entry, entry + 1); 250016db6264SMasami Hiramatsu } 250116db6264SMasami Hiramatsu 2502d002b8bcSAdrian Hunter int __weak arch_kprobe_get_kallsym(unsigned int *symnum, unsigned long *value, 2503d002b8bcSAdrian Hunter char *type, char *sym) 2504d002b8bcSAdrian Hunter { 2505d002b8bcSAdrian Hunter return -ERANGE; 2506d002b8bcSAdrian Hunter } 2507d002b8bcSAdrian Hunter 2508d002b8bcSAdrian Hunter int kprobe_get_kallsym(unsigned int symnum, unsigned long *value, char *type, 2509d002b8bcSAdrian Hunter char *sym) 2510d002b8bcSAdrian Hunter { 2511d002b8bcSAdrian Hunter #ifdef __ARCH_WANT_KPROBES_INSN_SLOT 2512d002b8bcSAdrian Hunter if (!kprobe_cache_get_kallsym(&kprobe_insn_slots, &symnum, value, type, sym)) 2513d002b8bcSAdrian Hunter return 0; 2514d002b8bcSAdrian Hunter #ifdef CONFIG_OPTPROBES 2515d002b8bcSAdrian Hunter if (!kprobe_cache_get_kallsym(&kprobe_optinsn_slots, &symnum, value, type, sym)) 2516d002b8bcSAdrian Hunter return 0; 2517d002b8bcSAdrian Hunter #endif 2518d002b8bcSAdrian Hunter #endif 2519d002b8bcSAdrian Hunter if (!arch_kprobe_get_kallsym(&symnum, value, type, sym)) 2520d002b8bcSAdrian Hunter return 0; 2521d002b8bcSAdrian Hunter return -ERANGE; 2522d002b8bcSAdrian Hunter } 2523d002b8bcSAdrian Hunter 2524fb1a59faSMasami Hiramatsu int __init __weak arch_populate_kprobe_blacklist(void) 2525fb1a59faSMasami Hiramatsu { 2526fb1a59faSMasami Hiramatsu return 0; 2527fb1a59faSMasami Hiramatsu } 2528fb1a59faSMasami Hiramatsu 2529376e2424SMasami Hiramatsu /* 2530376e2424SMasami Hiramatsu * Lookup and populate the kprobe_blacklist. 2531376e2424SMasami Hiramatsu * 2532376e2424SMasami Hiramatsu * Unlike the kretprobe blacklist, we'll need to determine 2533376e2424SMasami Hiramatsu * the range of addresses that belong to the said functions, 2534376e2424SMasami Hiramatsu * since a kprobe need not necessarily be at the beginning 2535376e2424SMasami Hiramatsu * of a function. 2536376e2424SMasami Hiramatsu */ 2537376e2424SMasami Hiramatsu static int __init populate_kprobe_blacklist(unsigned long *start, 2538376e2424SMasami Hiramatsu unsigned long *end) 2539376e2424SMasami Hiramatsu { 2540fb1a59faSMasami Hiramatsu unsigned long entry; 2541376e2424SMasami Hiramatsu unsigned long *iter; 2542fb1a59faSMasami Hiramatsu int ret; 2543376e2424SMasami Hiramatsu 2544376e2424SMasami Hiramatsu for (iter = start; iter < end; iter++) { 2545f2ec8d9aSMasami Hiramatsu entry = (unsigned long)dereference_symbol_descriptor((void *)*iter); 2546fb1a59faSMasami Hiramatsu ret = kprobe_add_ksym_blacklist(entry); 2547fb1a59faSMasami Hiramatsu if (ret == -EINVAL) 2548376e2424SMasami Hiramatsu continue; 2549fb1a59faSMasami Hiramatsu if (ret < 0) 2550fb1a59faSMasami Hiramatsu return ret; 2551376e2424SMasami Hiramatsu } 2552fb1a59faSMasami Hiramatsu 2553223a76b2SMasami Hiramatsu /* Symbols in '__kprobes_text' are blacklisted */ 2554fb1a59faSMasami Hiramatsu ret = kprobe_add_area_blacklist((unsigned long)__kprobes_text_start, 2555fb1a59faSMasami Hiramatsu (unsigned long)__kprobes_text_end); 255666e9b071SThomas Gleixner if (ret) 255766e9b071SThomas Gleixner return ret; 255866e9b071SThomas Gleixner 2559223a76b2SMasami Hiramatsu /* Symbols in 'noinstr' section are blacklisted */ 256066e9b071SThomas Gleixner ret = kprobe_add_area_blacklist((unsigned long)__noinstr_text_start, 256166e9b071SThomas Gleixner (unsigned long)__noinstr_text_end); 2562fb1a59faSMasami Hiramatsu 2563fb1a59faSMasami Hiramatsu return ret ? : arch_populate_kprobe_blacklist(); 2564376e2424SMasami Hiramatsu } 2565376e2424SMasami Hiramatsu 25661e6769b0SMasami Hiramatsu static void add_module_kprobe_blacklist(struct module *mod) 25671e6769b0SMasami Hiramatsu { 25681e6769b0SMasami Hiramatsu unsigned long start, end; 256916db6264SMasami Hiramatsu int i; 257016db6264SMasami Hiramatsu 257116db6264SMasami Hiramatsu if (mod->kprobe_blacklist) { 257216db6264SMasami Hiramatsu for (i = 0; i < mod->num_kprobe_blacklist; i++) 257316db6264SMasami Hiramatsu kprobe_add_ksym_blacklist(mod->kprobe_blacklist[i]); 257416db6264SMasami Hiramatsu } 25751e6769b0SMasami Hiramatsu 25761e6769b0SMasami Hiramatsu start = (unsigned long)mod->kprobes_text_start; 25771e6769b0SMasami Hiramatsu if (start) { 25781e6769b0SMasami Hiramatsu end = start + mod->kprobes_text_size; 25791e6769b0SMasami Hiramatsu kprobe_add_area_blacklist(start, end); 25801e6769b0SMasami Hiramatsu } 258166e9b071SThomas Gleixner 258266e9b071SThomas Gleixner start = (unsigned long)mod->noinstr_text_start; 258366e9b071SThomas Gleixner if (start) { 258466e9b071SThomas Gleixner end = start + mod->noinstr_text_size; 258566e9b071SThomas Gleixner kprobe_add_area_blacklist(start, end); 258666e9b071SThomas Gleixner } 25871e6769b0SMasami Hiramatsu } 25881e6769b0SMasami Hiramatsu 25891e6769b0SMasami Hiramatsu static void remove_module_kprobe_blacklist(struct module *mod) 25901e6769b0SMasami Hiramatsu { 25911e6769b0SMasami Hiramatsu unsigned long start, end; 259216db6264SMasami Hiramatsu int i; 259316db6264SMasami Hiramatsu 259416db6264SMasami Hiramatsu if (mod->kprobe_blacklist) { 259516db6264SMasami Hiramatsu for (i = 0; i < mod->num_kprobe_blacklist; i++) 259616db6264SMasami Hiramatsu kprobe_remove_ksym_blacklist(mod->kprobe_blacklist[i]); 259716db6264SMasami Hiramatsu } 25981e6769b0SMasami Hiramatsu 25991e6769b0SMasami Hiramatsu start = (unsigned long)mod->kprobes_text_start; 26001e6769b0SMasami Hiramatsu if (start) { 26011e6769b0SMasami Hiramatsu end = start + mod->kprobes_text_size; 26021e6769b0SMasami Hiramatsu kprobe_remove_area_blacklist(start, end); 26031e6769b0SMasami Hiramatsu } 260466e9b071SThomas Gleixner 260566e9b071SThomas Gleixner start = (unsigned long)mod->noinstr_text_start; 260666e9b071SThomas Gleixner if (start) { 260766e9b071SThomas Gleixner end = start + mod->noinstr_text_size; 260866e9b071SThomas Gleixner kprobe_remove_area_blacklist(start, end); 260966e9b071SThomas Gleixner } 26101e6769b0SMasami Hiramatsu } 26111e6769b0SMasami Hiramatsu 2612e8386a0cSMasami Hiramatsu /* Module notifier call back, checking kprobes on the module */ 261355479f64SMasami Hiramatsu static int kprobes_module_callback(struct notifier_block *nb, 2614e8386a0cSMasami Hiramatsu unsigned long val, void *data) 2615e8386a0cSMasami Hiramatsu { 2616e8386a0cSMasami Hiramatsu struct module *mod = data; 2617e8386a0cSMasami Hiramatsu struct hlist_head *head; 2618e8386a0cSMasami Hiramatsu struct kprobe *p; 2619e8386a0cSMasami Hiramatsu unsigned int i; 2620f24659d9SMasami Hiramatsu int checkcore = (val == MODULE_STATE_GOING); 2621e8386a0cSMasami Hiramatsu 26221e6769b0SMasami Hiramatsu if (val == MODULE_STATE_COMING) { 26231e6769b0SMasami Hiramatsu mutex_lock(&kprobe_mutex); 26241e6769b0SMasami Hiramatsu add_module_kprobe_blacklist(mod); 26251e6769b0SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 26261e6769b0SMasami Hiramatsu } 2627f24659d9SMasami Hiramatsu if (val != MODULE_STATE_GOING && val != MODULE_STATE_LIVE) 2628e8386a0cSMasami Hiramatsu return NOTIFY_DONE; 2629e8386a0cSMasami Hiramatsu 2630e8386a0cSMasami Hiramatsu /* 2631223a76b2SMasami Hiramatsu * When 'MODULE_STATE_GOING' was notified, both of module '.text' and 2632223a76b2SMasami Hiramatsu * '.init.text' sections would be freed. When 'MODULE_STATE_LIVE' was 2633223a76b2SMasami Hiramatsu * notified, only '.init.text' section would be freed. We need to 2634f24659d9SMasami Hiramatsu * disable kprobes which have been inserted in the sections. 2635e8386a0cSMasami Hiramatsu */ 2636e8386a0cSMasami Hiramatsu mutex_lock(&kprobe_mutex); 2637e8386a0cSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 2638e8386a0cSMasami Hiramatsu head = &kprobe_table[i]; 26397e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) 2640f24659d9SMasami Hiramatsu if (within_module_init((unsigned long)p->addr, mod) || 2641f24659d9SMasami Hiramatsu (checkcore && 2642f24659d9SMasami Hiramatsu within_module_core((unsigned long)p->addr, mod))) { 2643e8386a0cSMasami Hiramatsu /* 2644e8386a0cSMasami Hiramatsu * The vaddr this probe is installed will soon 2645e8386a0cSMasami Hiramatsu * be vfreed buy not synced to disk. Hence, 2646e8386a0cSMasami Hiramatsu * disarming the breakpoint isn't needed. 2647545a0281SSteven Rostedt (VMware) * 2648545a0281SSteven Rostedt (VMware) * Note, this will also move any optimized probes 2649545a0281SSteven Rostedt (VMware) * that are pending to be removed from their 2650223a76b2SMasami Hiramatsu * corresponding lists to the 'freeing_list' and 2651545a0281SSteven Rostedt (VMware) * will not be touched by the delayed 2652223a76b2SMasami Hiramatsu * kprobe_optimizer() work handler. 2653e8386a0cSMasami Hiramatsu */ 2654e8386a0cSMasami Hiramatsu kill_kprobe(p); 2655e8386a0cSMasami Hiramatsu } 2656e8386a0cSMasami Hiramatsu } 26571e6769b0SMasami Hiramatsu if (val == MODULE_STATE_GOING) 26581e6769b0SMasami Hiramatsu remove_module_kprobe_blacklist(mod); 2659e8386a0cSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2660e8386a0cSMasami Hiramatsu return NOTIFY_DONE; 2661e8386a0cSMasami Hiramatsu } 2662e8386a0cSMasami Hiramatsu 2663e8386a0cSMasami Hiramatsu static struct notifier_block kprobe_module_nb = { 2664e8386a0cSMasami Hiramatsu .notifier_call = kprobes_module_callback, 2665e8386a0cSMasami Hiramatsu .priority = 0 2666e8386a0cSMasami Hiramatsu }; 2667e8386a0cSMasami Hiramatsu 266882d083abSMasami Hiramatsu void kprobe_free_init_mem(void) 266982d083abSMasami Hiramatsu { 267082d083abSMasami Hiramatsu void *start = (void *)(&__init_begin); 267182d083abSMasami Hiramatsu void *end = (void *)(&__init_end); 267282d083abSMasami Hiramatsu struct hlist_head *head; 267382d083abSMasami Hiramatsu struct kprobe *p; 267482d083abSMasami Hiramatsu int i; 267582d083abSMasami Hiramatsu 267682d083abSMasami Hiramatsu mutex_lock(&kprobe_mutex); 267782d083abSMasami Hiramatsu 2678223a76b2SMasami Hiramatsu /* Kill all kprobes on initmem because the target code has been freed. */ 267982d083abSMasami Hiramatsu for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 268082d083abSMasami Hiramatsu head = &kprobe_table[i]; 268182d083abSMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 268282d083abSMasami Hiramatsu if (start <= (void *)p->addr && (void *)p->addr < end) 268382d083abSMasami Hiramatsu kill_kprobe(p); 268482d083abSMasami Hiramatsu } 268582d083abSMasami Hiramatsu } 268682d083abSMasami Hiramatsu 268782d083abSMasami Hiramatsu mutex_unlock(&kprobe_mutex); 268882d083abSMasami Hiramatsu } 268982d083abSMasami Hiramatsu 26901da177e4SLinus Torvalds static int __init init_kprobes(void) 26911da177e4SLinus Torvalds { 26921da177e4SLinus Torvalds int i, err = 0; 26931da177e4SLinus Torvalds 26941da177e4SLinus Torvalds /* FIXME allocate the probe table, currently defined statically */ 26951da177e4SLinus Torvalds /* initialize all list heads */ 2696d741bf41SPeter Zijlstra for (i = 0; i < KPROBE_TABLE_SIZE; i++) 26971da177e4SLinus Torvalds INIT_HLIST_HEAD(&kprobe_table[i]); 26981da177e4SLinus Torvalds 2699376e2424SMasami Hiramatsu err = populate_kprobe_blacklist(__start_kprobe_blacklist, 2700376e2424SMasami Hiramatsu __stop_kprobe_blacklist); 2701223a76b2SMasami Hiramatsu if (err) 27029c89bb8eSMasami Hiramatsu pr_err("Failed to populate blacklist (error %d), kprobes not restricted, be careful using them!\n", err); 27033d8d996eSSrinivasa Ds 2704f438d914SMasami Hiramatsu if (kretprobe_blacklist_size) { 2705f438d914SMasami Hiramatsu /* lookup the function address from its name */ 2706f438d914SMasami Hiramatsu for (i = 0; kretprobe_blacklist[i].name != NULL; i++) { 270749e0b465SNaveen N. Rao kretprobe_blacklist[i].addr = 2708290e3070SNaveen N. Rao kprobe_lookup_name(kretprobe_blacklist[i].name, 0); 2709f438d914SMasami Hiramatsu if (!kretprobe_blacklist[i].addr) 27109c89bb8eSMasami Hiramatsu pr_err("Failed to lookup symbol '%s' for kretprobe blacklist. Maybe the target function is removed or renamed.\n", 2711f438d914SMasami Hiramatsu kretprobe_blacklist[i].name); 2712f438d914SMasami Hiramatsu } 2713f438d914SMasami Hiramatsu } 2714f438d914SMasami Hiramatsu 2715e579abebSMasami Hiramatsu /* By default, kprobes are armed */ 2716e579abebSMasami Hiramatsu kprobes_all_disarmed = false; 2717bf8f6e5bSAnanth N Mavinakayanahalli 2718c85c9a2cSMasami Hiramatsu #if defined(CONFIG_OPTPROBES) && defined(__ARCH_WANT_KPROBES_INSN_SLOT) 2719223a76b2SMasami Hiramatsu /* Init 'kprobe_optinsn_slots' for allocation */ 2720c85c9a2cSMasami Hiramatsu kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; 2721c85c9a2cSMasami Hiramatsu #endif 2722c85c9a2cSMasami Hiramatsu 27236772926bSRusty Lynch err = arch_init_kprobes(); 2724802eae7cSRusty Lynch if (!err) 27251da177e4SLinus Torvalds err = register_die_notifier(&kprobe_exceptions_nb); 2726e8386a0cSMasami Hiramatsu if (!err) 2727e8386a0cSMasami Hiramatsu err = register_module_notifier(&kprobe_module_nb); 2728e8386a0cSMasami Hiramatsu 2729ef53d9c5SSrinivasa D S kprobes_initialized = (err == 0); 2730a737a3c6SXiaoming Ni kprobe_sysctls_init(); 27311da177e4SLinus Torvalds return err; 27321da177e4SLinus Torvalds } 273336dadef2SMasami Hiramatsu early_initcall(init_kprobes); 27341da177e4SLinus Torvalds 2735c85c9a2cSMasami Hiramatsu #if defined(CONFIG_OPTPROBES) 2736c85c9a2cSMasami Hiramatsu static int __init init_optprobes(void) 2737c85c9a2cSMasami Hiramatsu { 2738c85c9a2cSMasami Hiramatsu /* 2739c85c9a2cSMasami Hiramatsu * Enable kprobe optimization - this kicks the optimizer which 2740c85c9a2cSMasami Hiramatsu * depends on synchronize_rcu_tasks() and ksoftirqd, that is 2741c85c9a2cSMasami Hiramatsu * not spawned in early initcall. So delay the optimization. 2742c85c9a2cSMasami Hiramatsu */ 2743c85c9a2cSMasami Hiramatsu optimize_all_kprobes(); 2744c85c9a2cSMasami Hiramatsu 2745c85c9a2cSMasami Hiramatsu return 0; 2746c85c9a2cSMasami Hiramatsu } 2747c85c9a2cSMasami Hiramatsu subsys_initcall(init_optprobes); 2748c85c9a2cSMasami Hiramatsu #endif 2749c85c9a2cSMasami Hiramatsu 2750346fd59bSSrinivasa Ds #ifdef CONFIG_DEBUG_FS 275155479f64SMasami Hiramatsu static void report_probe(struct seq_file *pi, struct kprobe *p, 2752afd66255SMasami Hiramatsu const char *sym, int offset, char *modname, struct kprobe *pp) 2753346fd59bSSrinivasa Ds { 2754346fd59bSSrinivasa Ds char *kprobe_type; 275581365a94SMasami Hiramatsu void *addr = p->addr; 2756346fd59bSSrinivasa Ds 2757346fd59bSSrinivasa Ds if (p->pre_handler == pre_handler_kretprobe) 2758346fd59bSSrinivasa Ds kprobe_type = "r"; 2759346fd59bSSrinivasa Ds else 2760346fd59bSSrinivasa Ds kprobe_type = "k"; 2761afd66255SMasami Hiramatsu 276260f7bb66SKees Cook if (!kallsyms_show_value(pi->file->f_cred)) 276381365a94SMasami Hiramatsu addr = NULL; 276481365a94SMasami Hiramatsu 2765346fd59bSSrinivasa Ds if (sym) 276681365a94SMasami Hiramatsu seq_printf(pi, "%px %s %s+0x%x %s ", 276781365a94SMasami Hiramatsu addr, kprobe_type, sym, offset, 2768afd66255SMasami Hiramatsu (modname ? modname : " ")); 276981365a94SMasami Hiramatsu else /* try to use %pS */ 277081365a94SMasami Hiramatsu seq_printf(pi, "%px %s %pS ", 277181365a94SMasami Hiramatsu addr, kprobe_type, p->addr); 2772afd66255SMasami Hiramatsu 2773afd66255SMasami Hiramatsu if (!pp) 2774afd66255SMasami Hiramatsu pp = p; 2775ae6aa16fSMasami Hiramatsu seq_printf(pi, "%s%s%s%s\n", 2776de5bd88dSMasami Hiramatsu (kprobe_gone(p) ? "[GONE]" : ""), 2777afd66255SMasami Hiramatsu ((kprobe_disabled(p) && !kprobe_gone(p)) ? "[DISABLED]" : ""), 2778ae6aa16fSMasami Hiramatsu (kprobe_optimized(pp) ? "[OPTIMIZED]" : ""), 2779ae6aa16fSMasami Hiramatsu (kprobe_ftrace(pp) ? "[FTRACE]" : "")); 2780346fd59bSSrinivasa Ds } 2781346fd59bSSrinivasa Ds 278255479f64SMasami Hiramatsu static void *kprobe_seq_start(struct seq_file *f, loff_t *pos) 2783346fd59bSSrinivasa Ds { 2784346fd59bSSrinivasa Ds return (*pos < KPROBE_TABLE_SIZE) ? pos : NULL; 2785346fd59bSSrinivasa Ds } 2786346fd59bSSrinivasa Ds 278755479f64SMasami Hiramatsu static void *kprobe_seq_next(struct seq_file *f, void *v, loff_t *pos) 2788346fd59bSSrinivasa Ds { 2789346fd59bSSrinivasa Ds (*pos)++; 2790346fd59bSSrinivasa Ds if (*pos >= KPROBE_TABLE_SIZE) 2791346fd59bSSrinivasa Ds return NULL; 2792346fd59bSSrinivasa Ds return pos; 2793346fd59bSSrinivasa Ds } 2794346fd59bSSrinivasa Ds 279555479f64SMasami Hiramatsu static void kprobe_seq_stop(struct seq_file *f, void *v) 2796346fd59bSSrinivasa Ds { 2797346fd59bSSrinivasa Ds /* Nothing to do */ 2798346fd59bSSrinivasa Ds } 2799346fd59bSSrinivasa Ds 280055479f64SMasami Hiramatsu static int show_kprobe_addr(struct seq_file *pi, void *v) 2801346fd59bSSrinivasa Ds { 2802346fd59bSSrinivasa Ds struct hlist_head *head; 2803346fd59bSSrinivasa Ds struct kprobe *p, *kp; 2804346fd59bSSrinivasa Ds const char *sym = NULL; 2805346fd59bSSrinivasa Ds unsigned int i = *(loff_t *) v; 2806ffb45122SAlexey Dobriyan unsigned long offset = 0; 2807ab767865SJoe Mario char *modname, namebuf[KSYM_NAME_LEN]; 2808346fd59bSSrinivasa Ds 2809346fd59bSSrinivasa Ds head = &kprobe_table[i]; 2810346fd59bSSrinivasa Ds preempt_disable(); 2811b67bfe0dSSasha Levin hlist_for_each_entry_rcu(p, head, hlist) { 2812ffb45122SAlexey Dobriyan sym = kallsyms_lookup((unsigned long)p->addr, NULL, 2813346fd59bSSrinivasa Ds &offset, &modname, namebuf); 2814afd66255SMasami Hiramatsu if (kprobe_aggrprobe(p)) { 2815346fd59bSSrinivasa Ds list_for_each_entry_rcu(kp, &p->list, list) 2816afd66255SMasami Hiramatsu report_probe(pi, kp, sym, offset, modname, p); 2817346fd59bSSrinivasa Ds } else 2818afd66255SMasami Hiramatsu report_probe(pi, p, sym, offset, modname, NULL); 2819346fd59bSSrinivasa Ds } 2820346fd59bSSrinivasa Ds preempt_enable(); 2821346fd59bSSrinivasa Ds return 0; 2822346fd59bSSrinivasa Ds } 2823346fd59bSSrinivasa Ds 2824eac2ceceSKefeng Wang static const struct seq_operations kprobes_sops = { 2825346fd59bSSrinivasa Ds .start = kprobe_seq_start, 2826346fd59bSSrinivasa Ds .next = kprobe_seq_next, 2827346fd59bSSrinivasa Ds .stop = kprobe_seq_stop, 2828346fd59bSSrinivasa Ds .show = show_kprobe_addr 2829346fd59bSSrinivasa Ds }; 2830346fd59bSSrinivasa Ds 2831eac2ceceSKefeng Wang DEFINE_SEQ_ATTRIBUTE(kprobes); 2832346fd59bSSrinivasa Ds 283363724740SMasami Hiramatsu /* kprobes/blacklist -- shows which functions can not be probed */ 283463724740SMasami Hiramatsu static void *kprobe_blacklist_seq_start(struct seq_file *m, loff_t *pos) 283563724740SMasami Hiramatsu { 28364fdd8887SMasami Hiramatsu mutex_lock(&kprobe_mutex); 283763724740SMasami Hiramatsu return seq_list_start(&kprobe_blacklist, *pos); 283863724740SMasami Hiramatsu } 283963724740SMasami Hiramatsu 284063724740SMasami Hiramatsu static void *kprobe_blacklist_seq_next(struct seq_file *m, void *v, loff_t *pos) 284163724740SMasami Hiramatsu { 284263724740SMasami Hiramatsu return seq_list_next(v, &kprobe_blacklist, pos); 284363724740SMasami Hiramatsu } 284463724740SMasami Hiramatsu 284563724740SMasami Hiramatsu static int kprobe_blacklist_seq_show(struct seq_file *m, void *v) 284663724740SMasami Hiramatsu { 284763724740SMasami Hiramatsu struct kprobe_blacklist_entry *ent = 284863724740SMasami Hiramatsu list_entry(v, struct kprobe_blacklist_entry, list); 284963724740SMasami Hiramatsu 2850ffb9bd68SMasami Hiramatsu /* 2851223a76b2SMasami Hiramatsu * If '/proc/kallsyms' is not showing kernel address, we won't 2852ffb9bd68SMasami Hiramatsu * show them here either. 2853ffb9bd68SMasami Hiramatsu */ 285460f7bb66SKees Cook if (!kallsyms_show_value(m->file->f_cred)) 2855ffb9bd68SMasami Hiramatsu seq_printf(m, "0x%px-0x%px\t%ps\n", NULL, NULL, 2856ffb9bd68SMasami Hiramatsu (void *)ent->start_addr); 2857ffb9bd68SMasami Hiramatsu else 2858bcbd385bSThomas Richter seq_printf(m, "0x%px-0x%px\t%ps\n", (void *)ent->start_addr, 285963724740SMasami Hiramatsu (void *)ent->end_addr, (void *)ent->start_addr); 286063724740SMasami Hiramatsu return 0; 286163724740SMasami Hiramatsu } 286263724740SMasami Hiramatsu 28634fdd8887SMasami Hiramatsu static void kprobe_blacklist_seq_stop(struct seq_file *f, void *v) 28644fdd8887SMasami Hiramatsu { 28654fdd8887SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 28664fdd8887SMasami Hiramatsu } 28674fdd8887SMasami Hiramatsu 2868eac2ceceSKefeng Wang static const struct seq_operations kprobe_blacklist_sops = { 286963724740SMasami Hiramatsu .start = kprobe_blacklist_seq_start, 287063724740SMasami Hiramatsu .next = kprobe_blacklist_seq_next, 28714fdd8887SMasami Hiramatsu .stop = kprobe_blacklist_seq_stop, 287263724740SMasami Hiramatsu .show = kprobe_blacklist_seq_show, 287363724740SMasami Hiramatsu }; 2874eac2ceceSKefeng Wang DEFINE_SEQ_ATTRIBUTE(kprobe_blacklist); 287563724740SMasami Hiramatsu 287612310e34SJessica Yu static int arm_all_kprobes(void) 2877bf8f6e5bSAnanth N Mavinakayanahalli { 2878bf8f6e5bSAnanth N Mavinakayanahalli struct hlist_head *head; 2879bf8f6e5bSAnanth N Mavinakayanahalli struct kprobe *p; 288012310e34SJessica Yu unsigned int i, total = 0, errors = 0; 288112310e34SJessica Yu int err, ret = 0; 2882bf8f6e5bSAnanth N Mavinakayanahalli 2883bf8f6e5bSAnanth N Mavinakayanahalli mutex_lock(&kprobe_mutex); 2884bf8f6e5bSAnanth N Mavinakayanahalli 2885e579abebSMasami Hiramatsu /* If kprobes are armed, just return */ 2886e579abebSMasami Hiramatsu if (!kprobes_all_disarmed) 2887bf8f6e5bSAnanth N Mavinakayanahalli goto already_enabled; 2888bf8f6e5bSAnanth N Mavinakayanahalli 2889977ad481SWang Nan /* 2890977ad481SWang Nan * optimize_kprobe() called by arm_kprobe() checks 2891977ad481SWang Nan * kprobes_all_disarmed, so set kprobes_all_disarmed before 2892977ad481SWang Nan * arm_kprobe. 2893977ad481SWang Nan */ 2894977ad481SWang Nan kprobes_all_disarmed = false; 2895afd66255SMasami Hiramatsu /* Arming kprobes doesn't optimize kprobe itself */ 2896bf8f6e5bSAnanth N Mavinakayanahalli for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 2897bf8f6e5bSAnanth N Mavinakayanahalli head = &kprobe_table[i]; 289812310e34SJessica Yu /* Arm all kprobes on a best-effort basis */ 28997e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 290012310e34SJessica Yu if (!kprobe_disabled(p)) { 290112310e34SJessica Yu err = arm_kprobe(p); 290212310e34SJessica Yu if (err) { 290312310e34SJessica Yu errors++; 290412310e34SJessica Yu ret = err; 290512310e34SJessica Yu } 290612310e34SJessica Yu total++; 290712310e34SJessica Yu } 290812310e34SJessica Yu } 2909bf8f6e5bSAnanth N Mavinakayanahalli } 2910bf8f6e5bSAnanth N Mavinakayanahalli 291112310e34SJessica Yu if (errors) 29129c89bb8eSMasami Hiramatsu pr_warn("Kprobes globally enabled, but failed to enable %d out of %d probes. Please check which kprobes are kept disabled via debugfs.\n", 291312310e34SJessica Yu errors, total); 291412310e34SJessica Yu else 291512310e34SJessica Yu pr_info("Kprobes globally enabled\n"); 2916bf8f6e5bSAnanth N Mavinakayanahalli 2917bf8f6e5bSAnanth N Mavinakayanahalli already_enabled: 2918bf8f6e5bSAnanth N Mavinakayanahalli mutex_unlock(&kprobe_mutex); 291912310e34SJessica Yu return ret; 2920bf8f6e5bSAnanth N Mavinakayanahalli } 2921bf8f6e5bSAnanth N Mavinakayanahalli 2922297f9233SJessica Yu static int disarm_all_kprobes(void) 2923bf8f6e5bSAnanth N Mavinakayanahalli { 2924bf8f6e5bSAnanth N Mavinakayanahalli struct hlist_head *head; 2925bf8f6e5bSAnanth N Mavinakayanahalli struct kprobe *p; 2926297f9233SJessica Yu unsigned int i, total = 0, errors = 0; 2927297f9233SJessica Yu int err, ret = 0; 2928bf8f6e5bSAnanth N Mavinakayanahalli 2929bf8f6e5bSAnanth N Mavinakayanahalli mutex_lock(&kprobe_mutex); 2930bf8f6e5bSAnanth N Mavinakayanahalli 2931e579abebSMasami Hiramatsu /* If kprobes are already disarmed, just return */ 29326274de49SMasami Hiramatsu if (kprobes_all_disarmed) { 29336274de49SMasami Hiramatsu mutex_unlock(&kprobe_mutex); 2934297f9233SJessica Yu return 0; 29356274de49SMasami Hiramatsu } 2936bf8f6e5bSAnanth N Mavinakayanahalli 2937e579abebSMasami Hiramatsu kprobes_all_disarmed = true; 2938afd66255SMasami Hiramatsu 2939bf8f6e5bSAnanth N Mavinakayanahalli for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 2940bf8f6e5bSAnanth N Mavinakayanahalli head = &kprobe_table[i]; 2941297f9233SJessica Yu /* Disarm all kprobes on a best-effort basis */ 29427e6a71d8SMasami Hiramatsu hlist_for_each_entry(p, head, hlist) { 2943297f9233SJessica Yu if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) { 2944297f9233SJessica Yu err = disarm_kprobe(p, false); 2945297f9233SJessica Yu if (err) { 2946297f9233SJessica Yu errors++; 2947297f9233SJessica Yu ret = err; 2948297f9233SJessica Yu } 2949297f9233SJessica Yu total++; 2950bf8f6e5bSAnanth N Mavinakayanahalli } 2951bf8f6e5bSAnanth N Mavinakayanahalli } 2952297f9233SJessica Yu } 2953297f9233SJessica Yu 2954297f9233SJessica Yu if (errors) 29559c89bb8eSMasami Hiramatsu pr_warn("Kprobes globally disabled, but failed to disable %d out of %d probes. Please check which kprobes are kept enabled via debugfs.\n", 2956297f9233SJessica Yu errors, total); 2957297f9233SJessica Yu else 2958297f9233SJessica Yu pr_info("Kprobes globally disabled\n"); 2959297f9233SJessica Yu 2960bf8f6e5bSAnanth N Mavinakayanahalli mutex_unlock(&kprobe_mutex); 2961bf8f6e5bSAnanth N Mavinakayanahalli 29626274de49SMasami Hiramatsu /* Wait for disarming all kprobes by optimizer */ 29636274de49SMasami Hiramatsu wait_for_kprobe_optimizer(); 2964297f9233SJessica Yu 2965297f9233SJessica Yu return ret; 2966bf8f6e5bSAnanth N Mavinakayanahalli } 2967bf8f6e5bSAnanth N Mavinakayanahalli 2968bf8f6e5bSAnanth N Mavinakayanahalli /* 2969bf8f6e5bSAnanth N Mavinakayanahalli * XXX: The debugfs bool file interface doesn't allow for callbacks 2970bf8f6e5bSAnanth N Mavinakayanahalli * when the bool state is switched. We can reuse that facility when 2971bf8f6e5bSAnanth N Mavinakayanahalli * available 2972bf8f6e5bSAnanth N Mavinakayanahalli */ 2973bf8f6e5bSAnanth N Mavinakayanahalli static ssize_t read_enabled_file_bool(struct file *file, 2974bf8f6e5bSAnanth N Mavinakayanahalli char __user *user_buf, size_t count, loff_t *ppos) 2975bf8f6e5bSAnanth N Mavinakayanahalli { 2976bf8f6e5bSAnanth N Mavinakayanahalli char buf[3]; 2977bf8f6e5bSAnanth N Mavinakayanahalli 2978e579abebSMasami Hiramatsu if (!kprobes_all_disarmed) 2979bf8f6e5bSAnanth N Mavinakayanahalli buf[0] = '1'; 2980bf8f6e5bSAnanth N Mavinakayanahalli else 2981bf8f6e5bSAnanth N Mavinakayanahalli buf[0] = '0'; 2982bf8f6e5bSAnanth N Mavinakayanahalli buf[1] = '\n'; 2983bf8f6e5bSAnanth N Mavinakayanahalli buf[2] = 0x00; 2984bf8f6e5bSAnanth N Mavinakayanahalli return simple_read_from_buffer(user_buf, count, ppos, buf, 2); 2985bf8f6e5bSAnanth N Mavinakayanahalli } 2986bf8f6e5bSAnanth N Mavinakayanahalli 2987bf8f6e5bSAnanth N Mavinakayanahalli static ssize_t write_enabled_file_bool(struct file *file, 2988bf8f6e5bSAnanth N Mavinakayanahalli const char __user *user_buf, size_t count, loff_t *ppos) 2989bf8f6e5bSAnanth N Mavinakayanahalli { 29905d6de7d7SPunit Agrawal bool enable; 29915d6de7d7SPunit Agrawal int ret; 2992bf8f6e5bSAnanth N Mavinakayanahalli 29935d6de7d7SPunit Agrawal ret = kstrtobool_from_user(user_buf, count, &enable); 29945d6de7d7SPunit Agrawal if (ret) 29955d6de7d7SPunit Agrawal return ret; 2996bf8f6e5bSAnanth N Mavinakayanahalli 29975d6de7d7SPunit Agrawal ret = enable ? arm_all_kprobes() : disarm_all_kprobes(); 299812310e34SJessica Yu if (ret) 299912310e34SJessica Yu return ret; 300012310e34SJessica Yu 3001bf8f6e5bSAnanth N Mavinakayanahalli return count; 3002bf8f6e5bSAnanth N Mavinakayanahalli } 3003bf8f6e5bSAnanth N Mavinakayanahalli 3004828c0950SAlexey Dobriyan static const struct file_operations fops_kp = { 3005bf8f6e5bSAnanth N Mavinakayanahalli .read = read_enabled_file_bool, 3006bf8f6e5bSAnanth N Mavinakayanahalli .write = write_enabled_file_bool, 30076038f373SArnd Bergmann .llseek = default_llseek, 3008bf8f6e5bSAnanth N Mavinakayanahalli }; 3009bf8f6e5bSAnanth N Mavinakayanahalli 301055479f64SMasami Hiramatsu static int __init debugfs_kprobe_init(void) 3011346fd59bSSrinivasa Ds { 30128c0fd1faSGreg Kroah-Hartman struct dentry *dir; 3013346fd59bSSrinivasa Ds 3014346fd59bSSrinivasa Ds dir = debugfs_create_dir("kprobes", NULL); 3015346fd59bSSrinivasa Ds 3016eac2ceceSKefeng Wang debugfs_create_file("list", 0400, dir, NULL, &kprobes_fops); 3017346fd59bSSrinivasa Ds 30188f7262cdSPunit Agrawal debugfs_create_file("enabled", 0600, dir, NULL, &fops_kp); 301963724740SMasami Hiramatsu 30208c0fd1faSGreg Kroah-Hartman debugfs_create_file("blacklist", 0400, dir, NULL, 3021eac2ceceSKefeng Wang &kprobe_blacklist_fops); 3022bf8f6e5bSAnanth N Mavinakayanahalli 3023346fd59bSSrinivasa Ds return 0; 3024346fd59bSSrinivasa Ds } 3025346fd59bSSrinivasa Ds 3026346fd59bSSrinivasa Ds late_initcall(debugfs_kprobe_init); 3027346fd59bSSrinivasa Ds #endif /* CONFIG_DEBUG_FS */ 3028