Blob Blame History Raw
From: Hendrik Brueckner <brueckner@linux.ibm.com>
Date: Wed, 8 Aug 2018 10:30:37 +0200
Subject: s390/cpum_cf: introduce kernel_cpumcf_alert() to obtain measurement
 alerts
Git-commit: 26b8317f51a20c1e4f61fbd2cc68975faad10b02
Patch-mainline: v5.1-rc1
References: jsc#SLE-6904 FATE#327581

During a __kernel_cpumcf_begin()/end() session, save measurement alerts
for the counter facility in the per-CPU cpu_cf_events variable.
Users can obtain and, optionally, clear the alerts by calling
kernel_cpumcf_alert() to specifically handle alerts.

Signed-off-by: Hendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 arch/s390/include/asm/cpu_mcf.h |    2 ++
 arch/s390/kernel/perf_cpum_cf.c |   18 ++++++++++++++++++
 2 files changed, 20 insertions(+)

--- a/arch/s390/include/asm/cpu_mcf.h
+++ b/arch/s390/include/asm/cpu_mcf.h
@@ -52,6 +52,7 @@ static inline void ctr_set_stop(u64 *sta
 struct cpu_cf_events {
 	struct cpumf_ctr_info	info;
 	atomic_t		ctr_set[CPUMF_CTR_SET_MAX];
+	atomic64_t		alert;
 	u64			state, tx_state;
 	unsigned int		flags;
 	unsigned int		txn_flags;
@@ -59,6 +60,7 @@ struct cpu_cf_events {
 DECLARE_PER_CPU(struct cpu_cf_events, cpu_cf_events);
 
 int __kernel_cpumcf_begin(void);
+unsigned long kernel_cpumcf_alert(int clear);
 void __kernel_cpumcf_end(void);
 
 #endif /* _ASM_S390_CPU_MCF_H */
--- a/arch/s390/kernel/perf_cpum_cf.c
+++ b/arch/s390/kernel/perf_cpum_cf.c
@@ -30,6 +30,7 @@ DEFINE_PER_CPU(struct cpu_cf_events, cpu
 		[CPUMF_CTR_SET_EXT]	= ATOMIC_INIT(0),
 		[CPUMF_CTR_SET_MT_DIAG] = ATOMIC_INIT(0),
 	},
+	.alert = ATOMIC64_INIT(0),
 	.state = 0,
 	.flags = 0,
 	.txn_flags = 0,
@@ -208,6 +209,9 @@ static void cpumf_measurement_alert(stru
 	if (alert & CPU_MF_INT_CF_MTDA)
 		pr_warn("CPU[%i] MT counter data was lost\n",
 			smp_processor_id());
+
+	/* store alert for special handling by in-kernel users */
+	atomic64_or(alert, &cpuhw->alert);
 }
 
 #define PMC_INIT      0
@@ -258,6 +262,20 @@ int __kernel_cpumcf_begin(void)
 }
 EXPORT_SYMBOL(__kernel_cpumcf_begin);
 
+/* Obtain the CPU-measurement alerts for the counter facility */
+unsigned long kernel_cpumcf_alert(int clear)
+{
+	struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events);
+	unsigned long alert;
+
+	alert = atomic64_read(&cpuhw->alert);
+	if (clear)
+		atomic64_set(&cpuhw->alert, 0);
+
+	return alert;
+}
+EXPORT_SYMBOL(kernel_cpumcf_alert);
+
 /* Release the CPU-measurement counter facility */
 void __kernel_cpumcf_end(void)
 {