summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/include/pmc_mdep.h5
-rw-r--r--sys/dev/hwpmc/hwpmc_x86.c6
-rw-r--r--sys/i386/include/pmc_mdep.h22
3 files changed, 26 insertions, 7 deletions
diff --git a/sys/amd64/include/pmc_mdep.h b/sys/amd64/include/pmc_mdep.h
index 258d6aa..a11a82a 100644
--- a/sys/amd64/include/pmc_mdep.h
+++ b/sys/amd64/include/pmc_mdep.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2007 Joseph Koshy
+ * Copyright (c) 2003-2008 Joseph Koshy
* Copyright (c) 2007 The FreeBSD Foundation
* All rights reserved.
*
@@ -59,7 +59,8 @@ struct pmc;
#define PMC_TRAPFRAME_TO_PC(TF) ((TF)->tf_rip)
#define PMC_TRAPFRAME_TO_FP(TF) ((TF)->tf_rbp)
-#define PMC_TRAPFRAME_TO_SP(TF) ((TF)->tf_rsp)
+#define PMC_TRAPFRAME_TO_USER_SP(TF) ((TF)->tf_rsp)
+#define PMC_TRAPFRAME_TO_KERNEL_SP(TF) ((TF)->tf_rsp)
#define PMC_AT_FUNCTION_PROLOGUE_PUSH_BP(I) \
(((I) & 0xffffffff) == 0xe5894855) /* pushq %rbp; movq %rsp,%rbp */
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 */
diff --git a/sys/i386/include/pmc_mdep.h b/sys/i386/include/pmc_mdep.h
index 7ec1f4b..de0688a 100644
--- a/sys/i386/include/pmc_mdep.h
+++ b/sys/i386/include/pmc_mdep.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2003-2005 Joseph Koshy
+ * Copyright (c) 2003-2005,2008 Joseph Koshy
* Copyright (c) 2007 The FreeBSD Foundation
* All rights reserved.
*
@@ -79,7 +79,25 @@ struct pmc;
#define PMC_TRAPFRAME_TO_PC(TF) ((TF)->tf_eip)
#define PMC_TRAPFRAME_TO_FP(TF) ((TF)->tf_ebp)
-#define PMC_TRAPFRAME_TO_SP(TF) ((TF)->tf_esp)
+
+/*
+ * The layout of the stack frame on entry into the NMI handler depends on
+ * whether a privilege level change (and consequent stack switch) was
+ * required for entry.
+ *
+ * When processing an interrupt when in user mode, the processor switches
+ * stacks, and saves the user mode stack pointer on the kernel stack. The
+ * user mode stack pointer is then available to the interrupt handler
+ * at frame->tf_esp.
+ *
+ * When processing an interrupt while in kernel mode, the processor
+ * continues to use the existing (kernel) stack. Therefore we determine
+ * the stack pointer for the interrupted kernel procedure by adding an
+ * offset to the current frame pointer.
+ */
+
+#define PMC_TRAPFRAME_TO_USER_SP(TF) ((TF)->tf_esp)
+#define PMC_TRAPFRAME_TO_KERNEL_SP(TF) ((uintptr_t) &((TF)->tf_esp))
#define PMC_IN_KERNEL_STACK(S,START,END) \
((S) >= (START) && (S) < (END))
OpenPOWER on IntegriCloud