.. | .. |
---|
21 | 21 | #include <asm/lowcore.h> |
---|
22 | 22 | #include <asm/processor.h> |
---|
23 | 23 | #include <asm/sysinfo.h> |
---|
| 24 | +#include <asm/unwind.h> |
---|
24 | 25 | |
---|
25 | 26 | const char *perf_pmu_name(void) |
---|
26 | 27 | { |
---|
.. | .. |
---|
50 | 51 | if (!stack) |
---|
51 | 52 | return NULL; |
---|
52 | 53 | |
---|
53 | | - return (struct kvm_s390_sie_block *) stack->empty1[0]; |
---|
| 54 | + return (struct kvm_s390_sie_block *)stack->empty1[1]; |
---|
54 | 55 | } |
---|
55 | 56 | |
---|
56 | 57 | static bool is_in_guest(struct pt_regs *regs) |
---|
.. | .. |
---|
219 | 220 | } |
---|
220 | 221 | arch_initcall(service_level_perf_register); |
---|
221 | 222 | |
---|
222 | | -static int __perf_callchain_kernel(void *data, unsigned long address, int reliable) |
---|
223 | | -{ |
---|
224 | | - struct perf_callchain_entry_ctx *entry = data; |
---|
225 | | - |
---|
226 | | - perf_callchain_store(entry, address); |
---|
227 | | - return 0; |
---|
228 | | -} |
---|
229 | | - |
---|
230 | 223 | void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, |
---|
231 | 224 | struct pt_regs *regs) |
---|
232 | 225 | { |
---|
233 | | - if (user_mode(regs)) |
---|
234 | | - return; |
---|
235 | | - dump_trace(__perf_callchain_kernel, entry, NULL, regs->gprs[15]); |
---|
| 226 | + struct unwind_state state; |
---|
| 227 | + unsigned long addr; |
---|
| 228 | + |
---|
| 229 | + unwind_for_each_frame(&state, current, regs, 0) { |
---|
| 230 | + addr = unwind_get_return_address(&state); |
---|
| 231 | + if (!addr || perf_callchain_store(entry, addr)) |
---|
| 232 | + return; |
---|
| 233 | + } |
---|
236 | 234 | } |
---|
237 | 235 | |
---|
238 | 236 | /* Perf definitions for PMU event attributes in sysfs */ |
---|