The branch stable/13 has been updated by mhorne:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=6b5db9d3af0497e4538d6fd43df2596172867568

commit 6b5db9d3af0497e4538d6fd43df2596172867568
Author:     Mitchell Horne <[email protected]>
AuthorDate: 2023-05-05 21:58:40 +0000
Commit:     Mitchell Horne <[email protected]>
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);

Reply via email to