From a9cbfb55cdc6f2ac0c38c5c9877fafbaad0c70ee Mon Sep 17 00:00:00 2001 From: jkoshy Date: Mon, 15 Sep 2008 06:47:52 +0000 Subject: Correct a callchain capture bug on the i386. On the i386 architecture, the processor only saves the current value of `%esp' on stack if a privilege switch is necessary when entering the interrupt handler. Thus, `frame->tf_esp' is only valid for an entry from user mode. For interrupts taken in kernel mode, we need to determine the top-of-stack for the interrupted kernel procedure by adding the appropriate offset to the current frame pointer. Reported by: kris, Fabien Thomas Tested by: Fabien Thomas --- sys/dev/hwpmc/hwpmc_x86.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sys/dev/hwpmc') diff --git a/sys/dev/hwpmc/hwpmc_x86.c b/sys/dev/hwpmc/hwpmc_x86.c index 2fc7cd9..8720c0e 100644 --- a/sys/dev/hwpmc/hwpmc_x86.c +++ b/sys/dev/hwpmc/hwpmc_x86.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2005, Joseph Koshy + * Copyright (c) 2005,2008 Joseph Koshy * Copyright (c) 2007 The FreeBSD Foundation * All rights reserved. * @@ -90,7 +90,7 @@ pmc_save_user_callchain(uintptr_t *cc, int nframes, struct trapframe *tf) pc = PMC_TRAPFRAME_TO_PC(tf); oldfp = fp = PMC_TRAPFRAME_TO_FP(tf); - sp = PMC_TRAPFRAME_TO_SP(tf); + sp = PMC_TRAPFRAME_TO_USER_SP(tf); *cc++ = pc; n = 1; @@ -171,7 +171,7 @@ pmc_save_kernel_callchain(uintptr_t *cc, int nframes, struct trapframe *tf) pc = PMC_TRAPFRAME_TO_PC(tf); fp = PMC_TRAPFRAME_TO_FP(tf); - sp = PMC_TRAPFRAME_TO_SP(tf); + sp = PMC_TRAPFRAME_TO_KERNEL_SP(tf); *cc++ = pc; r = fp + sizeof(uintptr_t); /* points to return address */ -- cgit v1.1