git: 5387495773e9 - main - hwpmc: simplify arm64 kernel stack unwinding
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 06 May 2023 17:49:45 UTC
The branch main has been updated by mhorne:
URL: https://cgit.FreeBSD.org/src/commit/?id=5387495773e9e92441b795c0eb8c2a3ecc25708a
commit 5387495773e9e92441b795c0eb8c2a3ecc25708a
Author: Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2023-05-05 21:58:40 +0000
Commit: Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2023-05-06 17:49:19 +0000
hwpmc: simplify arm64 kernel stack unwinding
Use the unwind_frame() function, which properly validates the frame
pointer and uses ADDR_MAKE_CANONICAL() for the pc, required when PAC is
enabled.
Reviewed by: andrew, markj, jkoshy
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D39934
---
sys/dev/hwpmc/hwpmc_arm64_md.c | 31 ++++++++++---------------------
1 file changed, 10 insertions(+), 21 deletions(-)
diff --git a/sys/dev/hwpmc/hwpmc_arm64_md.c b/sys/dev/hwpmc/hwpmc_arm64_md.c
index 59d33ef34d06..dd51f7bd18d5 100644
--- a/sys/dev/hwpmc/hwpmc_arm64_md.c
+++ b/sys/dev/hwpmc/hwpmc_arm64_md.c
@@ -62,7 +62,8 @@ int
pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples,
struct trapframe *tf)
{
- uintptr_t pc, r, stackstart, stackend, fp;
+ struct unwind_state frame;
+ uintptr_t stackstart, stackend;
struct thread *td;
int count;
@@ -70,38 +71,26 @@ pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples,
__LINE__));
td = curthread;
- pc = PMC_TRAPFRAME_TO_PC(tf);
- *cc++ = pc;
+ frame.pc = PMC_TRAPFRAME_TO_PC(tf);
+ *cc++ = frame.pc;
if (maxsamples <= 1)
return (1);
stackstart = (uintptr_t) td->td_kstack;
stackend = (uintptr_t) td->td_kstack + td->td_kstack_pages * PAGE_SIZE;
- fp = PMC_TRAPFRAME_TO_FP(tf);
+ frame.fp = PMC_TRAPFRAME_TO_FP(tf);
- if (!PMC_IN_KERNEL(pc) ||
- !PMC_IN_KERNEL_STACK(fp, stackstart, stackend))
+ if (!PMC_IN_KERNEL(frame.pc) ||
+ !PMC_IN_KERNEL_STACK(frame.fp, stackstart, stackend))
return (1);
for (count = 1; count < maxsamples; count++) {
- /* Use saved lr as pc. */
- r = fp + sizeof(uintptr_t);
- if (!PMC_IN_KERNEL_STACK(r, stackstart, stackend))
- break;
- pc = *(uintptr_t *)r;
- if (!PMC_IN_KERNEL(pc))
- break;
-
- *cc++ = pc;
-
- /* Switch to next frame up */
- r = fp;
- if (!PMC_IN_KERNEL_STACK(r, stackstart, stackend))
+ if (!unwind_frame(curthread, &frame))
break;
- fp = *(uintptr_t *)r;
- if (!PMC_IN_KERNEL_STACK(fp, stackstart, stackend))
+ if (!PMC_IN_KERNEL(frame.pc))
break;
+ *cc++ = frame.pc;
}
return (count);