···135135config UPROBES136136 def_bool n137137 depends on ARCH_SUPPORTS_UPROBES138138+ select TASKS_TRACE_RCU138139 help139140 Uprobes is the user-space counterpart to kprobes: they140141 enable instrumentation applications (such as 'perf probe')
+8-2
arch/x86/events/amd/core.c
···943943static int amd_pmu_v2_handle_irq(struct pt_regs *regs)944944{945945 struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);946946+ static atomic64_t status_warned = ATOMIC64_INIT(0);947947+ u64 reserved, status, mask, new_bits, prev_bits;946948 struct perf_sample_data data;947949 struct hw_perf_event *hwc;948950 struct perf_event *event;949951 int handled = 0, idx;950950- u64 reserved, status, mask;951952 bool pmu_enabled;952953953954 /*···10131012 * the corresponding PMCs are expected to be inactive according to the10141013 * active_mask10151014 */10161016- WARN_ON(status > 0);10151015+ if (status > 0) {10161016+ prev_bits = atomic64_fetch_or(status, &status_warned);10171017+ // A new bit was set for the very first time.10181018+ new_bits = status & ~prev_bits;10191019+ WARN(new_bits, "New overflows for inactive PMCs: %llx\n", new_bits);10201020+ }1017102110181022 /* Clear overflow and freeze bits */10191023 amd_pmu_ack_global_status(~status);
+121-12
arch/x86/events/intel/core.c
···45994599 X86_CONFIG(.event=0xc0, .umask=0x01);46004600}4601460146024602+static struct event_constraint *46034603+arl_h_get_event_constraints(struct cpu_hw_events *cpuc, int idx,46044604+ struct perf_event *event)46054605+{46064606+ struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);46074607+46084608+ if (pmu->pmu_type == hybrid_tiny)46094609+ return cmt_get_event_constraints(cpuc, idx, event);46104610+46114611+ return mtl_get_event_constraints(cpuc, idx, event);46124612+}46134613+46144614+static int arl_h_hw_config(struct perf_event *event)46154615+{46164616+ struct x86_hybrid_pmu *pmu = hybrid_pmu(event->pmu);46174617+46184618+ if (pmu->pmu_type == hybrid_tiny)46194619+ return intel_pmu_hw_config(event);46204620+46214621+ return adl_hw_config(event);46224622+}46234623+46024624/*46034625 * The HSW11 requires a period larger than 100 which is the same as the BDM11.46044626 * A minimum period of 128 is enforced as well for the INST_RETIRED.ALL.···4946492449474925 /*49484926 * This essentially just maps between the 'hybrid_cpu_type'49494949- * and 'hybrid_pmu_type' enums:49274927+ * and 'hybrid_pmu_type' enums except for ARL-H processor49284928+ * which needs to compare atom uarch native id since ARL-H49294929+ * contains two different atom uarchs.49504930 */49514931 for (i = 0; i < x86_pmu.num_hybrid_pmus; i++) {49524932 enum hybrid_pmu_type pmu_type = x86_pmu.hybrid_pmu[i].pmu_type;49334933+ u32 native_id;4953493449544954- if (cpu_type == HYBRID_INTEL_CORE &&49554955- pmu_type == hybrid_big)49354935+ if (cpu_type == HYBRID_INTEL_CORE && pmu_type == hybrid_big)49564936 return &x86_pmu.hybrid_pmu[i];49574957- if (cpu_type == HYBRID_INTEL_ATOM &&49584958- pmu_type == hybrid_small)49594959- return &x86_pmu.hybrid_pmu[i];49374937+ if (cpu_type == HYBRID_INTEL_ATOM) {49384938+ if (x86_pmu.num_hybrid_pmus == 2 && pmu_type == hybrid_small)49394939+ return &x86_pmu.hybrid_pmu[i];49404940+49414941+ native_id = get_this_hybrid_cpu_native_id();49424942+ if (native_id == skt_native_id && pmu_type == hybrid_small)49434943+ return &x86_pmu.hybrid_pmu[i];49444944+ if (native_id == cmt_native_id && pmu_type == hybrid_tiny)49454945+ return &x86_pmu.hybrid_pmu[i];49464946+ }49604947 }4961494849624949 return NULL;···59965965 NULL59975966};5998596759685968+/* The event string must be in PMU IDX order. */59695969+EVENT_ATTR_STR_HYBRID(topdown-retiring,59705970+ td_retiring_arl_h,59715971+ "event=0xc2,umask=0x02;event=0x00,umask=0x80;event=0xc2,umask=0x0",59725972+ hybrid_big_small_tiny);59735973+EVENT_ATTR_STR_HYBRID(topdown-bad-spec,59745974+ td_bad_spec_arl_h,59755975+ "event=0x73,umask=0x0;event=0x00,umask=0x81;event=0x73,umask=0x0",59765976+ hybrid_big_small_tiny);59775977+EVENT_ATTR_STR_HYBRID(topdown-fe-bound,59785978+ td_fe_bound_arl_h,59795979+ "event=0x9c,umask=0x01;event=0x00,umask=0x82;event=0x71,umask=0x0",59805980+ hybrid_big_small_tiny);59815981+EVENT_ATTR_STR_HYBRID(topdown-be-bound,59825982+ td_be_bound_arl_h,59835983+ "event=0xa4,umask=0x02;event=0x00,umask=0x83;event=0x74,umask=0x0",59845984+ hybrid_big_small_tiny);59855985+59865986+static struct attribute *arl_h_hybrid_events_attrs[] = {59875987+ EVENT_PTR(slots_adl),59885988+ EVENT_PTR(td_retiring_arl_h),59895989+ EVENT_PTR(td_bad_spec_arl_h),59905990+ EVENT_PTR(td_fe_bound_arl_h),59915991+ EVENT_PTR(td_be_bound_arl_h),59925992+ EVENT_PTR(td_heavy_ops_adl),59935993+ EVENT_PTR(td_br_mis_adl),59945994+ EVENT_PTR(td_fetch_lat_adl),59955995+ EVENT_PTR(td_mem_bound_adl),59965996+ NULL,59975997+};59985998+59995999/* Must be in IDX order */60006000EVENT_ATTR_STR_HYBRID(mem-loads, mem_ld_adl, "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3", hybrid_big_small);60016001EVENT_ATTR_STR_HYBRID(mem-stores, mem_st_adl, "event=0xd0,umask=0x6;event=0xcd,umask=0x2", hybrid_big_small);···60435981 EVENT_PTR(mem_ld_adl),60445982 EVENT_PTR(mem_st_adl),60455983 NULL59845984+};59855985+59865986+EVENT_ATTR_STR_HYBRID(mem-loads,59875987+ mem_ld_arl_h,59885988+ "event=0xd0,umask=0x5,ldlat=3;event=0xcd,umask=0x1,ldlat=3;event=0xd0,umask=0x5,ldlat=3",59895989+ hybrid_big_small_tiny);59905990+EVENT_ATTR_STR_HYBRID(mem-stores,59915991+ mem_st_arl_h,59925992+ "event=0xd0,umask=0x6;event=0xcd,umask=0x2;event=0xd0,umask=0x6",59935993+ hybrid_big_small_tiny);59945994+59955995+static struct attribute *arl_h_hybrid_mem_attrs[] = {59965996+ EVENT_PTR(mem_ld_arl_h),59975997+ EVENT_PTR(mem_st_arl_h),59985998+ NULL,60465999};6047600060486001EVENT_ATTR_STR_HYBRID(tx-start, tx_start_adl, "event=0xc9,umask=0x1", hybrid_big);···6083600660846007FORMAT_ATTR_HYBRID(in_tx, hybrid_big);60856008FORMAT_ATTR_HYBRID(in_tx_cp, hybrid_big);60866086-FORMAT_ATTR_HYBRID(offcore_rsp, hybrid_big_small);60876087-FORMAT_ATTR_HYBRID(ldlat, hybrid_big_small);60096009+FORMAT_ATTR_HYBRID(offcore_rsp, hybrid_big_small_tiny);60106010+FORMAT_ATTR_HYBRID(ldlat, hybrid_big_small_tiny);60886011FORMAT_ATTR_HYBRID(frontend, hybrid_big);6089601260906013#define ADL_HYBRID_RTM_FORMAT_ATTR \···61076030 NULL61086031};6109603261106110-FORMAT_ATTR_HYBRID(snoop_rsp, hybrid_small);60336033+FORMAT_ATTR_HYBRID(snoop_rsp, hybrid_small_tiny);6111603461126035static struct attribute *mtl_hybrid_extra_attr_rtm[] = {61136036 ADL_HYBRID_RTM_FORMAT_ATTR,···63156238}6316623963176240static const struct { enum hybrid_pmu_type id; char *name; } intel_hybrid_pmu_type_map[] __initconst = {63186318- { hybrid_small, "cpu_atom" },63196319- { hybrid_big, "cpu_core" },62416241+ { hybrid_small, "cpu_atom" },62426242+ { hybrid_big, "cpu_core" },62436243+ { hybrid_tiny, "cpu_lowpower" },63206244};6321624563226246static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus)···63506272 0, x86_pmu_num_counters(&pmu->pmu), 0, 0);6351627363526274 pmu->intel_cap.capabilities = x86_pmu.intel_cap.capabilities;63536353- if (pmu->pmu_type & hybrid_small) {62756275+ if (pmu->pmu_type & hybrid_small_tiny) {63546276 pmu->intel_cap.perf_metrics = 0;63556277 pmu->intel_cap.pebs_output_pt_available = 1;63566278 pmu->mid_ack = true;···71877109 intel_pmu_pebs_data_source_lnl();71887110 pr_cont("Lunarlake Hybrid events, ");71897111 name = "lunarlake_hybrid";71127112+ break;71137113+71147114+ case INTEL_ARROWLAKE_H:71157115+ intel_pmu_init_hybrid(hybrid_big_small_tiny);71167116+71177117+ x86_pmu.pebs_latency_data = arl_h_latency_data;71187118+ x86_pmu.get_event_constraints = arl_h_get_event_constraints;71197119+ x86_pmu.hw_config = arl_h_hw_config;71207120+71217121+ td_attr = arl_h_hybrid_events_attrs;71227122+ mem_attr = arl_h_hybrid_mem_attrs;71237123+ tsx_attr = adl_hybrid_tsx_attrs;71247124+ extra_attr = boot_cpu_has(X86_FEATURE_RTM) ?71257125+ mtl_hybrid_extra_attr_rtm : mtl_hybrid_extra_attr;71267126+71277127+ /* Initialize big core specific PerfMon capabilities. */71287128+ pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_CORE_IDX];71297129+ intel_pmu_init_lnc(&pmu->pmu);71307130+71317131+ /* Initialize Atom core specific PerfMon capabilities. */71327132+ pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_ATOM_IDX];71337133+ intel_pmu_init_skt(&pmu->pmu);71347134+71357135+ /* Initialize Lower Power Atom specific PerfMon capabilities. */71367136+ pmu = &x86_pmu.hybrid_pmu[X86_HYBRID_PMU_TINY_IDX];71377137+ intel_pmu_init_grt(&pmu->pmu);71387138+ pmu->extra_regs = intel_cmt_extra_regs;71397139+71407140+ intel_pmu_pebs_data_source_arl_h();71417141+ pr_cont("ArrowLake-H Hybrid events, ");71427142+ name = "arrowlake_h_hybrid";71907143 break;7191714471927145 default:
···1299129913001300 return cpuid_eax(0x0000001a) >> X86_HYBRID_CPU_TYPE_ID_SHIFT;13011301}13021302+13031303+/**13041304+ * get_this_hybrid_cpu_native_id() - Get the native id of this hybrid CPU13051305+ *13061306+ * Returns the uarch native ID [23:0] of a CPU in a hybrid processor.13071307+ * If the processor is not hybrid, returns 0.13081308+ */13091309+u32 get_this_hybrid_cpu_native_id(void)13101310+{13111311+ if (!cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))13121312+ return 0;13131313+13141314+ return cpuid_eax(0x0000001a) &13151315+ (BIT_ULL(X86_HYBRID_CPU_TYPE_ID_SHIFT) - 1);13161316+}
···1515#include <linux/rbtree.h>1616#include <linux/types.h>1717#include <linux/wait.h>1818+#include <linux/timer.h>18191920struct uprobe;2021struct vm_area_struct;···2423struct notifier_block;2524struct page;26252626+/*2727+ * Allowed return values from uprobe consumer's handler callback2828+ * with following meaning:2929+ *3030+ * UPROBE_HANDLER_REMOVE3131+ * - Remove the uprobe breakpoint from current->mm.3232+ * UPROBE_HANDLER_IGNORE3333+ * - Ignore ret_handler callback for this consumer.3434+ */2735#define UPROBE_HANDLER_REMOVE 12828-#define UPROBE_HANDLER_MASK 13636+#define UPROBE_HANDLER_IGNORE 229373038#define MAX_URETPROBE_DEPTH 643139···4737 * for the current process. If filter() is omitted or returns true,4838 * UPROBE_HANDLER_REMOVE is effectively ignored.4939 */5050- int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);4040+ int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs, __u64 *data);5141 int (*ret_handler)(struct uprobe_consumer *self,5242 unsigned long func,5353- struct pt_regs *regs);4343+ struct pt_regs *regs, __u64 *data);5444 bool (*filter)(struct uprobe_consumer *self, struct mm_struct *mm);55455646 struct list_head cons_node;4747+4848+ __u64 id; /* set when uprobe_consumer is registered */5749};58505951#ifdef CONFIG_UPROBES···6654 UTASK_SSTEP,6755 UTASK_SSTEP_ACK,6856 UTASK_SSTEP_TRAPPED,5757+};5858+5959+/* The state of hybrid-lifetime uprobe inside struct return_instance */6060+enum hprobe_state {6161+ HPROBE_LEASED, /* uretprobes_srcu-protected uprobe */6262+ HPROBE_STABLE, /* refcounted uprobe */6363+ HPROBE_GONE, /* NULL uprobe, SRCU expired, refcount failed */6464+ HPROBE_CONSUMED, /* uprobe "consumed" by uretprobe handler */6565+};6666+6767+/*6868+ * Hybrid lifetime uprobe. Represents a uprobe instance that could be either6969+ * SRCU protected (with SRCU protection eventually potentially timing out),7070+ * refcounted using uprobe->ref, or there could be no valid uprobe (NULL).7171+ *7272+ * hprobe's internal state is setup such that background timer thread can7373+ * atomically "downgrade" temporarily RCU-protected uprobe into refcounted one7474+ * (or no uprobe, if refcounting failed).7575+ *7676+ * *stable* pointer always point to the uprobe (or could be NULL if there is7777+ * was no valid underlying uprobe to begin with).7878+ *7979+ * *leased* pointer is the key to achieving race-free atomic lifetime state8080+ * transition and can have three possible states:8181+ * - either the same non-NULL value as *stable*, in which case uprobe is8282+ * SRCU-protected;8383+ * - NULL, in which case uprobe (if there is any) is refcounted;8484+ * - special __UPROBE_DEAD value, which represents an uprobe that was SRCU8585+ * protected initially, but SRCU period timed out and we attempted to8686+ * convert it to refcounted, but refcount_inc_not_zero() failed, because8787+ * uprobe effectively went away (the last consumer unsubscribed). In this8888+ * case it's important to know that *stable* pointer (which still has8989+ * non-NULL uprobe pointer) shouldn't be used, because lifetime of9090+ * underlying uprobe is not guaranteed anymore. __UPROBE_DEAD is just an9191+ * internal marker and is handled transparently by hprobe_fetch() helper.9292+ *9393+ * When uprobe is SRCU-protected, we also record srcu_idx value, necessary for9494+ * SRCU unlocking.9595+ *9696+ * See hprobe_expire() and hprobe_fetch() for details of race-free uprobe9797+ * state transitioning details. It all hinges on atomic xchg() over *leaded*9898+ * pointer. *stable* pointer, once initially set, is not modified concurrently.9999+ */100100+struct hprobe {101101+ enum hprobe_state state;102102+ int srcu_idx;103103+ struct uprobe *uprobe;69104};7010571106/*···13475 };1357613677 struct uprobe *active_uprobe;7878+ struct timer_list ri_timer;13779 unsigned long xol_vaddr;1388013981 struct arch_uprobe *auprobe;···14383 unsigned int depth;14484};145858686+struct return_consumer {8787+ __u64 cookie;8888+ __u64 id;8989+};9090+14691struct return_instance {147147- struct uprobe *uprobe;9292+ struct hprobe hprobe;14893 unsigned long func;14994 unsigned long stack; /* stack pointer */15095 unsigned long orig_ret_vaddr; /* original return address */15196 bool chained; /* true, if instance is nested */9797+ int consumers_cnt;1529815399 struct return_instance *next; /* keep as stack */154154-};100100+ struct rcu_head rcu;101101+102102+ struct return_consumer consumers[] __counted_by(consumers_cnt);103103+} ____cacheline_aligned;155104156105enum rp_check {157106 RP_CHECK_CALL,
+440-172
kernel/events/uprobes.c
···2626#include <linux/task_work.h>2727#include <linux/shmem_fs.h>2828#include <linux/khugepaged.h>2929+#include <linux/rcupdate_trace.h>3030+#include <linux/workqueue.h>3131+#include <linux/srcu.h>29323033#include <linux/uprobes.h>3134···4542static DEFINE_RWLOCK(uprobes_treelock); /* serialize rbtree access */4643static seqcount_rwlock_t uprobes_seqcount = SEQCNT_RWLOCK_ZERO(uprobes_seqcount, &uprobes_treelock);47444848-DEFINE_STATIC_SRCU(uprobes_srcu);4949-5045#define UPROBES_HASH_SZ 135146/* serialize uprobe->pending_list */5247static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];5348#define uprobes_mmap_hash(v) (&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])54495550DEFINE_STATIC_PERCPU_RWSEM(dup_mmap_sem);5151+5252+/* Covers return_instance's uprobe lifetime. */5353+DEFINE_STATIC_SRCU(uretprobes_srcu);56545755/* Have a copy of original instruction */5856#define UPROBE_COPY_INSN 0···6662 struct list_head pending_list;6763 struct list_head consumers;6864 struct inode *inode; /* Also hold a ref to inode */6969- struct rcu_head rcu;6565+ union {6666+ struct rcu_head rcu;6767+ struct work_struct work;6868+ };7069 loff_t offset;7170 loff_t ref_ctr_offset;7272- unsigned long flags;7171+ unsigned long flags; /* "unsigned long" so bitops work */73727473 /*7574 * The generic code assumes that it has two members of unknown type···107100 */108101struct xol_area {109102 wait_queue_head_t wq; /* if all slots are busy */110110- atomic_t slot_count; /* number of in-use slots */111103 unsigned long *bitmap; /* 0 = free slot */112104113105 struct page *page;···626620 return !RB_EMPTY_NODE(&uprobe->rb_node);627621}628622629629-static void uprobe_free_rcu(struct rcu_head *rcu)623623+static void uprobe_free_rcu_tasks_trace(struct rcu_head *rcu)630624{631625 struct uprobe *uprobe = container_of(rcu, struct uprobe, rcu);632626633627 kfree(uprobe);634628}635629636636-static void put_uprobe(struct uprobe *uprobe)630630+static void uprobe_free_srcu(struct rcu_head *rcu)637631{638638- if (!refcount_dec_and_test(&uprobe->ref))639639- return;632632+ struct uprobe *uprobe = container_of(rcu, struct uprobe, rcu);633633+634634+ call_rcu_tasks_trace(&uprobe->rcu, uprobe_free_rcu_tasks_trace);635635+}636636+637637+static void uprobe_free_deferred(struct work_struct *work)638638+{639639+ struct uprobe *uprobe = container_of(work, struct uprobe, work);640640641641 write_lock(&uprobes_treelock);642642···663651 delayed_uprobe_remove(uprobe, NULL);664652 mutex_unlock(&delayed_uprobe_lock);665653666666- call_srcu(&uprobes_srcu, &uprobe->rcu, uprobe_free_rcu);654654+ /* start srcu -> rcu_tasks_trace -> kfree chain */655655+ call_srcu(&uretprobes_srcu, &uprobe->rcu, uprobe_free_srcu);656656+}657657+658658+static void put_uprobe(struct uprobe *uprobe)659659+{660660+ if (!refcount_dec_and_test(&uprobe->ref))661661+ return;662662+663663+ INIT_WORK(&uprobe->work, uprobe_free_deferred);664664+ schedule_work(&uprobe->work);665665+}666666+667667+/* Initialize hprobe as SRCU-protected "leased" uprobe */668668+static void hprobe_init_leased(struct hprobe *hprobe, struct uprobe *uprobe, int srcu_idx)669669+{670670+ WARN_ON(!uprobe);671671+ hprobe->state = HPROBE_LEASED;672672+ hprobe->uprobe = uprobe;673673+ hprobe->srcu_idx = srcu_idx;674674+}675675+676676+/* Initialize hprobe as refcounted ("stable") uprobe (uprobe can be NULL). */677677+static void hprobe_init_stable(struct hprobe *hprobe, struct uprobe *uprobe)678678+{679679+ hprobe->state = uprobe ? HPROBE_STABLE : HPROBE_GONE;680680+ hprobe->uprobe = uprobe;681681+ hprobe->srcu_idx = -1;682682+}683683+684684+/*685685+ * hprobe_consume() fetches hprobe's underlying uprobe and detects whether686686+ * uprobe is SRCU protected or is refcounted. hprobe_consume() can be687687+ * used only once for a given hprobe.688688+ *689689+ * Caller has to call hprobe_finalize() and pass previous hprobe_state, so690690+ * that hprobe_finalize() can perform SRCU unlock or put uprobe, whichever691691+ * is appropriate.692692+ */693693+static inline struct uprobe *hprobe_consume(struct hprobe *hprobe, enum hprobe_state *hstate)694694+{695695+ *hstate = xchg(&hprobe->state, HPROBE_CONSUMED);696696+ switch (*hstate) {697697+ case HPROBE_LEASED:698698+ case HPROBE_STABLE:699699+ return hprobe->uprobe;700700+ case HPROBE_GONE: /* uprobe is NULL, no SRCU */701701+ case HPROBE_CONSUMED: /* uprobe was finalized already, do nothing */702702+ return NULL;703703+ default:704704+ WARN(1, "hprobe invalid state %d", *hstate);705705+ return NULL;706706+ }707707+}708708+709709+/*710710+ * Reset hprobe state and, if hprobe was LEASED, release SRCU lock.711711+ * hprobe_finalize() can only be used from current context after712712+ * hprobe_consume() call (which determines uprobe and hstate value).713713+ */714714+static void hprobe_finalize(struct hprobe *hprobe, enum hprobe_state hstate)715715+{716716+ switch (hstate) {717717+ case HPROBE_LEASED:718718+ __srcu_read_unlock(&uretprobes_srcu, hprobe->srcu_idx);719719+ break;720720+ case HPROBE_STABLE:721721+ put_uprobe(hprobe->uprobe);722722+ break;723723+ case HPROBE_GONE:724724+ case HPROBE_CONSUMED:725725+ break;726726+ default:727727+ WARN(1, "hprobe invalid state %d", hstate);728728+ break;729729+ }730730+}731731+732732+/*733733+ * Attempt to switch (atomically) uprobe from being SRCU protected (LEASED)734734+ * to refcounted (STABLE) state. Competes with hprobe_consume(); only one of735735+ * them can win the race to perform SRCU unlocking. Whoever wins must perform736736+ * SRCU unlock.737737+ *738738+ * Returns underlying valid uprobe or NULL, if there was no underlying uprobe739739+ * to begin with or we failed to bump its refcount and it's going away.740740+ *741741+ * Returned non-NULL uprobe can be still safely used within an ongoing SRCU742742+ * locked region. If `get` is true, it's guaranteed that non-NULL uprobe has743743+ * an extra refcount for caller to assume and use. Otherwise, it's not744744+ * guaranteed that returned uprobe has a positive refcount, so caller has to745745+ * attempt try_get_uprobe(), if it needs to preserve uprobe beyond current746746+ * SRCU lock region. See dup_utask().747747+ */748748+static struct uprobe *hprobe_expire(struct hprobe *hprobe, bool get)749749+{750750+ enum hprobe_state hstate;751751+752752+ /*753753+ * return_instance's hprobe is protected by RCU.754754+ * Underlying uprobe is itself protected from reuse by SRCU.755755+ */756756+ lockdep_assert(rcu_read_lock_held() && srcu_read_lock_held(&uretprobes_srcu));757757+758758+ hstate = READ_ONCE(hprobe->state);759759+ switch (hstate) {760760+ case HPROBE_STABLE:761761+ /* uprobe has positive refcount, bump refcount, if necessary */762762+ return get ? get_uprobe(hprobe->uprobe) : hprobe->uprobe;763763+ case HPROBE_GONE:764764+ /*765765+ * SRCU was unlocked earlier and we didn't manage to take766766+ * uprobe refcnt, so it's effectively NULL767767+ */768768+ return NULL;769769+ case HPROBE_CONSUMED:770770+ /*771771+ * uprobe was consumed, so it's effectively NULL as far as772772+ * uretprobe processing logic is concerned773773+ */774774+ return NULL;775775+ case HPROBE_LEASED: {776776+ struct uprobe *uprobe = try_get_uprobe(hprobe->uprobe);777777+ /*778778+ * Try to switch hprobe state, guarding against779779+ * hprobe_consume() or another hprobe_expire() racing with us.780780+ * Note, if we failed to get uprobe refcount, we use special781781+ * HPROBE_GONE state to signal that hprobe->uprobe shouldn't782782+ * be used as it will be freed after SRCU is unlocked.783783+ */784784+ if (try_cmpxchg(&hprobe->state, &hstate, uprobe ? HPROBE_STABLE : HPROBE_GONE)) {785785+ /* We won the race, we are the ones to unlock SRCU */786786+ __srcu_read_unlock(&uretprobes_srcu, hprobe->srcu_idx);787787+ return get ? get_uprobe(uprobe) : uprobe;788788+ }789789+790790+ /*791791+ * We lost the race, undo refcount bump (if it ever happened),792792+ * unless caller would like an extra refcount anyways.793793+ */794794+ if (uprobe && !get)795795+ put_uprobe(uprobe);796796+ /*797797+ * Even if hprobe_consume() or another hprobe_expire() wins798798+ * the state update race and unlocks SRCU from under us, we799799+ * still have a guarantee that underyling uprobe won't be800800+ * freed due to ongoing caller's SRCU lock region, so we can801801+ * return it regardless. Also, if `get` was true, we also have802802+ * an extra ref for the caller to own. This is used in dup_utask().803803+ */804804+ return uprobe;805805+ }806806+ default:807807+ WARN(1, "unknown hprobe state %d", hstate);808808+ return NULL;809809+ }667810}668811669812static __always_inline···873706 struct rb_node *node;874707 unsigned int seq;875708876876- lockdep_assert(srcu_read_lock_held(&uprobes_srcu));709709+ lockdep_assert(rcu_read_lock_trace_held());877710878711 do {879712 seq = read_seqcount_begin(&uprobes_seqcount);···992825993826static void consumer_add(struct uprobe *uprobe, struct uprobe_consumer *uc)994827{828828+ static atomic64_t id;829829+995830 down_write(&uprobe->consumer_rwsem);996831 list_add_rcu(&uc->cons_node, &uprobe->consumers);832832+ uc->id = (__u64) atomic64_inc_return(&id);997833 up_write(&uprobe->consumer_rwsem);998834}999835···1104934 bool ret = false;11059351106936 down_read(&uprobe->consumer_rwsem);11071107- list_for_each_entry_srcu(uc, &uprobe->consumers, cons_node,11081108- srcu_read_lock_held(&uprobes_srcu)) {937937+ list_for_each_entry_rcu(uc, &uprobe->consumers, cons_node, rcu_read_lock_trace_held()) {1109938 ret = consumer_filter(uc, mm);1110939 if (ret)1111940 break;···13251156 * unlucky enough caller can free consumer's memory and cause13261157 * handler_chain() or handle_uretprobe_chain() to do an use-after-free.13271158 */13281328- synchronize_srcu(&uprobes_srcu);11591159+ synchronize_rcu_tasks_trace();11601160+ synchronize_srcu(&uretprobes_srcu);13291161}13301162EXPORT_SYMBOL_GPL(uprobe_unregister_sync);13311163···14101240int uprobe_apply(struct uprobe *uprobe, struct uprobe_consumer *uc, bool add)14111241{14121242 struct uprobe_consumer *con;14131413- int ret = -ENOENT, srcu_idx;12431243+ int ret = -ENOENT;1414124414151245 down_write(&uprobe->register_rwsem);1416124614171417- srcu_idx = srcu_read_lock(&uprobes_srcu);14181418- list_for_each_entry_srcu(con, &uprobe->consumers, cons_node,14191419- srcu_read_lock_held(&uprobes_srcu)) {12471247+ rcu_read_lock_trace();12481248+ list_for_each_entry_rcu(con, &uprobe->consumers, cons_node, rcu_read_lock_trace_held()) {14201249 if (con == uc) {14211250 ret = register_for_each_vma(uprobe, add ? uc : NULL);14221251 break;14231252 }14241253 }14251425- srcu_read_unlock(&uprobes_srcu, srcu_idx);12541254+ rcu_read_unlock_trace();1426125514271256 up_write(&uprobe->register_rwsem);14281257···16441475 return 0;16451476}1646147714781478+static int xol_mremap(const struct vm_special_mapping *sm, struct vm_area_struct *new_vma)14791479+{14801480+ return -EPERM;14811481+}14821482+16471483static const struct vm_special_mapping xol_mapping = {16481484 .name = "[uprobes]",16491485 .fault = xol_fault,14861486+ .mremap = xol_mremap,16501487};1651148816521489/* Slot allocation for XOL */···17281553 init_waitqueue_head(&area->wq);17291554 /* Reserve the 1st slot for get_trampoline_vaddr() */17301555 set_bit(0, area->bitmap);17311731- atomic_set(&area->slot_count, 1);17321556 insns = arch_uprobe_trampoline(&insns_size);17331557 arch_uprobe_copy_ixol(area->page, 0, insns, insns_size);17341558···18001626 }18011627}1802162818031803-/*18041804- * - search for a free slot.18051805- */18061806-static unsigned long xol_take_insn_slot(struct xol_area *area)16291629+static unsigned long xol_get_slot_nr(struct xol_area *area)18071630{18081808- unsigned long slot_addr;18091809- int slot_nr;16311631+ unsigned long slot_nr;1810163218111811- do {18121812- slot_nr = find_first_zero_bit(area->bitmap, UINSNS_PER_PAGE);18131813- if (slot_nr < UINSNS_PER_PAGE) {18141814- if (!test_and_set_bit(slot_nr, area->bitmap))18151815- break;16331633+ slot_nr = find_first_zero_bit(area->bitmap, UINSNS_PER_PAGE);16341634+ if (slot_nr < UINSNS_PER_PAGE) {16351635+ if (!test_and_set_bit(slot_nr, area->bitmap))16361636+ return slot_nr;16371637+ }1816163818171817- slot_nr = UINSNS_PER_PAGE;18181818- continue;18191819- }18201820- wait_event(area->wq, (atomic_read(&area->slot_count) < UINSNS_PER_PAGE));18211821- } while (slot_nr >= UINSNS_PER_PAGE);18221822-18231823- slot_addr = area->vaddr + (slot_nr * UPROBE_XOL_SLOT_BYTES);18241824- atomic_inc(&area->slot_count);18251825-18261826- return slot_addr;16391639+ return UINSNS_PER_PAGE;18271640}1828164118291642/*18301643 * xol_get_insn_slot - allocate a slot for xol.18311831- * Returns the allocated slot address or 0.18321644 */18331833-static unsigned long xol_get_insn_slot(struct uprobe *uprobe)16451645+static bool xol_get_insn_slot(struct uprobe *uprobe, struct uprobe_task *utask)18341646{18351835- struct xol_area *area;18361836- unsigned long xol_vaddr;16471647+ struct xol_area *area = get_xol_area();16481648+ unsigned long slot_nr;1837164918381838- area = get_xol_area();18391650 if (!area)18401840- return 0;16511651+ return false;1841165218421842- xol_vaddr = xol_take_insn_slot(area);18431843- if (unlikely(!xol_vaddr))18441844- return 0;16531653+ wait_event(area->wq, (slot_nr = xol_get_slot_nr(area)) < UINSNS_PER_PAGE);1845165418461846- arch_uprobe_copy_ixol(area->page, xol_vaddr,16551655+ utask->xol_vaddr = area->vaddr + slot_nr * UPROBE_XOL_SLOT_BYTES;16561656+ arch_uprobe_copy_ixol(area->page, utask->xol_vaddr,18471657 &uprobe->arch.ixol, sizeof(uprobe->arch.ixol));18481848-18491849- return xol_vaddr;16581658+ return true;18501659}1851166018521661/*18531853- * xol_free_insn_slot - If slot was earlier allocated by18541854- * @xol_get_insn_slot(), make the slot available for18551855- * subsequent requests.16621662+ * xol_free_insn_slot - free the slot allocated by xol_get_insn_slot()18561663 */18571857-static void xol_free_insn_slot(struct task_struct *tsk)16641664+static void xol_free_insn_slot(struct uprobe_task *utask)18581665{18591859- struct xol_area *area;18601860- unsigned long vma_end;18611861- unsigned long slot_addr;16661666+ struct xol_area *area = current->mm->uprobes_state.xol_area;16671667+ unsigned long offset = utask->xol_vaddr - area->vaddr;16681668+ unsigned int slot_nr;1862166918631863- if (!tsk->mm || !tsk->mm->uprobes_state.xol_area || !tsk->utask)16701670+ utask->xol_vaddr = 0;16711671+ /* xol_vaddr must fit into [area->vaddr, area->vaddr + PAGE_SIZE) */16721672+ if (WARN_ON_ONCE(offset >= PAGE_SIZE))18641673 return;1865167418661866- slot_addr = tsk->utask->xol_vaddr;18671867- if (unlikely(!slot_addr))18681868- return;18691869-18701870- area = tsk->mm->uprobes_state.xol_area;18711871- vma_end = area->vaddr + PAGE_SIZE;18721872- if (area->vaddr <= slot_addr && slot_addr < vma_end) {18731873- unsigned long offset;18741874- int slot_nr;18751875-18761876- offset = slot_addr - area->vaddr;18771877- slot_nr = offset / UPROBE_XOL_SLOT_BYTES;18781878- if (slot_nr >= UINSNS_PER_PAGE)18791879- return;18801880-18811881- clear_bit(slot_nr, area->bitmap);18821882- atomic_dec(&area->slot_count);18831883- smp_mb__after_atomic(); /* pairs with prepare_to_wait() */18841884- if (waitqueue_active(&area->wq))18851885- wake_up(&area->wq);18861886-18871887- tsk->utask->xol_vaddr = 0;18881888- }16751675+ slot_nr = offset / UPROBE_XOL_SLOT_BYTES;16761676+ clear_bit(slot_nr, area->bitmap);16771677+ smp_mb__after_atomic(); /* pairs with prepare_to_wait() */16781678+ if (waitqueue_active(&area->wq))16791679+ wake_up(&area->wq);18891680}1890168118911682void __weak arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,···18891750 return instruction_pointer(regs);18901751}1891175218921892-static struct return_instance *free_ret_instance(struct return_instance *ri)17531753+static struct return_instance *free_ret_instance(struct return_instance *ri, bool cleanup_hprobe)18931754{18941755 struct return_instance *next = ri->next;18951895- put_uprobe(ri->uprobe);18961896- kfree(ri);17561756+17571757+ if (cleanup_hprobe) {17581758+ enum hprobe_state hstate;17591759+17601760+ (void)hprobe_consume(&ri->hprobe, &hstate);17611761+ hprobe_finalize(&ri->hprobe, hstate);17621762+ }17631763+17641764+ kfree_rcu(ri, rcu);18971765 return next;18981766}18991767···19161770 if (!utask)19171771 return;1918177219191919- if (utask->active_uprobe)19201920- put_uprobe(utask->active_uprobe);17731773+ WARN_ON_ONCE(utask->active_uprobe || utask->xol_vaddr);17741774+17751775+ timer_delete_sync(&utask->ri_timer);1921177619221777 ri = utask->return_instances;19231778 while (ri)19241924- ri = free_ret_instance(ri);17791779+ ri = free_ret_instance(ri, true /* cleanup_hprobe */);1925178019261926- xol_free_insn_slot(t);19271781 kfree(utask);19281782 t->utask = NULL;17831783+}17841784+17851785+#define RI_TIMER_PERIOD (HZ / 10) /* 100 ms */17861786+17871787+#define for_each_ret_instance_rcu(pos, head) \17881788+ for (pos = rcu_dereference_raw(head); pos; pos = rcu_dereference_raw(pos->next))17891789+17901790+static void ri_timer(struct timer_list *timer)17911791+{17921792+ struct uprobe_task *utask = container_of(timer, struct uprobe_task, ri_timer);17931793+ struct return_instance *ri;17941794+17951795+ /* SRCU protects uprobe from reuse for the cmpxchg() inside hprobe_expire(). */17961796+ guard(srcu)(&uretprobes_srcu);17971797+ /* RCU protects return_instance from freeing. */17981798+ guard(rcu)();17991799+18001800+ for_each_ret_instance_rcu(ri, utask->return_instances)18011801+ hprobe_expire(&ri->hprobe, false);18021802+}18031803+18041804+static struct uprobe_task *alloc_utask(void)18051805+{18061806+ struct uprobe_task *utask;18071807+18081808+ utask = kzalloc(sizeof(*utask), GFP_KERNEL);18091809+ if (!utask)18101810+ return NULL;18111811+18121812+ timer_setup(&utask->ri_timer, ri_timer, 0);18131813+18141814+ return utask;19291815}1930181619311817/*···19711793static struct uprobe_task *get_utask(void)19721794{19731795 if (!current->utask)19741974- current->utask = kzalloc(sizeof(struct uprobe_task), GFP_KERNEL);17961796+ current->utask = alloc_utask();19751797 return current->utask;17981798+}17991799+18001800+static size_t ri_size(int consumers_cnt)18011801+{18021802+ struct return_instance *ri;18031803+18041804+ return sizeof(*ri) + sizeof(ri->consumers[0]) * consumers_cnt;18051805+}18061806+18071807+#define DEF_CNT 418081808+18091809+static struct return_instance *alloc_return_instance(void)18101810+{18111811+ struct return_instance *ri;18121812+18131813+ ri = kzalloc(ri_size(DEF_CNT), GFP_KERNEL);18141814+ if (!ri)18151815+ return ZERO_SIZE_PTR;18161816+18171817+ ri->consumers_cnt = DEF_CNT;18181818+ return ri;18191819+}18201820+18211821+static struct return_instance *dup_return_instance(struct return_instance *old)18221822+{18231823+ size_t size = ri_size(old->consumers_cnt);18241824+18251825+ return kmemdup(old, size, GFP_KERNEL);19761826}1977182719781828static int dup_utask(struct task_struct *t, struct uprobe_task *o_utask)19791829{19801830 struct uprobe_task *n_utask;19811831 struct return_instance **p, *o, *n;18321832+ struct uprobe *uprobe;1982183319831983- n_utask = kzalloc(sizeof(struct uprobe_task), GFP_KERNEL);18341834+ n_utask = alloc_utask();19841835 if (!n_utask)19851836 return -ENOMEM;19861837 t->utask = n_utask;1987183818391839+ /* protect uprobes from freeing, we'll need try_get_uprobe() them */18401840+ guard(srcu)(&uretprobes_srcu);18411841+19881842 p = &n_utask->return_instances;19891843 for (o = o_utask->return_instances; o; o = o->next) {19901990- n = kmalloc(sizeof(struct return_instance), GFP_KERNEL);18441844+ n = dup_return_instance(o);19911845 if (!n)19921846 return -ENOMEM;1993184719941994- *n = *o;19951995- /*19961996- * uprobe's refcnt has to be positive at this point, kept by19971997- * utask->return_instances items; return_instances can't be19981998- * removed right now, as task is blocked due to duping; so19991999- * get_uprobe() is safe to use here.20002000- */20012001- get_uprobe(n->uprobe);20022002- n->next = NULL;18481848+ /* if uprobe is non-NULL, we'll have an extra refcount for uprobe */18491849+ uprobe = hprobe_expire(&o->hprobe, true);2003185020042004- *p = n;18511851+ /*18521852+ * New utask will have stable properly refcounted uprobe or18531853+ * NULL. Even if we failed to get refcounted uprobe, we still18541854+ * need to preserve full set of return_instances for proper18551855+ * uretprobe handling and nesting in forked task.18561856+ */18571857+ hprobe_init_stable(&n->hprobe, uprobe);18581858+18591859+ n->next = NULL;18601860+ rcu_assign_pointer(*p, n);20051861 p = &n->next;18621862+20061863 n_utask->depth++;20071864 }20081865···21131900 enum rp_check ctx = chained ? RP_CHECK_CHAIN_CALL : RP_CHECK_CALL;2114190121151902 while (ri && !arch_uretprobe_is_alive(ri, ctx, regs)) {21162116- ri = free_ret_instance(ri);19031903+ ri = free_ret_instance(ri, true /* cleanup_hprobe */);21171904 utask->depth--;21181905 }21192119- utask->return_instances = ri;19061906+ rcu_assign_pointer(utask->return_instances, ri);21201907}2121190821222122-static void prepare_uretprobe(struct uprobe *uprobe, struct pt_regs *regs)19091909+static void prepare_uretprobe(struct uprobe *uprobe, struct pt_regs *regs,19101910+ struct return_instance *ri)21231911{21242124- struct return_instance *ri;21252125- struct uprobe_task *utask;19121912+ struct uprobe_task *utask = current->utask;21261913 unsigned long orig_ret_vaddr, trampoline_vaddr;21271914 bool chained;19151915+ int srcu_idx;2128191621291917 if (!get_xol_area())21302130- return;21312131-21322132- utask = get_utask();21332133- if (!utask)21342134- return;19181918+ goto free;2135191921361920 if (utask->depth >= MAX_URETPROBE_DEPTH) {21371921 printk_ratelimited(KERN_INFO "uprobe: omit uretprobe due to"21381922 " nestedness limit pid/tgid=%d/%d\n",21391923 current->pid, current->tgid);21402140- return;19241924+ goto free;21411925 }21422142-21432143- /* we need to bump refcount to store uprobe in utask */21442144- if (!try_get_uprobe(uprobe))21452145- return;21462146-21472147- ri = kmalloc(sizeof(struct return_instance), GFP_KERNEL);21482148- if (!ri)21492149- goto fail;2150192621511927 trampoline_vaddr = uprobe_get_trampoline_vaddr();21521928 orig_ret_vaddr = arch_uretprobe_hijack_return_addr(trampoline_vaddr, regs);21531929 if (orig_ret_vaddr == -1)21542154- goto fail;19301930+ goto free;2155193121561932 /* drop the entries invalidated by longjmp() */21571933 chained = (orig_ret_vaddr == trampoline_vaddr);···21581956 * attack from user-space.21591957 */21601958 uprobe_warn(current, "handle tail call");21612161- goto fail;19591959+ goto free;21621960 }21631961 orig_ret_vaddr = utask->return_instances->orig_ret_vaddr;21641962 }21652165- ri->uprobe = uprobe;19631963+19641964+ /* __srcu_read_lock() because SRCU lock survives switch to user space */19651965+ srcu_idx = __srcu_read_lock(&uretprobes_srcu);19661966+21661967 ri->func = instruction_pointer(regs);21671968 ri->stack = user_stack_pointer(regs);21681969 ri->orig_ret_vaddr = orig_ret_vaddr;21691970 ri->chained = chained;2170197121711972 utask->depth++;19731973+19741974+ hprobe_init_leased(&ri->hprobe, uprobe, srcu_idx);21721975 ri->next = utask->return_instances;21732173- utask->return_instances = ri;19761976+ rcu_assign_pointer(utask->return_instances, ri);19771977+19781978+ mod_timer(&utask->ri_timer, jiffies + RI_TIMER_PERIOD);2174197921751980 return;21762176-fail:19811981+free:21771982 kfree(ri);21782178- put_uprobe(uprobe);21791983}2180198421811985/* Prepare to single-step probed instruction out of line. */21821986static int21831987pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long bp_vaddr)21841988{21852185- struct uprobe_task *utask;21862186- unsigned long xol_vaddr;19891989+ struct uprobe_task *utask = current->utask;21871990 int err;21882188-21892189- utask = get_utask();21902190- if (!utask)21912191- return -ENOMEM;2192199121931992 if (!try_get_uprobe(uprobe))21941993 return -EINVAL;2195199421962196- xol_vaddr = xol_get_insn_slot(uprobe);21972197- if (!xol_vaddr) {19951995+ if (!xol_get_insn_slot(uprobe, utask)) {21981996 err = -ENOMEM;21991997 goto err_out;22001998 }2201199922022202- utask->xol_vaddr = xol_vaddr;22032000 utask->vaddr = bp_vaddr;22042204-22052001 err = arch_uprobe_pre_xol(&uprobe->arch, regs);22062002 if (unlikely(err)) {22072207- xol_free_insn_slot(current);20032003+ xol_free_insn_slot(utask);22082004 goto err_out;22092005 }22102006···23252125 return uprobe;23262126}2327212721282128+static struct return_instance*21292129+push_consumer(struct return_instance *ri, int idx, __u64 id, __u64 cookie)21302130+{21312131+ if (unlikely(ri == ZERO_SIZE_PTR))21322132+ return ri;21332133+21342134+ if (unlikely(idx >= ri->consumers_cnt)) {21352135+ struct return_instance *old_ri = ri;21362136+21372137+ ri->consumers_cnt += DEF_CNT;21382138+ ri = krealloc(old_ri, ri_size(old_ri->consumers_cnt), GFP_KERNEL);21392139+ if (!ri) {21402140+ kfree(old_ri);21412141+ return ZERO_SIZE_PTR;21422142+ }21432143+ }21442144+21452145+ ri->consumers[idx].id = id;21462146+ ri->consumers[idx].cookie = cookie;21472147+ return ri;21482148+}21492149+21502150+static struct return_consumer *21512151+return_consumer_find(struct return_instance *ri, int *iter, int id)21522152+{21532153+ struct return_consumer *ric;21542154+ int idx = *iter;21552155+21562156+ for (ric = &ri->consumers[idx]; idx < ri->consumers_cnt; idx++, ric++) {21572157+ if (ric->id == id) {21582158+ *iter = idx + 1;21592159+ return ric;21602160+ }21612161+ }21622162+ return NULL;21632163+}21642164+21652165+static bool ignore_ret_handler(int rc)21662166+{21672167+ return rc == UPROBE_HANDLER_REMOVE || rc == UPROBE_HANDLER_IGNORE;21682168+}21692169+23282170static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)23292171{23302172 struct uprobe_consumer *uc;23312331- int remove = UPROBE_HANDLER_REMOVE;23322332- bool need_prep = false; /* prepare return uprobe, when needed */23332333- bool has_consumers = false;21732173+ bool has_consumers = false, remove = true;21742174+ struct return_instance *ri = NULL;21752175+ int push_idx = 0;2334217623352177 current->utask->auprobe = &uprobe->arch;2336217823372337- list_for_each_entry_srcu(uc, &uprobe->consumers, cons_node,23382338- srcu_read_lock_held(&uprobes_srcu)) {21792179+ list_for_each_entry_rcu(uc, &uprobe->consumers, cons_node, rcu_read_lock_trace_held()) {21802180+ bool session = uc->handler && uc->ret_handler;21812181+ __u64 cookie = 0;23392182 int rc = 0;2340218323412184 if (uc->handler) {23422342- rc = uc->handler(uc, regs);23432343- WARN(rc & ~UPROBE_HANDLER_MASK,21852185+ rc = uc->handler(uc, regs, &cookie);21862186+ WARN(rc < 0 || rc > 2,23442187 "bad rc=0x%x from %ps()\n", rc, uc->handler);23452188 }2346218923472347- if (uc->ret_handler)23482348- need_prep = true;23492349-23502350- remove &= rc;21902190+ remove &= rc == UPROBE_HANDLER_REMOVE;23512191 has_consumers = true;21922192+21932193+ if (!uc->ret_handler || ignore_ret_handler(rc))21942194+ continue;21952195+21962196+ if (!ri)21972197+ ri = alloc_return_instance();21982198+21992199+ if (session)22002200+ ri = push_consumer(ri, push_idx++, uc->id, cookie);23522201 }23532202 current->utask->auprobe = NULL;2354220323552355- if (need_prep && !remove)23562356- prepare_uretprobe(uprobe, regs); /* put bp at return */22042204+ if (!ZERO_OR_NULL_PTR(ri)) {22052205+ /*22062206+ * The push_idx value has the final number of return consumers,22072207+ * and ri->consumers_cnt has number of allocated consumers.22082208+ */22092209+ ri->consumers_cnt = push_idx;22102210+ prepare_uretprobe(uprobe, regs, ri);22112211+ }2357221223582213 if (remove && has_consumers) {23592214 down_read(&uprobe->register_rwsem);···24242169}2425217024262171static void24272427-handle_uretprobe_chain(struct return_instance *ri, struct pt_regs *regs)21722172+handle_uretprobe_chain(struct return_instance *ri, struct uprobe *uprobe, struct pt_regs *regs)24282173{24292429- struct uprobe *uprobe = ri->uprobe;21742174+ struct return_consumer *ric;24302175 struct uprobe_consumer *uc;24312431- int srcu_idx;21762176+ int ric_idx = 0;2432217724332433- srcu_idx = srcu_read_lock(&uprobes_srcu);24342434- list_for_each_entry_srcu(uc, &uprobe->consumers, cons_node,24352435- srcu_read_lock_held(&uprobes_srcu)) {24362436- if (uc->ret_handler)24372437- uc->ret_handler(uc, ri->func, regs);21782178+ /* all consumers unsubscribed meanwhile */21792179+ if (unlikely(!uprobe))21802180+ return;21812181+21822182+ rcu_read_lock_trace();21832183+ list_for_each_entry_rcu(uc, &uprobe->consumers, cons_node, rcu_read_lock_trace_held()) {21842184+ bool session = uc->handler && uc->ret_handler;21852185+21862186+ if (uc->ret_handler) {21872187+ ric = return_consumer_find(ri, &ric_idx, uc->id);21882188+ if (!session || ric)21892189+ uc->ret_handler(uc, ri->func, regs, ric ? &ric->cookie : NULL);21902190+ }24382191 }24392439- srcu_read_unlock(&uprobes_srcu, srcu_idx);21922192+ rcu_read_unlock_trace();24402193}2441219424422195static struct return_instance *find_next_ret_chain(struct return_instance *ri)···24632200{24642201 struct uprobe_task *utask;24652202 struct return_instance *ri, *next;22032203+ struct uprobe *uprobe;22042204+ enum hprobe_state hstate;24662205 bool valid;2467220624682207 utask = current->utask;···24952230 * trampoline addresses on the stack are replaced with correct24962231 * original return addresses24972232 */24982498- utask->return_instances = ri->next;22332233+ rcu_assign_pointer(utask->return_instances, ri->next);22342234+22352235+ uprobe = hprobe_consume(&ri->hprobe, &hstate);24992236 if (valid)25002500- handle_uretprobe_chain(ri, regs);25012501- ri = free_ret_instance(ri);22372237+ handle_uretprobe_chain(ri, uprobe, regs);22382238+ hprobe_finalize(&ri->hprobe, hstate);22392239+22402240+ /* We already took care of hprobe, no need to waste more time on that. */22412241+ ri = free_ret_instance(ri, false /* !cleanup_hprobe */);25022242 utask->depth--;25032243 } while (ri != next);25042244 } while (!valid);2505224525062506- utask->return_instances = ri;25072246 return;2508224725092509- sigill:22482248+sigill:25102249 uprobe_warn(current, "handle uretprobe, sending SIGILL.");25112250 force_sig(SIGILL);25122512-25132251}2514225225152253bool __weak arch_uprobe_ignore(struct arch_uprobe *aup, struct pt_regs *regs)···25342266{25352267 struct uprobe *uprobe;25362268 unsigned long bp_vaddr;25372537- int is_swbp, srcu_idx;22692269+ int is_swbp;2538227025392271 bp_vaddr = uprobe_get_swbp_addr(regs);25402272 if (bp_vaddr == uprobe_get_trampoline_vaddr())25412273 return uprobe_handle_trampoline(regs);2542227425432543- srcu_idx = srcu_read_lock(&uprobes_srcu);22752275+ rcu_read_lock_trace();2544227625452277 uprobe = find_active_uprobe_rcu(bp_vaddr, &is_swbp);25462278 if (!uprobe) {···2598233025992331out:26002332 /* arch_uprobe_skip_sstep() succeeded, or restart if can't singlestep */26012601- srcu_read_unlock(&uprobes_srcu, srcu_idx);23332333+ rcu_read_unlock_trace();26022334}2603233526042336/*···26212353 put_uprobe(uprobe);26222354 utask->active_uprobe = NULL;26232355 utask->state = UTASK_RUNNING;26242624- xol_free_insn_slot(current);23562356+ xol_free_insn_slot(utask);2625235726262358 spin_lock_irq(¤t->sighand->siglock);26272359 recalc_sigpending(); /* see uprobe_deny_signal() */