From: Nicholas Piggin Date: Wed, 9 Aug 2017 13:44:00 +0000 (+0200) Subject: powerpc/perf: Avoid spurious PMU interrupts after idle X-Git-Tag: Ubuntu-4.10.0-34.38~32 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=e899988c4387b827897d7214493856b2b853baa9;p=mirror_ubuntu-zesty-kernel.git powerpc/perf: Avoid spurious PMU interrupts after idle BugLink: http://bugs.launchpad.net/bugs/1709352 POWER9 DD2 can see spurious PMU interrupts after state-loss idle in some conditions. A solution is to save and reload MMCR0 over state-loss idle. Signed-off-by: Nicholas Piggin Acked-by: Madhavan Srinivasan Tested-by: Anton Blanchard Signed-off-by: Michael Ellerman (cherry picked from commit 101dd590a7fa37954540cf3149a1c502c0acc524) Signed-off-by: Rodrigo R. Galvao Acked-by: Seth Forshee Acked-by: Kleber Sacilotto de Souza Signed-off-by: Kleber Sacilotto de Souza --- diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S index fb762ee5ac6f..e003fb99085d 100644 --- a/arch/powerpc/kernel/idle_book3s.S +++ b/arch/powerpc/kernel/idle_book3s.S @@ -29,6 +29,7 @@ * Use unused space in the interrupt stack to save and restore * registers for winkle support. */ +#define _MMCR0 GPR0 #define _SDR1 GPR3 #define _RPR GPR4 #define _SPURR GPR5 @@ -282,6 +283,14 @@ power_enter_stop: b pnv_wakeup_noloss .Lhandle_esl_ec_set: + /* + * POWER9 DD2 can incorrectly set PMAO when waking up after a + * state-loss idle. Saving and restoring MMCR0 over idle is a + * workaround. + */ + mfspr r4,SPRN_MMCR0 + std r4,_MMCR0(r1) + /* * Check if the requested state is a deep idle state. */ @@ -434,10 +443,14 @@ FTR_SECTION_ELSE_NESTED(70) ALT_FTR_SECTION_END_NESTED_IFSET(CPU_FTR_POWER9_DD1, 70) /* * Workaround for POWER9, if we lost resources, the ERAT - * might have been mixed up and needs flushing. + * might have been mixed up and needs flushing. We also need + * to reload MMCR0 (see comment above). */ blt cr3,1f PPC_INVALIDATE_ERAT + ld r1,PACAR1(r13) + ld r4,_MMCR0(r1) + mtspr SPRN_MMCR0,r4 1: /* * POWER ISA 3. Use PSSCR to determine if we