aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/kernel/perf_event.c8
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,
260void perf_callchain_kernel(struct perf_callchain_entry *entry, 260void 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);