Commit 26b8317f authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Martin Schwidefsky

s390/cpum_cf: introduce kernel_cpumcf_alert() to obtain measurement alerts

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: default avatarHendrik Brueckner <brueckner@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent f944bcdf
...@@ -52,6 +52,7 @@ static inline void ctr_set_stop(u64 *state, int ctr_set) ...@@ -52,6 +52,7 @@ static inline void ctr_set_stop(u64 *state, int ctr_set)
struct cpu_cf_events { struct cpu_cf_events {
struct cpumf_ctr_info info; struct cpumf_ctr_info info;
atomic_t ctr_set[CPUMF_CTR_SET_MAX]; atomic_t ctr_set[CPUMF_CTR_SET_MAX];
atomic64_t alert;
u64 state, tx_state; u64 state, tx_state;
unsigned int flags; unsigned int flags;
unsigned int txn_flags; unsigned int txn_flags;
...@@ -59,6 +60,7 @@ struct cpu_cf_events { ...@@ -59,6 +60,7 @@ struct cpu_cf_events {
DECLARE_PER_CPU(struct cpu_cf_events, cpu_cf_events); DECLARE_PER_CPU(struct cpu_cf_events, cpu_cf_events);
int __kernel_cpumcf_begin(void); int __kernel_cpumcf_begin(void);
unsigned long kernel_cpumcf_alert(int clear);
void __kernel_cpumcf_end(void); void __kernel_cpumcf_end(void);
#endif /* _ASM_S390_CPU_MCF_H */ #endif /* _ASM_S390_CPU_MCF_H */
...@@ -27,6 +27,7 @@ DEFINE_PER_CPU(struct cpu_cf_events, cpu_cf_events) = { ...@@ -27,6 +27,7 @@ DEFINE_PER_CPU(struct cpu_cf_events, cpu_cf_events) = {
[CPUMF_CTR_SET_EXT] = ATOMIC_INIT(0), [CPUMF_CTR_SET_EXT] = ATOMIC_INIT(0),
[CPUMF_CTR_SET_MT_DIAG] = ATOMIC_INIT(0), [CPUMF_CTR_SET_MT_DIAG] = ATOMIC_INIT(0),
}, },
.alert = ATOMIC64_INIT(0),
.state = 0, .state = 0,
.flags = 0, .flags = 0,
.txn_flags = 0, .txn_flags = 0,
...@@ -205,6 +206,9 @@ static void cpumf_measurement_alert(struct ext_code ext_code, ...@@ -205,6 +206,9 @@ static void cpumf_measurement_alert(struct ext_code ext_code,
if (alert & CPU_MF_INT_CF_MTDA) if (alert & CPU_MF_INT_CF_MTDA)
pr_warn("CPU[%i] MT counter data was lost\n", pr_warn("CPU[%i] MT counter data was lost\n",
smp_processor_id()); smp_processor_id());
/* store alert for special handling by in-kernel users */
atomic64_or(alert, &cpuhw->alert);
} }
#define PMC_INIT 0 #define PMC_INIT 0
...@@ -255,6 +259,20 @@ int __kernel_cpumcf_begin(void) ...@@ -255,6 +259,20 @@ int __kernel_cpumcf_begin(void)
} }
EXPORT_SYMBOL(__kernel_cpumcf_begin); 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 */ /* Release the CPU-measurement counter facility */
void __kernel_cpumcf_end(void) void __kernel_cpumcf_end(void)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment