Message ID | 1521632426-30770-1-git-send-email-maddy@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Accepted |
Commit | e1ebd0e5b9d0a10ba65e63a3514b6da8c6a5a819 |
Headers | show |
Series | [v2] powerpc/perf: Fix kernel address leaks via Sampling registers | expand |
On Wed, 2018-03-21 at 11:40:24 UTC, Madhavan Srinivasan wrote: > From: Michael Ellerman <mpe@ellerman.id.au> > > Current code in power_pmu_disable() does not clear the sampling > registers like Sampling Instruction Address Register (SAIR) and > Sampling Data Address Register (SDAR) after disabling the PMU. > Since these are userspace readable and could contain kernel > address, add code to explicitly clear the content of these registers. > Patch also adds a "context synchronizing instruction" to enforce > no further updates to these registers as mandated by PowerISA. > > "If an mtspr instruction is executed that changes the > value of a Performance Monitor register other than > SIAR, SDAR, and SIER, the change is not guaranteed > to have taken effect until after a subsequent context > synchronizing instruction has been executed (see > Chapter 11. "Synchronization Requirements for Con- > text Alterations" on page 1133)." > > Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Applied to powerpc next, thanks. https://git.kernel.org/powerpc/c/e1ebd0e5b9d0a10ba65e63a3514b6d cheers
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index f89bbd54ecec..39846226c702 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -1226,6 +1226,7 @@ static void power_pmu_disable(struct pmu *pmu) */ write_mmcr0(cpuhw, val); mb(); + isync(); /* * Disable instruction sampling if it was enabled @@ -1234,12 +1235,26 @@ static void power_pmu_disable(struct pmu *pmu) mtspr(SPRN_MMCRA, cpuhw->mmcr[2] & ~MMCRA_SAMPLE_ENABLE); mb(); + isync(); } cpuhw->disabled = 1; cpuhw->n_added = 0; ebb_switch_out(mmcr0); + +#ifdef CONFIG_PPC64 + /* + * These are readable by userspace, may contain kernel + * addresses and are not switched by context switch, so clear + * them now to avoid leaking anything to userspace in general + * including to another process. + */ + if (ppmu->flags & PPMU_ARCH_207S) { + mtspr(SPRN_SDAR, 0); + mtspr(SPRN_SIAR, 0); + } +#endif } local_irq_restore(flags);