]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
perf/amd/ibs: Use interrupt regs ip for stack unwinding
authorRavi Bangoria <ravi.bangoria@amd.com>
Fri, 29 Apr 2022 05:14:41 +0000 (10:44 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jun 2022 14:59:22 +0000 (16:59 +0200)
[ Upstream commit 3d47083b9ff46863e8374ad3bb5edb5e464c75f8 ]

IbsOpRip is recorded when IBS interrupt is triggered. But there is
a skid from the time IBS interrupt gets triggered to the time the
interrupt is presented to the core. Meanwhile processor would have
moved ahead and thus IbsOpRip will be inconsistent with rsp and rbp
recorded as part of the interrupt regs. This causes issues while
unwinding stack using the ORC unwinder as it needs consistent rip,
rsp and rbp. Fix this by using rip from interrupt regs instead of
IbsOpRip for stack unwinding.

Fixes: ee9f8fce99640 ("x86/unwind: Add the ORC unwinder")
Reported-by: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru>
Suggested-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Ravi Bangoria <ravi.bangoria@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20220429051441.14251-1-ravi.bangoria@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/x86/events/amd/ibs.c

index 2d9e1372b070c9c1f222a1c0b714ce1e56343cca..d157d0adef06e6601a0ae4fd6329cbe878ad0d5f 100644 (file)
@@ -324,6 +324,16 @@ static int perf_ibs_init(struct perf_event *event)
        hwc->config_base = perf_ibs->msr;
        hwc->config = config;
 
+       /*
+        * rip recorded by IbsOpRip will not be consistent with rsp and rbp
+        * recorded as part of interrupt regs. Thus we need to use rip from
+        * interrupt regs while unwinding call stack. Setting _EARLY flag
+        * makes sure we unwind call-stack before perf sample rip is set to
+        * IbsOpRip.
+        */
+       if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)
+               event->attr.sample_type |= __PERF_SAMPLE_CALLCHAIN_EARLY;
+
        return 0;
 }
 
@@ -693,6 +703,14 @@ fail:
                data.raw = &raw;
        }
 
+       /*
+        * rip recorded by IbsOpRip will not be consistent with rsp and rbp
+        * recorded as part of interrupt regs. Thus we need to use rip from
+        * interrupt regs while unwinding call stack.
+        */
+       if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)
+               data.callchain = perf_callchain(event, iregs);
+
        throttle = perf_event_overflow(event, &data, &regs);
 out:
        if (throttle) {