From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966801AbbBDOo1 (ORCPT ); Wed, 4 Feb 2015 09:44:27 -0500 Received: from terminus.zytor.com ([198.137.202.10]:39084 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965489AbbBDOoV (ORCPT ); Wed, 4 Feb 2015 09:44:21 -0500 Date: Wed, 4 Feb 2015 06:43:12 -0800 From: tip-bot for Andy Lutomirski Message-ID: Cc: mingo@kernel.org, luto@amacapital.net, keescook@chromium.org, Valdis.Kletnieks@vt.edu, tglx@linutronix.de, hpa@zytor.com, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, paulus@samba.org, hillf.zj@alibaba-inc.com, aarcange@redhat.com, peterz@infradead.org, vince@deater.net, acme@kernel.org Reply-To: aarcange@redhat.com, vince@deater.net, peterz@infradead.org, acme@kernel.org, hpa@zytor.com, paulus@samba.org, hillf.zj@alibaba-inc.com, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org, Valdis.Kletnieks@vt.edu, tglx@linutronix.de, luto@amacapital.net, mingo@kernel.org, keescook@chromium.org In-Reply-To: References: To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/x86] perf/x86: Add /sys/devices/cpu/rdpmc= 2 to allow rdpmc for all tasks Git-Commit-ID: a66734297f78707ce39d756b656bfae861d53f62 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: a66734297f78707ce39d756b656bfae861d53f62 Gitweb: http://git.kernel.org/tip/a66734297f78707ce39d756b656bfae861d53f62 Author: Andy Lutomirski AuthorDate: Fri, 24 Oct 2014 15:58:13 -0700 Committer: Ingo Molnar CommitDate: Wed, 4 Feb 2015 12:10:49 +0100 perf/x86: Add /sys/devices/cpu/rdpmc=2 to allow rdpmc for all tasks While perfmon2 is a sufficiently evil library (it pokes MSRs directly) that breaking it is fair game, it's still useful, so we might as well try to support it. This allows users to write 2 to /sys/devices/cpu/rdpmc to disable all rdpmc protection so that hack like perfmon2 can continue to work. At some point, if perf_event becomes fast enough to replace perfmon2, then this can go. Signed-off-by: Andy Lutomirski Signed-off-by: Peter Zijlstra (Intel) Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Kees Cook Cc: Andrea Arcangeli Cc: Vince Weaver Cc: "hillf.zj" Cc: Valdis Kletnieks Cc: Linus Torvalds Link: http://lkml.kernel.org/r/caac3c1c707dcca48ecbc35f4def21495856f479.1414190806.git.luto@amacapital.net Signed-off-by: Ingo Molnar --- arch/x86/include/asm/mmu_context.h | 5 ++++- arch/x86/kernel/cpu/perf_event.c | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 89c1fec..883f6b9 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -19,9 +19,12 @@ static inline void paravirt_activate_mm(struct mm_struct *prev, #endif /* !CONFIG_PARAVIRT */ #ifdef CONFIG_PERF_EVENTS +extern struct static_key rdpmc_always_available; + static inline void load_mm_cr4(struct mm_struct *mm) { - if (atomic_read(&mm->context.perf_rdpmc_allowed)) + if (static_key_true(&rdpmc_always_available) || + atomic_read(&mm->context.perf_rdpmc_allowed)) cr4_set_bits(X86_CR4_PCE); else cr4_clear_bits(X86_CR4_PCE); diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index bec5cff..b71a7f8 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -45,6 +45,8 @@ DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { .enabled = 1, }; +struct static_key rdpmc_always_available = STATIC_KEY_INIT_FALSE; + u64 __read_mostly hw_cache_event_ids [PERF_COUNT_HW_CACHE_MAX] [PERF_COUNT_HW_CACHE_OP_MAX] @@ -1870,10 +1872,27 @@ static ssize_t set_attr_rdpmc(struct device *cdev, if (ret) return ret; + if (val > 2) + return -EINVAL; + if (x86_pmu.attr_rdpmc_broken) return -ENOTSUPP; - x86_pmu.attr_rdpmc = !!val; + if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) { + /* + * Changing into or out of always available, aka + * perf-event-bypassing mode. This path is extremely slow, + * but only root can trigger it, so it's okay. + */ + if (val == 2) + static_key_slow_inc(&rdpmc_always_available); + else + static_key_slow_dec(&rdpmc_always_available); + on_each_cpu(refresh_pce, NULL, 1); + } + + x86_pmu.attr_rdpmc = val; + return count; }