svn commit: r268207 - head/sys/dev/hwpmc
Justin Hibbits
jhibbits at FreeBSD.org
Thu Jul 3 06:52:27 UTC 2014
Author: jhibbits
Date: Thu Jul 3 06:52:26 2014
New Revision: 268207
URL: http://svnweb.freebsd.org/changeset/base/268207
Log:
Fix a bug in hwpmc(4) callchain retrieval, for both user and kernel.
The array index for the callchain is getting double-incremented -- both in the
loop and the storing. It should only be incremented in one location.
Also, constrain the stack pointer range check.
MFC after: 2 weeks
Modified:
head/sys/dev/hwpmc/hwpmc_powerpc.c
Modified: head/sys/dev/hwpmc/hwpmc_powerpc.c
==============================================================================
--- head/sys/dev/hwpmc/hwpmc_powerpc.c Thu Jul 3 06:44:55 2014 (r268206)
+++ head/sys/dev/hwpmc/hwpmc_powerpc.c Thu Jul 3 06:52:26 2014 (r268207)
@@ -55,20 +55,22 @@ int
pmc_save_kernel_callchain(uintptr_t *cc, int maxsamples,
struct trapframe *tf)
{
+ uintptr_t *osp, *sp;
int frames = 0;
- uintptr_t *sp;
cc[frames++] = PMC_TRAPFRAME_TO_PC(tf);
sp = (uintptr_t *)PMC_TRAPFRAME_TO_FP(tf);
+ osp = NULL;
for (; frames < maxsamples; frames++) {
- if (!INKERNEL(sp))
+ if (!INKERNEL(sp) || sp <= osp)
break;
#ifdef __powerpc64__
- cc[frames++] = sp[2];
+ cc[frames] = sp[2];
#else
- cc[frames++] = sp[1];
+ cc[frames] = sp[1];
#endif
+ osp = sp;
sp = (uintptr_t *)*sp;
}
return (frames);
@@ -184,26 +186,28 @@ int
pmc_save_user_callchain(uintptr_t *cc, int maxsamples,
struct trapframe *tf)
{
- uintptr_t *sp;
+ uintptr_t *osp, *sp;
int frames = 0;
cc[frames++] = PMC_TRAPFRAME_TO_PC(tf);
sp = (uintptr_t *)PMC_TRAPFRAME_TO_FP(tf);
+ osp = NULL;
for (; frames < maxsamples; frames++) {
- if (!INUSER(sp))
+ if (!INUSER(sp) || sp <= osp)
break;
+ osp = sp;
#ifdef __powerpc64__
/* Check if 32-bit mode. */
if (!(tf->srr1 & PSL_SF)) {
- cc[frames++] = fuword32((uint32_t *)sp + 1);
+ cc[frames] = fuword32((uint32_t *)sp + 1);
sp = (uintptr_t *)(uintptr_t)fuword32(sp);
} else {
- cc[frames++] = fuword(sp + 2);
+ cc[frames] = fuword(sp + 2);
sp = (uintptr_t *)fuword(sp);
}
#else
- cc[frames++] = fuword32((uint32_t *)sp + 1);
+ cc[frames] = fuword32((uint32_t *)sp + 1);
sp = (uintptr_t *)fuword32(sp);
#endif
}
More information about the svn-src-all
mailing list