Date: Sun, 14 Sep 2014 22:03:41 +0000 (UTC) From: Justin Hibbits <jhibbits@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r271602 - head/sys/dev/hwpmc Message-ID: <201409142203.s8EM3fo5060209@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhibbits Date: Sun Sep 14 22:03:41 2014 New Revision: 271602 URL: http://svnweb.freebsd.org/changeset/base/271602 Log: Fix PowerPC backtraces. Since kernel and user have completely separate address spaces, rather than a split address, we actually can't check for being within the kernel's address range. Instead, do what other backtraces do, and use trapexit()/asttrapexit() as the stack sentinel. MFC after: 3 weeks Modified: head/sys/dev/hwpmc/hwpmc_powerpc.c Modified: head/sys/dev/hwpmc/hwpmc_powerpc.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_powerpc.c Sun Sep 14 21:21:03 2014 (r271601) +++ head/sys/dev/hwpmc/hwpmc_powerpc.c Sun Sep 14 22:03:41 2014 (r271602) @@ -40,14 +40,15 @@ __FBSDID("$FreeBSD$"); #include <machine/pte.h> #include <machine/sr.h> #include <machine/cpu.h> -#include <machine/vmparam.h> /* For VM_MIN_KERNEL_ADDRESS/VM_MAX_KERNEL_ADDRESS */ +#include <machine/stack.h> #include "hwpmc_powerpc.h" -#define INKERNEL(x) (((vm_offset_t)(x)) <= VM_MAX_KERNEL_ADDRESS && \ - ((vm_offset_t)(x)) >= VM_MIN_KERNEL_ADDRESS) -#define INUSER(x) (((vm_offset_t)(x)) <= VM_MAXUSER_ADDRESS && \ - ((vm_offset_t)(x)) >= VM_MIN_ADDRESS) +#ifdef __powerpc64__ +#define OFFSET 4 /* Account for the TOC reload slot */ +#else +#define OFFSET 0 +#endif struct powerpc_cpu **powerpc_pcpu; @@ -56,20 +57,33 @@ pmc_save_kernel_callchain(uintptr_t *cc, struct trapframe *tf) { uintptr_t *osp, *sp; + uintptr_t pc; int frames = 0; cc[frames++] = PMC_TRAPFRAME_TO_PC(tf); sp = (uintptr_t *)PMC_TRAPFRAME_TO_FP(tf); - osp = NULL; + osp = (uintptr_t *)PAGE_SIZE; for (; frames < maxsamples; frames++) { - if (!INKERNEL(sp) || sp <= osp) + if (sp <= osp) break; -#ifdef __powerpc64__ - cc[frames] = sp[2]; -#else - cc[frames] = sp[1]; -#endif + #ifdef __powerpc64__ + pc = sp[2]; + #else + pc = sp[1]; + #endif + if ((pc & 3) || (pc < 0x100)) + break; + + /* + * trapexit() and asttrapexit() are sentinels + * for kernel stack tracing. + * */ + if (pc + OFFSET == (uintptr_t) &trapexit || + pc + OFFSET == (uintptr_t) &asttrapexit) + break; + + cc[frames] = pc; osp = sp; sp = (uintptr_t *)*sp; } @@ -194,7 +208,7 @@ pmc_save_user_callchain(uintptr_t *cc, i osp = NULL; for (; frames < maxsamples; frames++) { - if (!INUSER(sp) || sp <= osp) + if (sp <= osp) break; osp = sp; #ifdef __powerpc64__
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409142203.s8EM3fo5060209>