git: 6b5db9d3af04 - stable/13 - hwpmc: simplify arm64 kernel stack unwinding
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 09 Jun 2023 19:58:08 UTC
The branch stable/13 has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=6b5db9d3af0497e4538d6fd43df2596172867568 commit 6b5db9d3af0497e4538d6fd43df2596172867568 Author: Mitchell Horne <mhorne@FreeBSD.org> AuthorDate: 2023-05-05 21:58:40 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2023-06-09 18:14:59 +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 (cherry picked from commit 5387495773e9e92441b795c0eb8c2a3ecc25708a) --- 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 015bee227f89..996c91eea592 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);