diff options
author | Paul Mackerras <paulus@samba.org> | 2007-07-11 13:28:26 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-07-11 13:28:26 +1000 |
commit | bf22f6fe2d72b4d7e9035be8ceb340414cf490e3 (patch) | |
tree | 14085d90de0428316479fe6de8a0c6d32e6e65e2 /arch/powerpc/oprofile/op_model_power4.c | |
parent | 4eb6bf6bfb580afaf1e1a1d30cba17a078530cf4 (diff) | |
parent | 93ab471889c6662b42ce7da257f31f24c08d7d9e (diff) |
Merge branch 'for-2.6.23' into merge
Diffstat (limited to 'arch/powerpc/oprofile/op_model_power4.c')
-rw-r--r-- | arch/powerpc/oprofile/op_model_power4.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/arch/powerpc/oprofile/op_model_power4.c b/arch/powerpc/oprofile/op_model_power4.c index fe597a154d4..a7c206b665a 100644 --- a/arch/powerpc/oprofile/op_model_power4.c +++ b/arch/powerpc/oprofile/op_model_power4.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM + * Added mmcra[slot] support: + * Copyright (C) 2006-2007 Will Schmidt <willschm@us.ibm.com>, IBM * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -181,11 +183,17 @@ static void __attribute_used__ kernel_unknown_bucket(void) * On GQ and newer the MMCRA stores the HV and PR bits at the time * the SIAR was sampled. We use that to work out if the SIAR was sampled in * the hypervisor, our exception vectors or RTAS. + * If the MMCRA_SAMPLE_ENABLE bit is set, we can use the MMCRA[slot] bits + * to more accurately identify the address of the sampled instruction. The + * mmcra[slot] bits represent the slot number of a sampled instruction + * within an instruction group. The slot will contain a value between 1 + * and 5 if MMCRA_SAMPLE_ENABLE is set, otherwise 0. */ static unsigned long get_pc(struct pt_regs *regs) { unsigned long pc = mfspr(SPRN_SIAR); unsigned long mmcra; + unsigned long slot; /* Cant do much about it */ if (!cur_cpu_spec->oprofile_mmcra_sihv) @@ -193,6 +201,12 @@ static unsigned long get_pc(struct pt_regs *regs) mmcra = mfspr(SPRN_MMCRA); + if (mmcra & MMCRA_SAMPLE_ENABLE) { + slot = ((mmcra & MMCRA_SLOT) >> MMCRA_SLOT_SHIFT); + if (slot > 1) + pc += 4 * (slot - 1); + } + /* Were we in the hypervisor? */ if (firmware_has_feature(FW_FEATURE_LPAR) && (mmcra & cur_cpu_spec->oprofile_mmcra_sihv)) |