| .. | .. |
|---|
| 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 */ |
|---|