Skip to content

Commit

Permalink
oprofile/fsl emb: Don't set MSR[PMM] until after clearing the interrupt.
Browse files Browse the repository at this point in the history
On an arch 2.06 hypervisor, a pending perfmon interrupt will be delivered
to the hypervisor at any point the guest is running, regardless of
MSR[EE].  In order to reflect this interrupt, the hypervisor has to mask
the interrupt in PMGC0 -- and set MSRP[PMMP] to intercept futher guest
accesses to the PMRs to detect when to unmask (and prevent the guest from
unmasking early, or seeing inconsistent state).

This has the side effect of ignoring any changes the guest makes to
MSR[PMM], so wait until after the interrupt is clear, and thus the
hypervisor should have cleared MSRP[PMMP], before setting MSR[PMM].  The
counters wil not actually run until PMGC0[FAC] is cleared in
pmc_start_ctrs(), so this will not reduce the effectiveness of PMM.

Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
  • Loading branch information
Scott Wood authored and Kumar Gala committed Oct 14, 2010
1 parent 4f0e332 commit 4267ea7
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions arch/powerpc/oprofile/op_model_fsl_emb.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Freescale Embedded oprofile support, based on ppc64 oprofile support
* Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
*
* Copyright (c) 2004 Freescale Semiconductor, Inc
* Copyright (c) 2004, 2010 Freescale Semiconductor, Inc
*
* Author: Andy Fleming
* Maintainer: Kumar Gala <galak@kernel.crashing.org>
Expand Down Expand Up @@ -321,9 +321,6 @@ static void fsl_emb_handle_interrupt(struct pt_regs *regs,
int val;
int i;

/* set the PMM bit (see comment below) */
mtmsr(mfmsr() | MSR_PMM);

pc = regs->nip;
is_kernel = is_kernel_addr(pc);

Expand All @@ -340,9 +337,13 @@ static void fsl_emb_handle_interrupt(struct pt_regs *regs,
}

/* The freeze bit was set by the interrupt. */
/* Clear the freeze bit, and reenable the interrupt.
* The counters won't actually start until the rfi clears
* the PMM bit */
/* Clear the freeze bit, and reenable the interrupt. The
* counters won't actually start until the rfi clears the PMM
* bit. The PMM bit should not be set until after the interrupt
* is cleared to avoid it getting lost in some hypervisor
* environments.
*/
mtmsr(mfmsr() | MSR_PMM);
pmc_start_ctrs(1);
}

Expand Down

0 comments on commit 4267ea7

Please sign in to comment.