aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2009-10-14 19:32:15 +0000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2009-10-27 16:42:38 +1100
commit7abb840b496f834a71a8943bb189683da320f047 (patch)
tree6444e23443d1ddd9c5d7aa7198e6d8c401dda0c0 /arch/powerpc
parent964fe080d94db82a3268443e9b9ece4c60246414 (diff)
powerpc/perf_events: Fix priority of MSR HV vs PR bits
The architecture defines that if MSR PR is set we are in problem state irrespective of the HV bit. This fixes perf events to reflect this. Also, on bare metal systems, samples taken in Linux will now be reported as kernel rather than hypervisor. Signed-off-by: Michael Neuling <mikey@neuling.org> CC: paulus@samba.org Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/perf_event.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/perf_event.c b/arch/powerpc/kernel/perf_event.c
index bbcbae183e9..87f1663584b 100644
--- a/arch/powerpc/kernel/perf_event.c
+++ b/arch/powerpc/kernel/perf_event.c
@@ -116,20 +116,23 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{
unsigned long mmcra = regs->dsisr;
+ unsigned long sihv = MMCRA_SIHV;
+ unsigned long sipr = MMCRA_SIPR;
if (TRAP(regs) != 0xf00)
return 0; /* not a PMU interrupt */
if (ppmu->flags & PPMU_ALT_SIPR) {
- if (mmcra & POWER6_MMCRA_SIHV)
- return PERF_RECORD_MISC_HYPERVISOR;
- return (mmcra & POWER6_MMCRA_SIPR) ?
- PERF_RECORD_MISC_USER : PERF_RECORD_MISC_KERNEL;
+ sihv = POWER6_MMCRA_SIHV;
+ sipr = POWER6_MMCRA_SIPR;
}
- if (mmcra & MMCRA_SIHV)
+
+ /* PR has priority over HV, so order below is important */
+ if (mmcra & sipr)
+ return PERF_RECORD_MISC_USER;
+ if ((mmcra & sihv) && (freeze_events_kernel != MMCR0_FCHV))
return PERF_RECORD_MISC_HYPERVISOR;
- return (mmcra & MMCRA_SIPR) ? PERF_RECORD_MISC_USER :
- PERF_RECORD_MISC_KERNEL;
+ return PERF_RECORD_MISC_KERNEL;
}
/*