.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
---|
1 | 2 | /* |
---|
2 | 3 | * Performance events callchain code, extracted from core.c: |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * Copyright (C) 2008-2011 Red Hat, Inc., Ingo Molnar |
---|
6 | 7 | * Copyright (C) 2008-2011 Red Hat, Inc., Peter Zijlstra |
---|
7 | 8 | * Copyright © 2009 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com> |
---|
8 | | - * |
---|
9 | | - * For licensing details see kernel-base/COPYING |
---|
10 | 9 | */ |
---|
11 | 10 | |
---|
12 | 11 | #include <linux/perf_event.h> |
---|
.. | .. |
---|
17 | 16 | |
---|
18 | 17 | struct callchain_cpus_entries { |
---|
19 | 18 | struct rcu_head rcu_head; |
---|
20 | | - struct perf_callchain_entry *cpu_entries[0]; |
---|
| 19 | + struct perf_callchain_entry *cpu_entries[]; |
---|
21 | 20 | }; |
---|
22 | 21 | |
---|
23 | 22 | int sysctl_perf_event_max_stack __read_mostly = PERF_MAX_STACK_DEPTH; |
---|
.. | .. |
---|
150 | 149 | } |
---|
151 | 150 | } |
---|
152 | 151 | |
---|
153 | | -static struct perf_callchain_entry *get_callchain_entry(int *rctx) |
---|
| 152 | +struct perf_callchain_entry *get_callchain_entry(int *rctx) |
---|
154 | 153 | { |
---|
155 | 154 | int cpu; |
---|
156 | 155 | struct callchain_cpus_entries *entries; |
---|
.. | .. |
---|
160 | 159 | return NULL; |
---|
161 | 160 | |
---|
162 | 161 | entries = rcu_dereference(callchain_cpus_entries); |
---|
163 | | - if (!entries) |
---|
| 162 | + if (!entries) { |
---|
| 163 | + put_recursion_context(this_cpu_ptr(callchain_recursion), *rctx); |
---|
164 | 164 | return NULL; |
---|
| 165 | + } |
---|
165 | 166 | |
---|
166 | 167 | cpu = smp_processor_id(); |
---|
167 | 168 | |
---|
.. | .. |
---|
169 | 170 | (*rctx * perf_callchain_entry__sizeof())); |
---|
170 | 171 | } |
---|
171 | 172 | |
---|
172 | | -static void |
---|
| 173 | +void |
---|
173 | 174 | put_callchain_entry(int rctx) |
---|
174 | 175 | { |
---|
175 | 176 | put_recursion_context(this_cpu_ptr(callchain_recursion), rctx); |
---|
.. | .. |
---|
184 | 185 | int rctx; |
---|
185 | 186 | |
---|
186 | 187 | entry = get_callchain_entry(&rctx); |
---|
187 | | - if (rctx == -1) |
---|
188 | | - return NULL; |
---|
189 | | - |
---|
190 | 188 | if (!entry) |
---|
191 | | - goto exit_put; |
---|
| 189 | + return NULL; |
---|
192 | 190 | |
---|
193 | 191 | ctx.entry = entry; |
---|
194 | 192 | ctx.max_stack = max_stack; |
---|
.. | .. |
---|
219 | 217 | if (add_mark) |
---|
220 | 218 | perf_callchain_store_context(&ctx, PERF_CONTEXT_USER); |
---|
221 | 219 | |
---|
222 | | - fs = get_fs(); |
---|
223 | | - set_fs(USER_DS); |
---|
| 220 | + fs = force_uaccess_begin(); |
---|
224 | 221 | perf_callchain_user(&ctx, regs); |
---|
225 | | - set_fs(fs); |
---|
| 222 | + force_uaccess_end(fs); |
---|
226 | 223 | } |
---|
227 | 224 | } |
---|
228 | 225 | |
---|
.. | .. |
---|
237 | 234 | * sysctl_perf_event_max_contexts_per_stack. |
---|
238 | 235 | */ |
---|
239 | 236 | int perf_event_max_stack_handler(struct ctl_table *table, int write, |
---|
240 | | - void __user *buffer, size_t *lenp, loff_t *ppos) |
---|
| 237 | + void *buffer, size_t *lenp, loff_t *ppos) |
---|
241 | 238 | { |
---|
242 | 239 | int *value = table->data; |
---|
243 | 240 | int new_value = *value, ret; |
---|