diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/include/pmc_mdep.h | 5 | ||||
-rw-r--r-- | sys/dev/hwpmc/hwpmc_x86.c | 6 | ||||
-rw-r--r-- | sys/i386/include/pmc_mdep.h | 22 |
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)) |