diff options
-rw-r--r-- | arch/s390/kernel/perf_event.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index cfcba2dd9bb5..0943b11a2f6e 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c | |||
@@ -260,12 +260,13 @@ static unsigned long __store_trace(struct perf_callchain_entry *entry, | |||
260 | void perf_callchain_kernel(struct perf_callchain_entry *entry, | 260 | void perf_callchain_kernel(struct perf_callchain_entry *entry, |
261 | struct pt_regs *regs) | 261 | struct pt_regs *regs) |
262 | { | 262 | { |
263 | unsigned long head; | 263 | unsigned long head, frame_size; |
264 | struct stack_frame *head_sf; | 264 | struct stack_frame *head_sf; |
265 | 265 | ||
266 | if (user_mode(regs)) | 266 | if (user_mode(regs)) |
267 | return; | 267 | return; |
268 | 268 | ||
269 | frame_size = STACK_FRAME_OVERHEAD + sizeof(struct pt_regs); | ||
269 | head = regs->gprs[15]; | 270 | head = regs->gprs[15]; |
270 | head_sf = (struct stack_frame *) head; | 271 | head_sf = (struct stack_frame *) head; |
271 | 272 | ||
@@ -273,8 +274,9 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, | |||
273 | return; | 274 | return; |
274 | 275 | ||
275 | head = head_sf->back_chain; | 276 | head = head_sf->back_chain; |
276 | head = __store_trace(entry, head, S390_lowcore.async_stack - ASYNC_SIZE, | 277 | head = __store_trace(entry, head, |
277 | S390_lowcore.async_stack); | 278 | S390_lowcore.async_stack + frame_size - ASYNC_SIZE, |
279 | S390_lowcore.async_stack + frame_size); | ||
278 | 280 | ||
279 | __store_trace(entry, head, S390_lowcore.thread_info, | 281 | __store_trace(entry, head, S390_lowcore.thread_info, |
280 | S390_lowcore.thread_info + THREAD_SIZE); | 282 | S390_lowcore.thread_info + THREAD_SIZE); |