[PATCH 05/23] perf/x86: Allow exclude_host events to run in non-root mode

Zide Chen <[email protected]>
Newsgroups org.kernel.vger.kvm,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
On Intel, exclude_host events are prevented from running by masking
the Global Ctrl bits with ~cpuc->intel_ctrl_guest_mask.

When PMU partitioning is enabled, the host is allowed to run
exclude_host events in non-root mode, while such events still need to
be masked in root mode, since there are no other checkpoints to stop
them from being scheduled in.

Add x86_pmu_partition_loaded() to distinguish scheduling constraints
from x86_pmu_partition_nmi_active(), as PMU partitioning constraints
apply in both the _PARTITION_PRELOAD and _PARTITION_NMI states.

Signed-off-by: Zide Chen <[email protected]>
---
 arch/x86/events/core.c       | 11 +++++++++++
 arch/x86/events/intel/core.c |  6 ++++--
 arch/x86/events/perf_event.h |  1 +
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index bbae68c49063..76af9cfaf0ad 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1813,6 +1813,17 @@ bool x86_pmu_partition_nmi_active(void)
 	       state == GUEST_PMU_PARTITION_NMI;
 }
 
+/*
+ * Skip for "fake" cpuc used during event validation, where
+ * per-CPU state like guest_pmu_state is meaningless.
+ */
+bool x86_pmu_partition_loaded(struct cpu_hw_events *cpuc)
+{
+	return !cpuc->is_fake &&
+	       pmu_partition_configured() &&
+	       this_cpu_read(guest_pmu_state) != GUEST_PMU_NONE;
+}
+
 u64 x86_pmu_current_partition_mask(void)
 {
 	return this_cpu_ptr(&cpu_hw_events)->partition_mask;
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index c595c86ecf90..894f98eb871a 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -2812,8 +2812,10 @@ static void __intel_pmu_enable_all(int added, bool pmi)
 		cpuc->active_fixed_ctrl_val = cpuc->fixed_ctrl_val;
 	}
 
-	wrmsrq(MSR_CORE_PERF_GLOBAL_CTRL,
-	       intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
+	if (!x86_pmu_partition_loaded(cpuc))
+	       intel_ctrl &= ~cpuc->intel_ctrl_guest_mask;
+
+	wrmsrq(MSR_CORE_PERF_GLOBAL_CTRL, intel_ctrl);
 
 	if (test_bit(INTEL_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
 		struct perf_event *event =
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index d9875f3e6c8c..fa3023c355d5 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1610,6 +1610,7 @@ static inline int is_pebs_pt(struct perf_event *event)
 
 bool pmu_partition_configured(void);
 bool x86_pmu_partition_nmi_active(void);
+bool x86_pmu_partition_loaded(struct cpu_hw_events *cpuc);
 u64 x86_pmu_current_partition_mask(void);
 
 #ifdef CONFIG_CPU_SUP_INTEL
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.